trigger php's default error

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

trigger php's default error

Post 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
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Look it up?
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

If you have error_reporting set to E_ALL it'll do it anyway.
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

feyd wrote:Look it up?
I think in this case it's not _that_ easy.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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>
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

errr.... in what way is that related to the question?
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

Post 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))
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post 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;
}
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post 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;
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

Post 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 !
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post 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.
ole wrote:That's what I said
Not with the code anjanesh had at this time because of the explicit isset()
and not with
ole wrote:return $this->_store[$name];
either ;)
User avatar
anjanesh
DevNet Resident
Posts: 1679
Joined: Sat Dec 06, 2003 9:52 pm
Location: Mumbai, India

Post 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.
Post Reply