如何获取PHP中根对象的迭代对象引用? [英] How do I obtain an iterative object reference to the root object in PHP?

查看:92
本文介绍了如何获取PHP中根对象的迭代对象引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,需要一些基本的HTML5,一些DOM魔术将它变成一个扩展名SimpleXMLElement的类。这一切都从工厂开始(我可能会滥用该术语),称为XPage。



因此,我们可能有

 <?php 
$ MyPage = new XPage($ HTML);

到目前为止这么好。我现在需要做的是选择XML文档的一些部分,以便它们可以被加书签(我相信它有一个更好的名称),所以可以像这样

  $ MyPage-> ThatBit(foo) - > addChild('p',$ MyParagraph); 

理想情况下,我想要去

  $ MyPage->页面() - >身体 - >报头 - > RememberThisBitAs( foo 的); 

或直觉相似的东西。那么应该发生的是对象$ MyPage(XPage类型)应该传递引用,在这种情况下是html / body / header(这可能不是正确的XPath符号,但希望你可以遵循)。 >

这个想法是,最常见的访问区域可以更顺利地获得。这就是SimpleXML类(即使是我的扩展名)也可以在没有其他工厂的情况下运行,而且XPage也是一个单例。



然而,XPage类$ MyPage),它包含书签数组。据我所知,没有办法通过SimpleXML的迭代传递一个引用,所以一个孩子或孩子的孩子不能告诉工厂请给我加书签。



这会让我做恶作剧,如:

  $ MyPage - > addBookmark(foo,
$ MyPage-> page() - > body-> header-> getChildren());

哪个似乎不正确。



  $ MyPage-> page() - > body-> header-> RememberThisBitAs(foo ,$我的页面); 

这不是很糟糕,但仍然感觉错了。



如果没有过多的对象耦合或丑陋的自我引用,我该如何处理?



更新



我想知道是否可以使用debug_backtrace反向遍历一个类,但答案似乎不是。



在PHP中,可以反转遍历一个Traversable类来查找根对象?



其他类似的测试显示,设置元素上的类变量的值在可遍历堆栈中的任何其他元素都不可访问。 / p>

我将重点关注包装器建议。



更新



SimpleXML实际上并不是一个真实的对象,而是一个系统资源。这可以解释我的痛苦来自哪里。说说: http://php.net/manual/en/class.simplexmlelement.php



所以对于所有的对象感觉像一连串的对象互相调用,实际上并不是这样。

解决方案

选项1:引用根



您可以修改XPage类的方法来返回XPage对象的simpleXMLElements(或另一个类扩展simpleXMLElement)。那么那个类就可以有一个附加的属性来保存对root元素的引用。



所以基本上你的包装类看起来像这样(伪代码提前!):

  class Wrap extends simpleXMLElement 
{
private $ root = null;
private $ refs = array();

public function addReference($ name,$ element = null){
if($ element === null){
$ element =
}
if($ this-> root === null){
$ this-> refs [$ name] = $ this;
} else {
$ this-> root-> addReference($ name,$ this);
}
}

公共函数getReference($ name){
if($ this-> root === null){
return $这 - >参考文献[$名称];
} else {
return $ this-> root-> getReference($ name);
}
}
}

所以你的用例来自以上将如下所示:

  $ MyPage-> page() - > body-> header-> addReference ( foo 的); 

$ MyPage-> getReference(foo) - > addChild('p',$ MyParagraph);



选项2:添加ID



或者,您可以添加一个id属性到元素并检索它:

  $ MyPage-> page() - > body-> header-> addAttribute(id,foo); 

$ MyPage-> xpath(// * [@ id ='foo']) - > addChild('p',$ MyParagraph);


I have a class that takes some basic HTML5 and with some DOM magic turns it into a class which is an extension simpleXMLElement. This all starts at a "factory" (I might be abusing that term slightly) class called XPage.

Thus we might have

<?php
$MyPage = new XPage($HTML);

So far so good. What I now need to do is select some parts of the XML doc so that they can be "bookmarked" (I am sure that there is a better name for it) so one can go like this

$MyPage->ThatBit("foo")->addChild('p',$MyParagraph);

Ideally I would like to be able to go

$MyPage->page()->body->header->RememberThisBitAs("foo");

Or something intuitively similar. What should then happen is that the object $MyPage (of type XPage) should be passed the reference for, in this case html/body/header (that is probably not quite the right XPath notation but hopefully you can follow).

The idea being that the most commonly access areas can be gotten to more smoothly. This is where the SimpleXML class (even with my extension) runs into something it cannot do without another factory and also making XPage a singleton.

However it is the XPage class ($MyPage) that holds the array of "bookmarks". As far as I know there is no way of passing a reference down the iterations of SimpleXML so that a child or a child of a child could not tell the factory "bookmark me please".

This would leave me doing nasty things like:

$MyPage->addBookmark("foo", 
$MyPage->page()->body->header->getChildren() );

Which just does not seem right.

or

$MyPage->page()->body->header->RememberThisBitAs("foo",$MyPage);

which is not so bad but still "feels" wrong.

How do I approach this without excessive object coupling or ugly self referencing?

Update

I wondered if it was possible to reverse traverse a class using debug_backtrace but the answer appears to be no.

In PHP is it possible to reverse traverse a Traversable class to find the root object?

Other similar test have shown me that setting the value of a class variable on an element is not accessible at any other element in the traversable stack.

I am going to focus on the wrapper suggestion.

Update

SimpleXML is not actually a true object but a system resource. This could explain where my pain was coming from. Say the notes: http://php.net/manual/en/class.simplexmlelement.php

So for all the objects feel like a chain of objects calling each other this is not actually the case.

解决方案

Option 1: Reference to root

You could modify the methods of your XPage class to return XPage objects instead of simpleXMLElements (or another class extending simpleXMLElement). That class could then have an additional property holding a reference to the "root" element.

So basically your "wrapper class" would look something like this (pseudo-code ahead!):

class Wrap extends simpleXMLElement
{
    private $root = null;
    private $refs = array();

    public function addReference($name, $element = null) {
        if($element === null) {
            $element = $this;
        }
        if($this->root === null) {
            $this->refs[$name] = $this;
        } else {
            $this->root->addReference($name, $this);
        }
    }

    public function getReference($name) {
        if($this->root === null) {
            return $this->refs[$name];
        } else {
            return $this->root->getReference($name);
        }
    }
}

So your use-case from above would look like this:

$MyPage->page()->body->header->addReference("foo");

$MyPage->getReference("foo")->addChild('p',$MyParagraph);

Option 2: Add an id

Alternatively, you might just add an id attribute to the element and retrieve it by that:

$MyPage->page()->body->header->addAttribute("id", "foo");

$MyPage->xpath("//*[@id='foo']")->addChild('p',$MyParagraph);

这篇关于如何获取PHP中根对象的迭代对象引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆