dor65412 2015-02-28 15:20
浏览 43
已采纳

在PHP中,是否可以反向遍历Traversable类以查找根对象?

If one were to extend a built in class that implements Traversable would it be possible to obtain a reference to the root object perhaps with debug_backtrace?

For example if I have

$foo->bar->baz->biz->bon->bop->bob();

and in the bob method of bop I make use of debug_backtrace is there a way to get a reference to $foo? (And what is that way?)

If so is this even the most elegant or efficient way to do that?

I've tried looking at the debug_backtrace php.net page and I am still not the clear how to really use this function but from other material and experimentation I have my doubts (see update).

Update #1:

There does seem to be some debate on if debug_backtrace should be left in production code. PHP debug_backtrace in production code to get information about calling method?

Of course part of this is the issue of coupling, should a called object have knowledge of the object calling it?

Update #2

After finding Find out which class called a method in another class I tried my hand at using what I have learned to reverse traverse using debug_backtrace and discovered that it is not likely to be possible.

<?php

class mother extends SimpleXMLElement {

    protected $test_a = 'foo';
    public $test_b = 'bar';

    public function shout(){
        echo "test_a '" , $this->test_a , "' while test_b '" , $this->test_b , "'.
";
    }

    public function tell_mother($message,$limit=42){    
        $trace = debug_backtrace();
        --$limit;
        if($limit<1){
            echo "Enough of that pointlessness
";
            var_dump($trace);
            return 0;
        }
        if ( isset($trace[1]) && isset($trace[1]['object']) ){
            // $trace[1] is the caller class
            echo "I will pass the message on
";
            $trace[1]['object']->tell_mother($message,$limit);
        }else{
            echo "I am a " , get_class($this) , "
";
            echo "I have been told \"{$message}\".
";
            var_dump($trace);
        }
    }


}

echo "<pre>";

$xml = <<<XML
<?xml version='1.0'?> 
<a>lob
    <b>tob
        <c>bob
            <d>boo
                <e>bin
                    <f>baz
                        <g>bar
                            <h>foo</h>
                        </g>
                    </f>
                </e>
            </d>
        </c>
    </b>
</a>

XML;

$obj = simplexml_load_string($xml,'mother');
$obj->b->c->d->e->f->g->h->tell_mother("I love her");
$obj->shout();
$obj->b->c->d->e->f->shout();

As far as I can tell debug_backtrace cannot reverse traverse and no values held in object scope can be accessed.

Output from the above gives

I am a mother
I have been told "I love her".
array(1) {
  [0]=>
  array(7) {
    ["file"]=>
    string(58) "/home/[[snip]]_test.php"
    ["line"]=>
    int(64)
    ["function"]=>
    string(11) "tell_mother"
    ["class"]=>
    string(6) "mother"
    ["object"]=>
    object(mother)#2 (1) {
      [0]=>
      string(3) "foo"
    }
    ["type"]=>
    string(2) "->"
    ["args"]=>
    array(1) {
      [0]=>
      &string(10) "I love her"
    }
  }
}
test_a '' while test_b ''.
test_a '' while test_b ''.

My conclusion is that internally PHP does not see the child elements as being called by the parents. So I have edited my question to simply ask if it is possible to reverse traverse a Traversable class.

  • 写回答

1条回答 默认 最新

  • dqzd92796 2015-03-02 01:33
    关注

    Through trail and error (mostly error) which is detailed in the question I have learned that at least some PHP classes which implement Traversable only appear to be classes but are actually system resources.

    So debug_backtrace (my first idea) will not be able to to reverse the traversal. It is likely that this is not possible but with a little ingenuity a delegation wrapper can be created to provide two way traversing of actual objects.

    An example of one such class can be found in my answer to another question I asked: How do I obtain an iterative object reference to the root object in PHP?

    Furthermore debug_backtrace is not a great choice for doing anything in production beyond error logging and debugging for which it was designed.

    TD;DR : Probably not, but we can fix that.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 MATLAB动图的问题
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名