简体   繁体   English

__get 魔术方法 - 如何抛出和捕获属性重载的错误?

[英]__get magic method - how to throw and catch error for property overloading?

I define what happens when a non-existent property is being accessed by taking advantage of the __get magic method.我定义了利用__get魔术方法访问不存在的属性时会发生什么。

So if $property->bla does not exist I will get null .因此,如果$property->bla不存在,我将得到null

return (isset($this->$name)) ? $this->$name : null;

But I want to throw and catch the error for $property->bla->bla when I know that $property->bla does not exist.但是当我知道$property->bla不存在时,我想抛出并捕获$property->bla->bla的错误。

with return (isset($this->$name)) ? $this->$name : null; return (isset($this->$name)) ? $this->$name : null; return (isset($this->$name)) ? $this->$name : null; I will get this error below,我将在下面收到此错误,

<b>Notice</b>:  Trying to get property of non-object in...

So I use throw and catch error in my class,所以我在课堂上使用throw and catch错误,

class property {类属性{

public function __get($name)
{
    //return (isset($this->$name)) ? $this->$name : null;

    try {
        if (!isset($this->$name)) {
          throw new Exception("Property $name is not defined");
        }
        return $this->$name;
      }
      catch (Exception $e) {

        return $e->getMessage(); 
      }
}

} }

But the result is not what I want because it throw the error message ("Property $name is not defined") instead of null for $property->bla .但结果不是我想要的,因为它throw错误消息("Property $name is not defined")而不是$property->blanull

How can I make it to throw error message only for $property->bla->bla , $property->bla->bla->bla , and so on?我怎样才能让它$property->bla->bla$property->bla->bla->bla抛出错误消息?

You can't.你不能。

Within the scope of the __get() function, you only know about $property->blah .__get()函数的范围内,您只知道$property->blah You have no clue what comes after it, because that's the functionality of the language.你不知道它后面是什么,因为那是语言的功能。

Note the order of evaluations on $foo = $property->blah->blah2->blah3 :请注意$foo = $property->blah->blah2->blah3上的评估顺序:

  1. $temp1 = $property->blah;
  2. $temp1 = $temp1->blah2;
  3. $foo = $temp1->blah3;

Of course, $temp1 is fictitious, but this is essentially what happens in the execution of that statement.当然, $temp1是虚构的,但这本质上是在执行该语句时发生的情况。 Your __get() call is only aware of the first call in that list, and nothing more.您的__get()调用只知道该列表中的第一个调用,仅此而已。 What you can do is handle the error on the calling side, with property_exists() or check for null :您可以做的是在调用端处理错误,使用property_exists()或检查null

$temp = $property->blah;
if( $temp === null || !property_exists( $temp, 'blah2')) {
    throw new Exception("Bad things!");
}

Note that property_exists() will fail if the object returned in $temp also relies on __get() , but that was not clear in the OP.请注意,如果$temp返回的对象也依赖于__get() ,则property_exists()将失败,但这在 OP 中并不清楚。

Actually, when you calling $property->foo->bar and $property class have magic __get method, you can verify only foo property and throw error only for it.实际上,当您调用$property->foo->bar$property类具有魔术 __get 方法时,您只能验证foo属性并仅为它抛出错误。

But if your foo is also an instance of the same class (or similar class with the same magic __get method) you can also verify bar property and throw the next error.但是,如果您的foo也是同一类(或具有相同魔术__get方法的类似类)的实例,您还可以验证bar属性并抛出下一个错误。

For example:例如:

class magicLeaf {
    protected $data;
    public function __construct($hashTree) {
        $this->data = $hashTree;
    }
    // Notice that we returning another instance of the same class with subtree
    public function __get($k) {
        if (array_key_exists($k, $this->data)) {
             throw new Exception ("Property $name is not defined");
        }
        if (is_array($this->data[$k])) { // lazy convert arrays to magicLeaf classes
            $this->data[$k] = new self($this->data[$k]);
        }
        return $this->data[$k];
    }
 }

And now just example of using it:现在只是使用它的例子:

$property = new magicLeaf(array(
    'foo' => 'root property',
    'bar' => array(
        'yo' => 'Hi!',
        'baz' => array(
            // dummy
        ),
    ),
));
$property->foo; // should contain 'root property' string
$property->bar->yo; // "Hi!"
$property->bar->baz->wut; // should throw an Exception with "Property wut is not defined"

So now you can see how to made it almost like you want.所以现在你可以看到如何让它几乎像你想要的那样。

Now just modify a little your __construct and magic __get methods and add new param to know where we are at each level:现在只需稍微修改您的__construct和魔法__get方法并添加新参数以了解我们在每个级别的位置:

...
    private $crumbs;
    public function __construct($hashTree, $crumbs = array()) {
        $this->data = $hashTree;
        $this->crumbs = $crumbs;
    }
    public function __get($k) {
        if (array_key_exists($k, $this->data)) {
             $crumbs = join('->', $this->crumbs);
             throw new Exception ("Property {$crumbs}->{$name} is not defined");
        }
        if (is_array($this->data[$k])) { // lazy convert arrays to magicLeaf classes
            $this->data[$k] = new self($this->data[$k], $this->crumbs + array($k));
        }
        return $this->data[$k];
    }
...

I think it should works like you want.我认为它应该像你想要的那样工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在PHP中的Overloading(使用__get()魔术方法或其他方法)类之外访问现有的私有属性? - How can I access an existing private property out of the class in Overloading(using __get() magic method or some other way) in PHP? 在C#中获取和设置(私有)属性,而不使用getter setter魔术方法重载 - Get and set (private) property in PHP as in C# without using getter setter magic method overloading 如何使用 try catch 异常抛出错误 - How to throw an error with a try catch exception 使用魔术__get方法时禁止显示不确定的属性警告 - Suppress unidentified property warning when using magic __get method PHP - 如何捕获“尝试获取非对象的属性”错误 - PHP - How to catch a 'Trying to get property of non-object' error 魔术获取方法的问题 - Problem with magic get method empty()和魔术方法__get() - empty() and magic method __get() 我该如何告诉用户doccommented魔术方法可以抛出一个异常? - How do I inform users a doccommented magic method can throw an Exception? PHP stdClass()与__get()魔术方法 - PHP stdClass() with __get() Magic Method 如何获得魔术方法的自动完成__call - PHP编辑器 - How to get autocomplete for magic method __call - PHP Editors
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM