ID: 33910 Updated by: [EMAIL PROTECTED] Reported By: jrweir at gmail dot com -Status: Open +Status: Feedback Bug Type: Output Control Operating System: all PHP Version: 5.1.0b3 New Comment:
This is a chicken-and-egg problem that can't be solved in an easy way. Please see bug #33772 for additional details. If you have any ideas what should be the *right* order of calls - please tell your opinion. But remember that we have a lot of different handlers that are called on shutdown. See the current order in php-src/main/main.c, php_request_shutdown() function. Previous Comments: ------------------------------------------------------------------------ [2005-07-28 18:59:58] jrweir at gmail dot com Description: ------------ http://bugs.php.net/bug.php?id=30578 I don't think the way this bug was solved was correct. While I agree the example code posted above should work as expected, a side effect of fixing this caused all destructors to run before registered ob handlers. Destructors used to run after an ob handler, which was very useful for analyzing script output and setting flags for objects to clean themselves up appropriately. Consider the following (which is now not possible in 5.1): <?php ob_start('outputHandler'); function outputHandler($buffer){ // find out if there was a fatal error. If none, allow sql connections to commit on destruct if (!preg_match('/((Fatal|Parse) error: .+ in .+ on line \d+)/', strip_tags($buffer), $matches)) SQL::setAllowCommit(true); return $buffer; } class SQL { private $connection; private static $allowCommit=false; public function __construct(){ } public function __destruct(){ if ($this->connection && self::getAllowCommit()) { $this->connection->commit(); echo ' commit happened '; } else echo ' no commit happened '; } public static function getAllowCommit() { return self::$allowCommit; } public static function setAllowCommit($val) { self::$allowCommit = $val; } public function connectToDatabase($host, $user, $pass, $db){ $this->connection = new mysqli($host, $user, $pass, $db) or die('no connection'); $this->connection->autocommit(false); } public function query($sql) { return $this->connection->query($sql); } } $dbOne = new SQL(); $dbOne->connectToDatabase('localhost', 'user', 'pass', 'db1'); $result = $dbOne->query("update tab set col = 'val'"); $dbTwo = new SQL(); $dbTwo->connectToDatabase('localhost', 'user', 'pass', 'db2'); $result = $dbTwo->query("update tab set col = 'val'"); ?> This simple example would be able to tell if a fatal error happened in the script and only allow the db connections to commit their transactions if there was no error. There is no way to do this now in php 5.1 (I realize I could achieve a similar affect by storing all the open connections and calling some other method from the ob handler, but then the destructors have no real purpose if not for cleanup based on the exit status of a script). The original example of this "bug" is really just pointing out contradicting functionality. I would assume that output buffering would not be allowed in destructors (as it is not allowed in output buffering handlers). If by waiting for all variables to go out of scope before the buffer flush, then there is even a bigger contradiction. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=33910&edit=1
