Php 扩展或实现simplexml以避免干燥

Php 扩展或实现simplexml以避免干燥,php,xml,php-7,Php,Xml,Php 7,请检查我为构建几个XML框架而创建的以下类 class CommandBuilder { public function __construct() { // } public function login($username, $password) { $frame = $this->frame(); $command = $frame->addChild('command');

请检查我为构建几个XML框架而创建的以下类

class CommandBuilder
{
    public function __construct()
    {
        //
    }

    public function login($username, $password)
    {
        $frame = $this->frame();

        $command = $frame->addChild('command');
        $login = $command->addChild('login');
        $login->addChild('username', $username);
        $login->addChild('password', $password);
        $command->addChild('authKey', 'authkey');

        return $frame->asXML();
    }

    public function info($id)
    {
        $frame = $this->frame();

        $command = $frame->addChild('command');
        $login = $command->addChild('product');
        $login->addChild('id', $id);
        $command->addChild('authKey', 'authkey');

        return $frame->asXML();
    }

    protected function frame()
    {
        return new SimpleXMLElement(
            '<app/>'
        );
    }
}
类命令生成器
{
公共函数构造()
{
//
}
公用函数登录($username,$password)
{
$frame=$this->frame();
$command=$frame->addChild('command');
$login=$command->addChild('login');
$login->addChild('username',$username);
$login->addChild('password',$password);
$command->addChild('authKey','authKey');
返回$frame->asXML();
}
公共功能信息($id)
{
$frame=$this->frame();
$command=$frame->addChild('command');
$login=$command->addChild('product');
$login->addChild('id',$id);
$command->addChild('authKey','authKey');
返回$frame->asXML();
}
受保护的功能框架()
{
返回新的SimpleXMLElement(
''
);
}
}
在不改变元素顺序的情况下,避免重复
$frame->addChild('command')
$command->addChild('authKey','authKey')
的最佳方法是什么


请帮助改进代码。谢谢

虽然您的代码可以简化,但也有一些复杂的地方。我这样做的方式将框架的构建移动到
frame
方法中。其他每个例程都构建
节点的基础并将其传递,然后frame方法添加authkey位。这段代码将做同样的事情-但它必须在所有帧上完成

class CommandBuilder
{
    public function __construct()
    {
        //
    }

    public function login($username, $password)
    {
        $command = new SimpleXMLElement('<command />');
        $login = $command->addChild('login');
        $login->addChild('username', $username);
        $login->addChild('password', $password);

        return $this->frame($command);
    }

    public function info($id)
    {
        $command = new SimpleXMLElement('<command />');
        $login = $command->addChild('product');
        $login->addChild('id', $id);

        return $this->frame($command);
    }

    protected function frame( $node )   {
        $node->addChild('authKey', 'authkey');
        $xml = new DOMDocument();
        $xml->loadXML('<app/>');
        // Convert SimpleXML to DOMDocument
        $fromDom = dom_import_simplexml($node);
        // Add in the $node passed in to the frame
        $xml->documentElement->appendChild($xml->importNode($fromDom, true));

        return $xml->saveXML();
    }
}
类命令生成器
{
公共函数构造()
{
//
}
公用函数登录($username,$password)
{
$command=新的SimpleXMLElement(“”);
$login=$command->addChild('login');
$login->addChild('username',$username);
$login->addChild('password',$password);
返回$this->frame($command);
}
公共功能信息($id)
{
$command=新的SimpleXMLElement(“”);
$login=$command->addChild('product');
$login->addChild('id',$id);
返回$this->frame($command);
}
受保护的功能帧($node){
$node->addChild('authKey','authKey');
$xml=newdomdocument();
$xml->loadXML(“”);
//将SimpleXML转换为DOMDocument
$fromDom=dom\u import\u simplexml($node);
//添加传入框架的$node
$xml->documentElement->appendChild($xml->importNode($fromDom,true));
返回$xml->saveXML();
}
}

看起来您的依赖项没有太多混淆,因此这是一个相当简单的示例,您可以将其转换为自己的方法。请记住,在PHP中,对象是通过引用传递的。这意味着对象变量实际上只是指向对象的内存指针,这与默认情况下传递标量和数组变量的方式(按值…也称为无内存指针)形成对比

它的好处是,无论在哪里使用,只要不使用,对象总是相同的

addChild('command');
$command->addChild('authKey','authKey');
}
}

现在,您不需要调用这两个方法,只需调用
$this->preBuild($frame)

这样的函数,您可以创建一个单独的生成器类:

类命令生成器
{
私有$commandName;
私有$params=[];
公共函数构造($commandName){
$this->commandName=$commandName;
}
//方便的方法,允许更干净流畅的界面使用
公共静态函数create($commandName){
返回新的self($commandName);
}
公共函数addParam($paramName,$paramValue){
$this->params[]=['name'=>$paramName,'value'=>$paramValue];
退还$this;
}
公共功能构建(){
$app=新的SimpleXMLElement('

如果需要,您当然也可以动态地将
authKey
传递给
CommandBuilder
,而不是在内部硬编码,例如:

类命令生成器
{
私有$commandName;
私人$authKey;
私有$params=[];
公共函数构造($commandName,$authKey){
$this->commandName=$commandName;
$this->authKey=$authKey;
}
公共静态函数create($commandName,$authKey){
返回新的self($commandName,$authKey);
}
/* ... */
公共功能构建(){
/* ... */
$commandContainer->addChild('authKey',$this->authKey);
返回$app->asXML();
}
如何编写一个“骨架”方法,该方法接受参数为可调用的,并在中间执行它。(缺点是现在,参数如“代码> $用户名<代码> >代码> $密码< /代码>)重复。
<?php
class CommandBuilder
{
    public function preBuild(\SimpleXMLElement $node)
    {
        $command = $node->addChild('command');
        $command->addChild('authKey', 'authkey');
    }
}
class CommandBuilder
{
    // ...

    private function createCommand(callable $cmdEnricher)
    {
        $frame = $this->frame();

        $command = $frame->addChild('command');
        $cmdEnricher($command);
        $command->addChild('authKey', 'authkey');

        return $frame->asXML();
    }

    public function login($username, $password)
    {
        return $this->createCommand(function ($command) use ($username, $password) {
            $login = $command->addChild('login');
            $login->addChild('username', $username);
            $login->addChild('password', $password);
        });
    }

    public function info($id)
    {
        return $this->createCommand(function ($command) use ($id) {
            $login = $command->addChild('product');
            $login->addChild('id', $id);
        });
    }

    // ...
}