5

私はクラスを持っています:

class Foo {
    // Accept an assoc array and appends its indexes to the object as property
    public function extend($values){
        foreach($values as $var=>$value){
            if(!isset($this->$var))
                $this->$var = $value;
        }
    }
}

$Foo = new Foo;
$Foo->extend(array('name' => 'Bee'));

これで、$Fooオブジェクトには値を持つパブリックnameプロパティが含まれますBee

関数を変更extendして変数を非公開にする方法は?

編集 プライベート配列を使用することは別の方法であり、間違いなく私の答えではありません。

4

4 に答える 4

4

このようなことができます。

この__get関数は、指定されたキーがプライベート プロパティ内に設定されているかどうかを確認します。

class Foo {

private $data = array();

// Accept an array and appends its indexes to the object as property
public function extend($values){
    foreach($values as $i=>$v){
        if(!isset($this->$i))
            $this->data[$i] = $v;
    }
}

public function __get($key) {
    if (isset($this->data[$key])) {
        return $this->data[$key];
    }
}

}
于 2012-11-16T10:53:00.290 に答える
3

単純な、悪いデザイン。

実行時にプライベート [!] フィールドを追加する目的は何ですか? 既存のメソッドは、そのような追加されたフィールドに依存できず、オブジェクトの機能をいじることになります。

オブジェクトをハッシュマップのように動作させたい場合 (つまり、 を呼び出すだけでよい場合$obj -> newField = $newValue)、マジック__get__setメソッドの使用を検討してください。

于 2012-11-16T10:56:21.780 に答える
0

アクセサーベースのアプローチは次のとおりです。

class Extendible
{
    private $properties;

    public function extend(array $properties)
    {
        foreach ($properties as $name => $value) {
            $this->properties[$name] = $value;
        }
    }

    public function __call($method, $parameters)
    {
        $accessor = substr($method, 0, 3);
        $property = lcfirst(substr($method, 3));
        if (($accessor !== 'get' && $accessor !== 'set')
                || !isset($this->properties[$property])) {
            throw new Exception('No such method!');
        }
        switch ($accessor) {
            case 'get':
                return $this->getProperty($property);
                break;
            case 'set':
                return $this->setProperty($property, $parameters[0]);
                break;
        }
    }

    private function getProperty($name)
    {
        return $this->properties[$name];
    }

    private function setProperty($name, $value)
    {
        $this->properties[$name] = $value;
        return $this;
    }
}

デモ:

try {
    $x = new Extendible();
    $x->extend(array('foo' => 'bar'));
    echo $x->getFoo(), PHP_EOL; // Shows 'bar'
    $x->setFoo('baz');
    echo $x->getFoo(), PHP_EOL; // Shows 'baz'
    echo $x->getQuux(), PHP_EOL; // Throws Exception
} catch (Exception $e) {
    echo 'Error: ', $e->getMessage(), PHP_EOL;
}
于 2012-11-16T11:10:55.863 に答える
0

私は配列全体で作業します:

$Foo = new Foo;
$Foo->setOptions(array('name' => 'Bee'));

class Foo {
    private $options = array();

    public function setOptions(array $options) {
        $this->options = $options;
    }

    public function getOption($value = false) {
        if($value) {
            return $this->options[$value];    
        } else {
            return $this->options;
        }
    }
}

次に、他の値が必要な場合にさらにオプションがあり、配列を反復処理してそれらを操作できます。ほとんどの場合、単一の変数がある場合、少し複雑になります。

于 2012-11-16T10:53:37.913 に答える