为了账号安全,请及时绑定邮箱和手机立即绑定

使用其他 XML 源扩展 SimpleXML 类

使用其他 XML 源扩展 SimpleXML 类

PHP
达令说 2023-10-15 16:34:32
对于当前的项目来说,如果能够扩展 SimpleXML 类来访问 SimpleXML 可遍历的魔力,那就太棒了。由于我无法理解的原因,构造函数是最终的。无论如何,我该如何延长课程呢?到目前为止,我所做的是避免在子类上使用构造函数,而是创建一个静态方法来返回一个 XML 字符串,该字符串可在调用者中用于构造对象。不太漂亮,因为它给调用者带来了应该隐藏的模式的负担,但它正在起作用。是否有更优雅的方法来避免最终构造函数的阻碍设计选择?namespace acme.com;class SubXML extends \SimpleXML{   static public createXML() {        // here we return a magnificent XML string        // probably from a DB or a REST interface   }}$o = new \SubXML( \SubXML::createXML() );
查看完整描述

1 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

SimpleXMLElement 上的构造函数不仅仅是初始化 PHP 对象,而是调用外部库来初始化一些内部内存结构,然后在您遍历 XML 文档或片段时重用这些内部内存结构。

扩展类的一种受支持的方法是将类的名称作为第二个参数传递给simplexml_load_string或simplexml_load_file,这将在您遍历时用于所有元素和属性。例如:

class MyXML extends SimpleXMLElement {

    public function hello() { echo "Hello ", $this->getName(); }

}

$sx = simplexml_load_string('<foo><bar><baz>42</baz></bar></foo>', 'MyXML');

$sx->bar->baz->hello();

目前尚不清楚如果MyXML在这种情况下有一个自定义构造函数会发生什么:是否应该为每个子元素调用它?有何论据?


撇开这一点不谈,您的实际要求似乎是拥有某种工厂,它从某个来源(数据库、API)获取数据并创建某种对象。您的静态方法似乎是一个明智的方向,但可以直接返回对象而不是字符串:


class SubXML extends SimpleXMLElement {

   public static function createXMLfromDB($db) {

        $xmlString = $db->query('Select XML from SpecialTable');

        return simplexml_load_string($xmlString, static::class);

   }

}

但是,我认为继承首先并不是表示这一点的特别好的方式 - 结果对象可能不需要知道其数据来自哪里,它需要能够表示该数据。因此,您的工厂可以是一个完全不同的类,以更适合测试的方式管理其依赖项:


class MyXMLFromDBFactory {

    private MyDBWrapper $db;


    public function __construct(MyDBWrapper $db) {

        $this->db = $db;

    }


    public function createXML() {

        $xmlString = $db->query('Select XML from SpecialTable');

        return simplexml_load_string($xmlString);

    }

}

然后你可以有一个单独的MyXMLFromAPIFactory,MyXMLFromFileOnAmazonS3Factory等。如果你愿意,这些都可以返回相同的扩展SimpleXMLElement类,甚至可以将类名作为参数并将其传递给simplexml_load_string。


查看完整回答
反对 回复 2023-10-15
  • 1 回答
  • 0 关注
  • 56 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信