Page 1 of 1
trigger php's default error
Posted: Sun Sep 02, 2007 5:38 am
by anjanesh
Hi
Code: Select all
class X
{
private $m1;
private $m2 = 98;
public function __construct($m1)
{
$this->m1 = $m1;
}
public function __get($nm)
{
if (isset($this->$nm))
return $this->$nm;
else
trigger_error("Notice: Undefined property: X::$nm in xxx.php on line nn", E_NOTICE); # somehow get this done by the interpreter automatically
}
}
$x = new X(56);
echo $x->m3;
How do I get it to throw the error like it normally would do if $this->$nm is not set ? Not by using custom error (E_USER_ERROR) - the default php's error msg.
Thanks
Posted: Sun Sep 02, 2007 7:54 am
by feyd
Look it up?
Posted: Sun Sep 02, 2007 7:57 am
by Ollie Saunders
If you have error_reporting set to E_ALL it'll do it anyway.
Posted: Sun Sep 02, 2007 8:26 am
by volka
feyd wrote:Look it up?
I think in this case it's not _that_ easy.
Posted: Sun Sep 02, 2007 8:30 am
by feyd
volka wrote:I think in this case it's not _that_ easy.
Sure it is:
Code: Select all
feyd:~ feyd$ php -r "class foo{function __construct(){$this->notHere;}} new foo();"
PHP Parse error: syntax error, unexpected T_OBJECT_OPERATOR in Command line code on line 1
<span style=color:red>
Parse error: syntax error, unexpected T_OBJECT_OPERATOR in Command line code on line 1
</span>
Posted: Sun Sep 02, 2007 8:31 am
by volka
errr.... in what way is that related to the question?
Posted: Sun Sep 02, 2007 8:38 am
by anjanesh
Assumming I dont have the __get method, I get this error :
Notice: Undefined property: X::$m3 in C:\xxx\oop.php on line nn
This is what I what it to fall back to in the else statement of if (isset($this->$nm))
Posted: Sun Sep 02, 2007 8:55 am
by Ollie Saunders
Actually the thing to do anjanesh is not to use __get to access object properties directly under $this but access an array. So do this
Code: Select all
private $_store = array();
public function __get($name)
{
return $this->_store[$name];
}
instead of this:
Code: Select all
public function __get($name)
{
return $this->$name;
}
Posted: Sun Sep 02, 2007 9:21 am
by volka
ole wrote:Actually the thing to do anjanesh is not to use __get to access object properties directly under $this but access an array.
Why not? Ok, there's nothing wrong with using an array, in fact it might be better. But how does that solve the original problem?
The only dirty workaround I've found so far is to access the same property again within the __get method. There's code in the zend engine to prevent that from happening.
Code: Select all
<?php
error_reporting(E_ALL|E_STRICT);
class Foo {
protected $properties=array('abc'=>1234);
public function __get($x) {
if ( array_key_exists($x, $this->properties) ) {
return $this->properties[$x];
}
else {
return $this->$x;
}
}
}
$fex = new Foo;
echo 'abc ', $fex->abc, "\n";
echo 'xyz ', $fex->xyz, "\n";
abc 1234
xyz
Notice: Undefined property: Foo::$xyz in /home/volker/schnickschnack/test.php on line 11
unfortunately as you can see "on line 11" doesn't point to $fex->xyz but $this->$x;
Posted: Sun Sep 02, 2007 10:37 am
by anjanesh
@volka : LOL ! I could've just done
return $this->$nm; !!!
Code: Select all
public function __get($nm)
{
return $this->$nm;
}
public function __set($nm, $value)
{
if (isset($this->$nm))
$this->$nm = $value;
else
return $this->$nm;
}
Dumbest question ever !
Posted: Sun Sep 02, 2007 11:08 am
by Ollie Saunders
Posted: Sun Sep 02, 2007 11:12 am
by volka
anjanesh wrote:@volka : LOL ! I could've just done return $this->$nm; !!!
Yes. I just wanted to incorporate ole's suggestion

Keep in mind it's still only a workaround. And I'd prefer to throw an exception.
Not with the code anjanesh had at this time because of the explicit isset()
and not with
ole wrote:return $this->_store[$name];
either

Posted: Sun Sep 02, 2007 11:54 pm
by anjanesh
Code: Select all
public function __get($nm)
{
if (!in_array($nm, array('m1', 'm2')))
return $this->nonExistentMember; // Problem is, it would show nonExistentMember not declared rather than value of $nm
return $this->$nm; // If this not set, it would trigger the default E_NOTICE error
}
I would want to do
if (!in_array($nm, array('m1', 'm2'))) only because if I had a private member called
m4 and dont want that accessed at all outside the class. If dont do this, return
$this->$nm would return
$this->m4; which is not an error.