Reputation: 12831
I don't know why, but this code worked for me a month ago... maybe I upgraded the php but can't remember. Tried this with PHP 5.2.17 and 5.3.6
Why is it not possible to use a class object inside the callback of a ob_start function?
<?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###
Output is:
PHP Notice: Trying to get property of non-object in /Users/qxxx/Sites/test/test.php on line 8
This is the
should be:
This is the awesome Title
Upvotes: 12
Views: 2556
Reputation: 12889
This is because the output buffer is being implicitly flushed by the termination of the script.
At this point PHP has already destroyed unreferenced variables, so when it comes to execute your callback function, the variable $f
does not exist in the global scope.
You can solve this by explicitly flushing the buffer before shutdown starts destroying objects, by placing the following line somewhere in your script.
register_shutdown_function('ob_end_flush');
Edit:
I'd like to add that even though this is currently the accepted answer that explains the "why", the solution provided here does not address the root cause of the issue; the fact that global
is being used.
Many people will tell you that global
is evil, without giving a reason why. Here you can see one of the reasons.
The answer provided by Jack gives a more "best practice" solution (using closures to maintain the variable reference), and should be considered as the proper way to avoid using global
in new codebases.
Upvotes: 11
Reputation: 173562
The reason for this has been outlined well by Leigh. Using a closure would work better in this case:
ob_start(function($b) use ($f) {
return str_replace('###TITLE###', $f->title, $b);
});
This is because the closure will keep the reference to $f
alive by the end of the script so that it won't get garbage collected before running the callback function.
Upvotes: 7
Reputation: 76395
From the php manual page of ob_start
, and a bug report I learned that, since 5.2, all objects are destroyed @ob_start
This function's behaviour has been changed in 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";
}
}
?>
In older versions it shows: "debug". But latest php version causes error: PHP Fatal error: Call to a member function test() on > a non-object. And this is not a bug: http://bugs.php.net/bug.php?id=40104
from the man pages
Upvotes: 2