dou12754 2011-04-28 17:52
浏览 32
已采纳

output_add_rewrite_var问题

Why doesn't this work?

output_add_rewrite_var('var', 'value');

// some links
echo '<a href="file.php">link</a>
<a href="http://example.com">link2</a>';

// a form
echo '<form action="script.php" method="post">
<input type="text" name="var2" />
</form>';

$tmp = ob_get_contents();

#print_r(ob_list_handlers());

ob_end_clean();

echo $tmp;

Taken from http://www.php.net/manual/en/function.ob-get-contents.php

I found a fix

ob_start();
ob_start();
output_add_rewrite_var('var', 'value');

// some links
echo '<a href="file.php">link</a>
<a href="http://example.com">link2</a>';

// a form
echo '<form action="script.php" method="post">
<input type="text" name="var2" />
</form>';

ob_end_flush();

$tmp = ob_get_contents();

#print_r(ob_list_handlers());

ob_end_clean();

echo $tmp;

The fix is not working

The fix is not working if I try to run it two times after each other, it works fine the first time, the last time it doesn't add the '?var=value' at all. Anyone have a clue?

  • 写回答

1条回答 默认 最新

  • dqdes60666 2011-04-30 04:44
    关注

    Why it won't work

    As evidenced by ob_list_handlers() in the example in the docs for output_add_rewrite_var(), "URL-Rewriter" is an output handler. Output handlers are not run on data on the way into the buffer; output handlers are run on data on the way out of the buffer. To illustrate this, what happens if you're using the ob_gzhandler and you grab the contents of the buffer? You don't get gz-encoded data; you get the original, uncompressed data.

    From the docs for ob_start()'s output_callback parameter:

    The function will be called when the output buffer is flushed (sent) or cleaned (with ob_flush(), ob_clean() or similar function) or when the output buffer is flushed to the browser at the end of the request.

    This is why your first example doesn't work. You're grabbing the contents of the buffer directly with ob_get_contents() rather than flushing its contents, so the rewrite handler hasn't been executed.

    Why the fix works

    The fix you posted is right on track. Since you have to flush the buffer for the output handler to run, you need to have another output buffer to catch the flushed data. Then that outer buffer will contain the handler-processed data, so grab its contents instead.


    Problems with multiple, consecutive buffers

    In regard to trying to "run it two times after each other," I see exactly what you mean. If I have a second inner buffer after the first is closed, the URL-Rewriter only works on the first. If I copy/paste and switch the order of the inner buffers, the one that works switches. It's always the one that occurs first. After playing with it for a few hours now, I'm tempted to say it's a PHP bug, unless there's an undocumented reason why it would behave that way specifically for the URL-Rewriter output handler.

    To test, I wrote a simple output handler.

    function ob_uppercase($buffer)
    {
        return strtoupper($buffer);
    }
    

    I got what I expected in terms of output handler usage.

    // outer buffer
    ob_start();
    
    print_r(ob_list_handlers());
    
    // inner buffer 1
    ob_start('ob_uppercase');
    print_r(ob_list_handlers());
    ob_end_flush();
    
    print_r(ob_list_handlers());
    
    // inner buffer 2
    ob_start('ob_uppercase');
    print_r(ob_list_handlers());
    ob_end_flush();
    
    print_r(ob_list_handlers());
    
    /*
    Yields:
    
    Array
    (
        [0] => default output handler
    )
    ARRAY
    (
        [0] => DEFAULT OUTPUT HANDLER
        [1] => OB_UPPERCASE
    )
    Array
    (
        [0] => default output handler
    )
    ARRAY
    (
        [0] => DEFAULT OUTPUT HANDLER
        [1] => OB_UPPERCASE
    )
    Array
    (
        [0] => default output handler
    )
    
    */
    

    Now if I did the same thing with the URL-Rewriter, it's not getting used in the second "inner buffer."

    // outer buffer
    ob_start();
    
    print_r(ob_list_handlers());
    
    // inner buffer 1
    ob_start();
    output_add_rewrite_var('var', 'value');
    print_r(ob_list_handlers());
    ob_end_flush();
    
    print_r(ob_list_handlers());
    
    // inner buffer 2
    ob_start();
    output_add_rewrite_var('var', 'value');
    print_r(ob_list_handlers());
    ob_end_flush();
    
    print_r(ob_list_handlers());
    
    /*
    Yields:
    
    Array
    (
        [0] => default output handler
    )
    Array
    (
        [0] => default output handler
        [1] => URL-Rewriter
    )
    Array
    (
        [0] => default output handler
    )
    Array
    (
        [0] => default output handler
        [1] => default output handler
    )
    Array
    (
        [0] => default output handler
    )
    */
    

    It doesn't matter if I use the same var name in both inner buffers or not. All uses of output_add_rewrite_var() in the second inner buffer is completely ignored, no matter what the vars are. (I also tested with more than two, and in all cases only the first one works.)

    I say it's a bug. If you agree, please submit a bug report to http://bugs.php.net .

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线