开发者

PHP Inheritance: If A then Must Set B

开发者 https://www.devze.com 2023-01-16 00:18 出处:网络
So, I tried to Google this but don\'t know what this kind of situation is called... I\'m working on my first use of class inheritance, where a parent class defines a set of methods and th开发者_Stack

So, I tried to Google this but don't know what this kind of situation is called...

I'm working on my first use of class inheritance, where a parent class defines a set of methods and th开发者_StackOverflowen several other classes extend that parent.

What I was wondering, is it possible to do something like this:

class foo {
  private bar = false;
  private baz = NULL;
}

Now let's say I have:

class foobar extends foo { }

I'd like to be able to have a condition in "foo" that says if any class extends "foo" and sets "bar = true" then "baz" must be set (ie. not null), or else throw an exception.

Is such a thing possible?


This seems possible by using a magic setter function that you define in foo, but comes with a serious caveat. Magic getters and setters fire only when you access an inaccessible property.

When operating inside a class, all properties, no matter whether declared private, public or protected, are usually accessible, so the magic getter and setter functions will not fire. There is only one exception: Properties that were declared private in an ancestor class. Those will be hidden (inaccessible) to descendant classes, and the magic functions will fire.

This means that you will need to declare bar and baz in foo. It wouldn't work if you would declare them in foobar, because they would become accessible.

With this in mind, the following will work as you want:

class foo {
  private $bar = false;
  private $baz = NULL;

  public function __set($name, $value)
   {
     if ($name == "bar") 
      { if ($value == true)
         {
           if ($this->baz == null) 
            throw new Exception();
         }
      }
   } 
}

class foobar extends foo {

     function test()
      {
       $this->bar = "TEST";   
      }

 }


 $foobar = new foobar();
 $foobar->test();  // Will throw an exception

If you want to read bar and baz from within foobar, you will also need to define a magic getter function.


Just run a construct function in the second class.

class foo {
  private bar = false;
  private baz = NULL;
  public function __construct() {
    if ($this->bar && is_null($this->baz)) // throw exception
  }
}
class foobar extends foo {
  public function __construct($baz) {
    $this->baz = $baz;
    $this->bar = true;
    parent::__construct(); // Now run the parent's constructor
  }
}

Many different ways to do it...

0

精彩评论

暂无评论...
验证码 换一张
取 消