7

オプションの配列を格納するクラスでプロパティをよく使用します。親クラスで宣言されたデフォルトからこれらのオプションを何とかマージできるようにしたいと思います。

私はいくつかのコードを示しました。

class A
{
    public $options = array('display'=>false,'name'=>'John');
}

class B extends A
{
    public $options = array('name'=>'Mathew');
}

を作成するときに、からのマージされた配列をB含めたい$optionsA::options

今起こっていることはこれです。

$b = new B();
print_r($b);
array('name'=>'Mathew');

を使ってこのようなものが欲しいarray_merge_recursive()です。

array('display'=>false,'name'=>'Mathew');
  • 多分それはコンストラクタでできることでしょうか?
  • これを の動作にすることは可能class Aですか? そのため、すべてのサブクラスで常に同じコードを実装する必要はありません。
  • リフレクションを使用して、両方のクラスで配列プロパティを自動検索してマージできますか?
4

3 に答える 3

6

前の回答に加えて、特定のケースに適している可能性がある別のアプローチは、PHP リフレクションまたは組み込みクラス関数を使用することです。後者を使用した基本的な例を次に示します。

class Organism
{
    public $settings;
    public $defaults = [
        'living' => true,
        'neocortex' => false,
    ];
    public function __construct($options = [])
    {
        $class = get_called_class();
        while ($class = get_parent_class($class)) {
            $this->defaults += get_class_vars($class)['defaults'];
        }
        $this->settings = $options + $this->defaults;
    }
}
class Animal extends Organism
{
    public $defaults = [
        'motile' => true,
    ];
}
class Mammal extends Animal
{
    public $defaults = [
        'neocortex' => true,
    ];
}

$fish = new Animal();
print_r($fish->settings); // motile: true, living: true, neocortex: false
$human = new Mammal(['speech' => true]);
print_r($human->settings); // motile: true, living: true, neocortex: true, speech: true
于 2016-04-22T05:44:11.543 に答える
4

インターフェイスをパブリック変数からメソッドに変更したことは承知していますが、おそらくうまくいくでしょう。setOps($ops)親 ops が引き続きマージされることを許可する場合、単純なメソッドを追加すると予期しない動作をする可能性があることに注意してください。

class A
{
    private $ops = array('display'=>false, 'name'=>'John');
    public function getops() { return $this->ops; }
}
class B extends A
{
    private $ops = array('name'=>'Mathew');
    public function getops() { return array_merge(parent::getOps(), $this->ops); }
}
class c extends B
{
    private $ops = array('c'=>'c');
    public function getops() { return array_merge(parent::getOps(), $this->ops); }
}

$c = new C();
print_r($c->getops());

アウト:

Array
(
    [display] => 
    [name] => Mathew
    [c] => c
)
于 2013-01-19T18:56:50.103 に答える
2

次のような単純なパターンを使用できます。

abstract class Parent {

    protected $_settings = array();

    protected $_defaultSettings = array(
        'foo' => 'bar'
    );

    public __construct($settings = array()) {
        $this->_settings = $settings + $this->_defaultSettings;
    }

}

このようにして、子クラスに適用されるデフォルトを簡単に変更できます。

class Child extends Parent {

    protected $_defaultSettings = array(
        'something' => 'different';
    );

}

または、より複雑なものを適用するには:

class OtherChild extends Parent {

    function __construct($settings = array()) {
        $this->_defaultSettings = Configure::read('OtherChild');
        return parent::__construct($settings);
    }

}

変数のマージ

Cake には、変数をマージするための関数が付属しています。コンポーネント、ヘルパーなどのコントローラ プロパティに使用されます。ただし、この関数を単純でない配列に適用する場合は注意してください。必要な / 期待どおりの結果が得られない場合があります。

于 2013-01-19T18:42:35.050 に答える