在PHP中可以反转遍历一个可遍历类来查找根对象? [英] In PHP is it possible to reverse traverse a Traversable class to find the root object?
问题描述
如果要扩展一个实现Traversable的内置类,那么可以通过debug_backtrace获得对根对象的引用?
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?
例如,如果我有
$foo->bar->baz->biz->bon->bop->bob();
在bop的bob方法中我使用debug_backtrace有一种方法来获取$ foo的? (那怎么样?)
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?
我试过看看debug_backtrace php.net页面,我仍然不清楚如何真正使用这个功能,但从其他材料和实验我有我的疑虑(见更新)。
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).
更新#1:
似乎有一些争论,如果debug_backtrace应该留在生产代码。 生产代码中的PHP debug_backtrace
There does seem to be some debate on if debug_backtrace should be left in production code. PHP debug_backtrace in production code?
当然,其中一部分是耦合的问题,一个被调用的对象是否知道对象调用它?
Of course part of this is the issue of coupling, should a called object have knowledge of the object calling it?
更新#2
找到在另一个类中查找哪个类叫做一个方法?我尝试使用我学到的方法来使用debug_backtrace来反转遍历,并发现它不太可能。 p>
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 , "'.\n";
}
public function tell_mother($message,$limit=42){
$trace = debug_backtrace();
--$limit;
if($limit<1){
echo "Enough of that pointlessness\n";
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\n";
$trace[1]['object']->tell_mother($message,$limit);
}else{
echo "I am a " , get_class($this) , "\n";
echo "I have been told \"{$message}\".\n";
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();
据我所知,debug_backtrace不能反转遍历,也不能访问对象范围中保留的值。
As far as I can tell debug_backtrace cannot reverse traverse and no values held in object scope can be accessed.
上面的输出给了
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 ''.
我的结论是,PHP内部看不到父元素调用的子元素。所以我已经编辑了我的问题,只要问是否可以反转遍历一个可遍历的类。
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.
推荐答案
通过跟踪和错误(主要是错误),我在这个问题中详细介绍了至少有一些PHP类实现可扩展只显示为类,但实际上是系统资源。
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.
所以debug_backtrace(我的第一个想法)将无法反转遍历。很可能这是不可能的,但有一点创造性,可以创建一个委托包装器来提供实际对象的双向遍历。
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.
一个这样的类的例子可以在我对另一个问题的答复中找到:如何获取PHP中根对象的迭代对象引用?
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?
此外,debug_backtrace不是
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:可能不是,但我们可以解决这个问题。
TD;DR : Probably not, but we can fix that.
这篇关于在PHP中可以反转遍历一个可遍历类来查找根对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!