Page 1 of 1
PHP 5 exceptions to PHP 4
Posted: Mon Feb 26, 2007 4:11 am
by fastfingertips
Hello guys
I’m in middle of a task that involves rewriting some PHP 5 classes to PHP 4 and I have somehow to simulate the PHP 5 exception system (since any error must be handled at a superior level). Any idea how I will be able to do that? I was thinking to create an observer and make all objects that are triggering error observable, but this will involve some hard work so this is my last solution.
Posted: Mon Feb 26, 2007 5:31 am
by Weirdan
other approach would be to use set_error_handler() & trigger_error()
Posted: Mon Feb 26, 2007 6:28 am
by Chris Corbyn
I've got this (it's not the best, I know):
Code: Select all
<?php
class MyException extends Swift_Exception {}
class TestOfErrors extends UnitTestCase
{
function setUp()
{
Swift_Errors::reset();
}
function testErrorIsTriggeredIfItNotCaught()
{
$ex =& new Swift_Exception("Foo");
Swift_Errors::trigger($ex);
$this->assertError(); //SimpleTest's of course
$ex =& new Swift_Exception("BAR");
Swift_Errors::trigger($ex);
$this->assertError(); //SimpleTest's of course
}
function testErrorCanBeCaught()
{
$ex =& new Swift_Exception("foo");
Swift_Errors::expect($e);
Swift_Errors::trigger($ex);
$this->assertEqual($e, $ex);
$ex =& new Swift_Exception("bar");
Swift_Errors::expect($e);
Swift_Errors::trigger($ex);
$this->assertEqual($e, $ex);
}
function testOnlyOneErrorCaught()
{
$ex =& new Swift_Exception("foo");
Swift_Errors::expect($e);
Swift_Errors::trigger($ex);
$this->assertEqual($e, $ex);
$ex =& new Swift_Exception("bar");
Swift_Errors::trigger($ex);
$this->assertError();
}
function testErrorTypeCanBeSpecified()
{
$ex =& new MyException("test");
Swift_Errors::trigger($ex);
$this->assertError();
$ex =& new MyException("test2");
Swift_Errors::expect($e, "MyException");
Swift_Errors::trigger($ex);
$this->assertEqual($e, $ex);
}
function testErrorTypeKnowsAboutInheritance()
{
$ex =& new MyException("test2");
Swift_Errors::expect($e, "MyException");
Swift_Errors::trigger($ex);
$this->assertEqual($e, $ex);
$ex =& new MyException("test2");
Swift_Errors::expect($e, "Swift_Exception");
Swift_Errors::trigger($ex);
$this->assertEqual($e, $ex);
}
function testCatchStatementsCanBeEndedWithoutThrowingException()
{
$ex =& new MyException("test2");
Swift_Errors::expect($e, "MyException");
//Swift_Errors::trigger($ex); let's not throw this one!
Swift_Errors::clear("MyException");
$ex =& new MyException("test3");
Swift_Errors::trigger($ex);
$this->assertError();
}
function testCatchStatementsCanBeNested()
{
$ex1 =& new MyException("ex1");
$ex2 =& new MyException("ex2");
Swift_Errors::expect($e1, "MyException");
Swift_Errors::expect($e2, "MyException");
Swift_Errors::trigger($ex1);
Swift_Errors::trigger($ex2);
$this->assertEqual($e1, $ex2);
$this->assertEqual($e2, $ex1);
}
function testRealCaseScenario()
{
Swift_Errors::expect($e, "MyException");
if (true) {
Swift_Errors::trigger(new MyException("foo"));
} else {
Swift_Errors::clear("MyException");
}
$this->assertIsA($e, "MyException");
$this->assertEqual("foo", $e->getMessage());
Swift_Errors::expect($e, "MyException");
if (false) {
Swift_Errors::trigger(new MyException("foo"));
} else {
Swift_Errors::clear("MyException");
}
$this->assertNull($e);
if (true) {
Swift_Errors::trigger(new Swift_Exception("bar"));
} else {
Swift_Errors::clear("MyException");
}
$this->assertError();
}
}
Code: Select all
<?php
/**
* Swift Mailer PHP4 Exception hackaround.
* Please read the LICENSE file
* @author Chris Corbyn <chris@w3style.co.uk>
* @package Swift
* @license GNU Lesser General Public License
*/
/**
* Swift Exception handling object for PHP4
* Triggers and/or catches errors
* @package Swift
* @author Chris Corbyn <chris@w3style.co.uk>
*/
class Swift_Errors
{
/**
* Caught errors
* @var array,Swift_Error
*/
var $errors = array();
/**
* If an error has been thrown previously and not caught (hack)
* @var boolean
*/
var $halt = false;
/**
* Errors we're expecting, so don't trigger them
* @var array
*/
var $try = array();
/**
* Get an instance of this class as a singleton - needed internally
* @return Swift_Errors
*/
function &getInstance()
{
static $instance = null;
if (!$instance) $instance = array(new Swift_Errors());
return $instance[0];
}
/**
* Check if things are supposed to have stopped processing because of an
* uncaught excpetion
* @return boolean
*/
function halted()
{
$me =& Swift_Errors::getInstance();
return $me->halt;
}
/**
* Reset everything logged so far
*/
function reset()
{
$me =& Swift_Errors::getInstance();
$me->errors = array();
$me->halt = false;
$me->try = array();
}
/**
* Throw a new exception - it will either be caught or triggered
* @param Swift_Exception
*/
function trigger(&$e)
{
$me =& Swift_Errors::getInstance();
$me->errors[] =& $e;
$me->halt = true;
foreach (array_reverse(array_keys($me->try)) as $type)
{
if (is_a($e, $type))
{
foreach (array_reverse(array_keys($me->try[$type])) as $i)
{
$me->try[$type][$i] = $e;
unset($me->try[$type][$i]);
$me->halt = false;
return;
}
}
}
//If here, then it wasn't caught
$me->dumpError($e);
}
/**
* Dump the error if it was not caught
* @param Swift_Exception
*/
function dumpError(&$e)
{
$output = "<br /><strong>Uncaught Error</strong> of type [" . get_class($e) . "] with message [" . $e->getMessage() . "]";
$output .= "<br />" . $e->getBacktraceDump() . "<br />";
trigger_error($output, E_USER_ERROR);
}
/**
* Tell the error handler we're expecting an error of type $type and assign it to $e
* @param &$e
* @param string The type of expection - optional
*/
function expect(&$e, $type="Swift_Exception")
{
$me =& Swift_Errors::getInstance();
$e = null;
$me->try[$type][] =& $e;
}
/**
* Clear anything that may have been expected matching $type
* @param string The type
*/
function clear($type)
{
$me =& Swift_Errors::getInstance();
if (isset($me->try[$type]))
{
foreach (array_reverse(array_keys($me->try[$type])) as $i)
{
unset($me->try[$type][$i]);
break;
}
}
}
/**
* The last error message as a string
* @return string
*/
function getLast()
{
$me =& Swift_Errors::getInstance();
if (count($me->errors))
{
$last =& $me->errors[(count($me->errors)-1)];
return $last->getMessage();
}
}
/**
* Get all logged errors as an array
* @return array,Swift_Exception
*/
function &getAll()
{
return $this->errors;
}
}
Code: Select all
<?php
/**
* Swift Mailer PHP4 Exception.
* Please read the LICENSE file
* @author Chris Corbyn <chris@w3style.co.uk>
* @package Swift
* @license GNU Lesser General Public License
*/
/**
* Swift Exception for PHP4.
* @package Swift
* @author Chris Corbyn <chris@w3style.co.uk>
*/
class Swift_Exception
{
/**
* The error message in this exception
* @var string
*/
var $message;
/**
* A backtrace to show
* @var array
*/
var $trace;
/**
* Constructor
* @param string The error message
*/
function Swift_Exception($message)
{
$this->message = $message;
$this->trace = debug_backtrace();
}
/**
* Get the error message
* @return string
*/
function getMessage()
{
return $this->message;
}
/**
* Get the backtrace
* @return array
*/
function getTrace()
{
return $this->trace;
}
/**
* Get a summarised backtrace as a string
* @return string
*/
function getBacktraceDump()
{
$trace = $this->getTrace();
$ret = "";
for ($i = 0; $i < count($trace); $i++)
{
$end = array_pop($trace);
if (!empty($end["class"])) $class = $end["class"] . "::";
else $class = "";
$file_info = " @$i " . $class . $end["function"] .
"() in " . $end["file"] . " on line " .
$end["line"] . "<br />";
$ret .= $file_info;
}
return $ret;
}
}