Объект класса не работает внутри обратного вызова ob_start

Я не знаю почему, но этот код работал у меня месяц назад... возможно, я обновил php, но не могу вспомнить. Пробовал это с помощью PHP 5.2.17 и 5.3.6

Почему невозможно использовать объект класса внутри обратного вызова функции ob_start?

<?php
$f=new stdClass();
$f->title="awesome Title";

function callback($buffer) 
{
    global $f;
    $buffer=str_replace("###TITLE###", $f->title, $buffer);
    return $buffer;
}
ob_start("callback");
?>

This is the ###TITLE###

Выход:

PHP Notice:  Trying to get property of non-object in /Users/qxxx/Sites/test/test.php on line 8
This is the 

должен быть:

Это потрясающее название

Ответ 1

Это связано с тем, что выходной буфер неявно очищается путем завершения script.

В этот момент PHP уже уничтожил неиспользуемые переменные, поэтому, когда дело доходит до выполнения вашей функции обратного вызова, переменная $f не существует в глобальной области.

Вы можете решить эту проблему, явно очистив буфер до того, как вы начнете уничтожать объекты, разместив следующую строку где-нибудь в вашем script.

register_shutdown_function('ob_end_flush');

Edit:

Я хотел бы добавить, что, хотя в настоящее время это принятый ответ, объясняющий "почему", приведенное здесь решение не затрагивает основную причину проблемы; тот факт, что используется global.

Многие скажут вам, что global является злом, не давая причины почему. Здесь вы можете увидеть одну из причин.

Ответ, предоставляемый Jack, дает более "лучшее" решение (с использованием замыканий для поддержки ссылки на переменные) и должно рассматриваться как правильный способ избежать использования global в новых кодовых базах.

Ответ 2

Причина этого была хорошо обозначена Ли. Использование закрытия в этом случае будет лучше:

ob_start(function($b) use ($f) {
        return str_replace('###TITLE###', $f->title, $b);
});

Это связано с тем, что закрытие будет содержать ссылку на $f до конца script, чтобы он не собирал мусор перед запуском функции обратного вызова.

Ответ 3

Из справочной страницы php ob_start и отчет об ошибке Я узнал, что начиная с 5.2 все объекты уничтожаются @ob_start

Это поведение функции было изменено в php 5.2.0:

<?
    global $AP;
    $AP = new ap;
    ob_start("ob_end");
    function ob_end()
    {
        global $AP;
        $r = $AP->test();
        return $r;
    }
    class ap
    {
        function test()
        {
            return "debug";
        }
    }
?>

В более старых версиях он показывает: "debug". Но последняя версия php вызывает ошибку: PHP Неустранимая ошибка: вызов функции-члена функции() on > не-объект. И это не ошибка: http://bugs.php.net/bug.php?id=40104

из man-страниц