:) .. this is almost exactly what I suggested to Bill last week for
exactly the same reasons (see the API: http://www.php.net/exceptions ).
To see the problem in detail, please consider the attached scripts and
their output.
Due to the time pressure of the 0.6 release, and the likely time
required for consensus regarding resolution of this issue, I resorted to
using __CLASS__ . __FUNCTION__ . __LINE__ in the message thrown by some
changes in changeset 2387. However, I'm not exactly fond of this either,
and welcome suggestions (like Ralph's) for obtaining similar
functionality with less code bloat.
I agree with John that we can likely extend Zend_Exception and add
another workaround by adding methods to Zend_Exception, but I have
reservations about adding more code to ZF to solve problems caused by a
performance optimization in Zend.php that was added to address a
perceived problem with PHP's performance when loading numerous files
containing only one line of code, such as:
class Zend_Component_Exception extends Zend_Exception {}
Various Alternatives (in no particular order)
====================================
Aggregate all these "one liners" into a single file, and dispense with
attempts to optimize the loading of these one liners.
For "empty" exception classes, use a shared class, combined with a
user-defined exception code ( http://www.php.net/exceptions ).
Ignore the perceived performance issue (might not be present / severe
when using various byte-code caching tools under real-world conditions),
and return to the original approach for handling exceptions in the ZF.
There are several other possibilities, but do any provide the same
functionality without resorting to numerous files containing an empty
class definition?
Cheers,
Gavin
Ralph Schindler wrote:
Yes, this is the case, the exception object will populate its internal
members at construction time, and having been thrown makes no
alterations to internal members. This is good b/c a trace at the time
of construction will persist until/or when the developer wishes to
handle it.
I personally don't need line/file as much as exception type, so this
has little affect on me. But to appease those that rely on file/line,
why not add to methods to the Zend_Exception class (which extends
exception and it is expected that all core exception classes derive from.
class Zend_Exception extends Exception
{
...
final function getTraceLine($traceDepth = 1) { ... }
final function getTraceFile($traceDepth = 1) { ... }
}
This will allow developers to lines and files from the trace, not the
constructor. Bam, everyone happy ;)
-ralph
Bill Karwin wrote:
Okay I just tried this:
<?php
function testException()
{
require_once 'Zend.php';
try {
$x = Zend::exception('Zend_Exception', 'boo!');
throw $x;
} catch (Zend_Exception $e) {
echo "{$e->getMessage()}\n";
echo "file: {$e->getFile()}\n";
echo "line: {$e->getLine()}\n";
echo "trace: {$e->getTraceAsString()}\n";
}
}
testException();
?>
<?php
error_reporting( E_ALL | E_STRICT );
require 'Zend.php';
class Foo
{
public function doit()
{
//echo "\n", __FILE__, __FUNCTION__, __LINE__, "\n";
throw new Foo_Exception('message of thrown exception)');
//throw Zend::exception('Foo_Exception', 'message of thrown exception');
}
}
class Foo_Exception extends Exception
{}
try {
$foo = new Foo();
$foo->doit();
} catch (Exception $e) {
echo "\nprint_r(\$e)=\n";
print_r($e);
echo "\nvar_dump(\$e)=\n";
var_dump($e);
}
print_r($e)=
Foo_Exception Object
(
[message:protected] => message of thrown exception)
[string:private] =>
[code:protected] => 0
[file:protected] =>
/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e1.php
[line:protected] => 12
[trace:private] => Array
(
[0] => Array
(
[file] =>
/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e1.php
[line] => 23
[function] => doit
[class] => Foo
[type] => ->
[args] => Array
(
)
)
)
)
var_dump($e)=
object(Foo_Exception)#2 (6) {
["message:protected"]=>
string(28) "message of thrown exception)"
["string:private"]=>
string(0) ""
["code:protected"]=>
int(0)
["file:protected"]=>
string(63) "/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e1.php"
["line:protected"]=>
int(12)
["trace:private"]=>
array(1) {
[0]=>
array(6) {
["file"]=>
string(63)
"/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e1.php"
["line"]=>
int(23)
["function"]=>
string(4) "doit"
["class"]=>
string(3) "Foo"
["type"]=>
string(2) "->"
["args"]=>
array(0) {
}
}
}
}
<?php
error_reporting( E_ALL | E_STRICT );
require 'Zend.php';
class Foo
{
public function doit()
{
//echo "\n", __FILE__, __FUNCTION__, __LINE__, "\n";
//throw new Foo_Exception('message of thrown exception)');
throw Zend::exception('Foo_Exception', 'message of thrown exception');
}
}
class Foo_Exception extends Exception
{}
try {
$foo = new Foo();
$foo->doit();
} catch (Exception $e) {
echo "\nprint_r(\$e)=\n";
print_r($e);
echo "\nvar_dump(\$e)=\n";
var_dump($e);
}
print_r($e)=
Foo_Exception Object
(
[message:protected] => message of thrown exception
[string:private] =>
[code:protected] => 0
[file:protected] => /cygdrive/c/gavin/home/src/zftrunk/library/Zend.php
[line:protected] => 229
[trace:private] => Array
(
[0] => Array
(
[file] =>
/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e2.php
[line] => 13
[function] => exception
[class] => Zend
[type] => ::
[args] => Array
(
[0] => Foo_Exception
[1] => message of thrown exception
)
)
[1] => Array
(
[file] =>
/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e2.php
[line] => 23
[function] => doit
[class] => Foo
[type] => ->
[args] => Array
(
)
)
)
)
var_dump($e)=
object(Foo_Exception)#2 (6) {
["message:protected"]=>
string(27) "message of thrown exception"
["string:private"]=>
string(0) ""
["code:protected"]=>
int(0)
["file:protected"]=>
string(51) "/cygdrive/c/gavin/home/src/zftrunk/library/Zend.php"
["line:protected"]=>
int(229)
["trace:private"]=>
array(2) {
[0]=>
array(6) {
["file"]=>
string(63)
"/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e2.php"
["line"]=>
int(13)
["function"]=>
string(9) "exception"
["class"]=>
string(4) "Zend"
["type"]=>
string(2) "::"
["args"]=>
array(2) {
[0]=>
string(13) "Foo_Exception"
[1]=>
string(27) "message of thrown exception"
}
}
[1]=>
array(6) {
["file"]=>
string(63)
"/cygdrive/c/gavin/home/src/zftrunk/incubator/jexceptions/e2.php"
["line"]=>
int(23)
["function"]=>
string(4) "doit"
["class"]=>
string(3) "Foo"
["type"]=>
string(2) "->"
["args"]=>
array(0) {
}
}
}
}