19

This will throw an error:

class foo
{
   var $bar;

   public function getBar()
   {
      return $this->Bar; // beware of capital 'B': "Fatal:    unknown property".
   }

}

But this won't:

class foo
{
   var $bar;

   public function setBar($val)
   {
      $this->Bar = $val; // beware of capital 'B': silently defines a new prop "Bar"
   }

}

How can I force PHP to throw errors in BOTH cases? I consider the second case more critical than the first (as it took me 2 hours to search for a d....ned typo in a property).

3
  • 1
    You could check if Bar is defined via isset Commented Jun 21, 2013 at 13:17
  • and what if it isn't? I still don't know that Bar isn't defined in the class. Commented Jun 21, 2013 at 13:18
  • Well, choose CamelCase or lowercase (or some other convention) and then stick with it. You can use something like PHP CodeSniffer (phpcs) to enforce it. Also, erroneous variable names will give you a perfectly understandable error message, which you can use to quickly find out where the error occurred. Using the magic methods __get and __set may solve the problem, but at what cost? It will slow down the code, and it may give rise to another set of problems. Commented Jun 21, 2013 at 13:33

2 Answers 2

15

You can use magic methods

__set() is run when writing data to inaccessible properties.

__get() is utilized for reading data from inaccessible properties.

class foo
{
   var $bar;

   public function setBar($val)
   {
      $this->Bar = $val; // beware of capital 'B': silently defines a new prop "Bar"
   }

   public function __set($var, $val)
   {
     trigger_error("Property $var doesn't exists and cannot be set.", E_USER_ERROR);
   }

   public function  __get($var)
   {
     trigger_error("Property $var doesn't exists and cannot be get.", E_USER_ERROR);
   }

}

$obj = new foo(); 
$obj->setBar('a');

It will cast error

Fatal error: Property Bar doesn't exists and cannot be set. on line 13

You can set Error Levels according to PHP error levels

Sign up to request clarification or add additional context in comments.

7 Comments

Working, but not what I'm looking for, actually: Both answers need to add code to the class in order to programmatically check syntax for errors. You need to add that to all classes (or inherit from somewhere), not the elegant way. Never the less: upvote, I'll consider this
There's no other way ;/ you can always inherit it from abstract class or use traits I don't see anything that is not elegant in it.
Got it. I still do not regard this as "elegant", but it's worth a try (and related to PHP and not to your answer!)
@AxelAmthor If you have PHP 5.4+, you could use Traits (like a mix-in) rather than inheritance.
it could be done with traits however personally I don't like them :)
|
11

One solution I can imagine would be (ab)using __set and maybe property_exists:

public function __set($var, $value) {
    if (!property_exists($this, $var)) {
        throw new Exception('Undefined property "'.$var.'" should be set to "'.$value.'"');
    }
    throw new Exception('Trying to set protected / private property "'.$var.'" to "'.$value.'" from invalid context');
}

Demo: http://codepad.org/T5X6QKCI

2 Comments

You were a bit faster :) beacuse I wrote more complicated example with errors not exceptions
@TimWolla You are not abusing the __set function. This "magic" method was defined for this. But you should not use Exception use a derived type of it. The question is which should be used. I'm unsure but I tend to use the OutOfBoundsException. see stackoverflow.com/questions/8193798/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.