..

2017-11-17 193 views
6

Ben birkaç XML çerçeveleri inşa etmek oluşturmak ettik sınıfa aşağıdakileri kontrol edin uzatmak veya KURU önlemek için SimpleXML uygulamak ..

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/>' 
     ); 
    } 
} 

öğelerin sırasını değiştirmeden $frame->addChild('command') ve $command->addChild('authKey', 'authkey') tekrarını önlemek için en iyi yolu nedir

?

Lütfen kodu iyileştirmeye yardım edin. Teşekkürler

cevap

0

Sahip olduğunuz kod basitleştirilmiş olsa da, karmaşıklıklar vardır. Yaptığım şekilde çerçevenin yapısını frame yöntemine taşır. Diğer tüm yordamların her biri <command> düğümünün temelini oluşturur ve bunu iletir, çerçeve yöntemi daha sonra authkey biti ekler. bağımlılıklar da karışık değil yani bu bu taşıyabilirsiniz oldukça basit bir örnektir gibi

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(); 
    } 
} 
0

görünüyor ... AMA hepsi çerçeveler üzerinde yapılması gerekir - Bu kod aynı yapacağını kendi başına bir yönteme. PHP'de, nesnelerin referans olarak geçtiğini unutmayın. Yani, nesne değişkeni aslında sadece nesne için bir bellek işaretçisidir ve skaler ve dizi değişkenlerinin varsayılan olarak nasıl aktarıldığının tersine (değer olarak ... hiçbir bellek işaretçisi yok) anlamına gelir.

Paket servisi olan restoran, clone numaralı telefonu kullanmıyor olmanız koşuluyla nesnenin her zaman aynı olması.

<?php 
class CommandBuilder 
{ 
    public function preBuild(\SimpleXMLElement $node) 
    { 
     $command = $node->addChild('command'); 
     $command->addChild('authKey', 'authkey'); 
    } 
} 

Şimdi, bunun yerine söz konusu iki yöntemi çağırmak, sadece $this->preBuild($frame) çağırabilir.

2

nasıl ayrı oluşturucu sınıfı oluşturmak Böyle bir şey, hakkında:

class CommandBuilder 
{ 
    private $commandName; 

    private $params = []; 

    public function __construct($commandName) { 
    $this->commandName = $commandName; 
    } 

    // convenience method, to allow for cleaner fluent interface usage 
    public static function create($commandName) { 
    return new self($commandName); 
    } 

    public function addParam($paramName, $paramValue) { 
    $this->params[] = [ 'name' => $paramName, 'value' => $paramValue ]; 

    return $this; 
    } 

    public function build() { 
    $app = new SimpleXMLElement('<app/>'); 
    $commandContainer = $app->addChild('command'); 
    $command = $commandContainer->addChild($this->commandName); 
    foreach($this->params as $param) { 
     $command->addChild($param[ 'name' ], $param[ 'value' ]); 
    } 
    $commandContainer->addChild('authKey', 'authKey'); 

    return $app->asXML(); 
    } 
} 

ve sonra özel uygulama komutlarını oluşturur ayrı bir sınıf var:

class AppCommands 
{ 
    public function login($username, $password) { 
    return CommandBuilder::create('login')->addParam('username', $username) 
              ->addParam('password', $password) 
              ->build(); 
    } 

    public function info($id) { 
    return CommandBuilder::create('product')->addParam('id', $id) 
               ->build(); 
    } 
} 

Kullanımı aynı kalır, CommandBuilder:

$ac = new AppCommands; 

echo $ac->login('MyUsername', 'MyPassword'); 
echo PHP_EOL; 
echo $ac->info(5); 
yerine AppCommands'u başlattığınızda Eğer isteseydim

View this example on eval.in

, elbette dinamik olarak da CommandBuilder için authKey geçmesi yerine olabilir sabit kodlama gibi bir şeyle, içine:

class CommandBuilder 
{ 
    private $commandName; 

    private $authKey; 

    private $params = []; 

    public function __construct($commandName, $authKey) { 
    $this->commandName = $commandName; 
    $this->authKey = $authKey; 
    } 

    public static function create($commandName, $authKey) { 
    return new self($commandName, $authKey); 
    } 

    /* ... */ 

    public function build() { 

    /* ... */ 

    $commandContainer->addChild('authKey', $this->authKey); 

    return $app->asXML(); 
    } 
0

Nasıl bir "iskelet yazma hakkında msgstr "bir parametre olarak kabul edilebilir bir yöntemi kabul eder ve bunu ortada yürütür. (Bir dezavantaj şimdi, $username ve $password gibi parametreler tekrarlanır.)