0
<?php
class BaseClass {
  protected $data = array("foo" => 0, "bar" => 0, "baz" => 0);

  public function __set($name, $value) {
    if( array_key_exists($name, $this->data)){
      $func = "set_$name";
      return call_user_func_array(array($this,$func),array($value));
    }
  }


  public function __get($name) {
    if ( array_key_exists($name, $this->data)){
      $func = "get_$name";
      return call_user_func_array(array($this,$func),array());
    }
  }

  public function __call($method, $args) {
    if (method_exists($this,$method)) {
      return call_user_func_array(array($this,$method),$args);
    }

    if (substr($method, 0, 4) == 'set_'){
      $var_name = substr($method, 4);
      if (!(array_key_exists($var_name, $this->data))){ 
        return FALSE;
      }
      $this->data[$var_name] = $args[0];
      return TRUE;
    }

    if (substr($method, 0, 4) == 'get_'){
      $var_name = substr($method, 4);
      if (!(array_key_exists($var_name, $this->data))){ 
        return FALSE;
      }
      return $this->data[$var_name];
    }
  }
}

class SubClass extends BaseClass {
  protected $baz_changed = FALSE;

  public function set_baz($value) {
    if ($value != $this->baz){
      print "\n\nthis->data BEFORE SET:  ";
      print_r($this->data);
      print "\n\nthis->baz:  ";
      print_r($this->baz);
      print "\n\nPASSED baz:  ";
      print_r($value);
      $this->baz = $value;
      print "\n\nbaz AFTER SET:  ";
      print_r($this->baz); // appears it was set 
      print "\n\nDATA ARRAY:  ";
      print_r($this->data);  // but it wasn't ... what gives? 
      $this->baz_changed = TRUE;
    }
  }
}

$sc = new SubClass();
$sc->foo = 1;
print "\n\$sc->foo = $sc->foo\n";
$sc->baz = 5;
print "\$sc->baz = $sc->baz\n";
?>

次の結果は、私が期待したものとは異なります。

 $sc->foo = 1


 this->data BEFORE SET:  Array (
     [foo] => 1
     [bar] => 0
     [baz] => 0 )


 this->baz:  0

 PASSED baz:  5

 baz AFTER SET:  5

 DATA ARRAY:  Array (
     [foo] => 1
     [bar] => 0
     [baz] => 0 ) $sc->baz = 5

ご覧のとおり、baz が設定されているように見えますが、データ配列には設定されません。誰でも理由とこれを修正する方法を説明できますか?

編集: 結果の書式設定を修正し、このコード セクションにコンテキストを追加しました。

編集: 最後に $sc->baz = 5 とあることに気付きました。しかし、データ配列は更新されません。これは予想外で、baz のデータ配列バージョンが更新された方がよいと思います。SubClass で作成された新しいインスタンス変数の代わりに。

4

2 に答える 2

2

を再帰的に呼び出そうとしていますが__set、PHP はこれを明確に禁止しています。

  • では__set、あなたはset_baz
  • ではset_baz、あなたはそうします$this->baz = 5
  • これにより、 が呼び出されますが__set、PHP がこれを防止している場合を除きます。そうしないと、プログラムは決して終了しません。

__setすでに 内にいる場合はトリガーできません__set$this->baz代わりに、存在しないかのように正確に呼び出される新しいメンバー変数を動的に定義して__setいます。オブジェクトにとメンバーのvar_dump両方が含まれていることがわかります。$data$baz

内部set_bazでは、明示的に に書き込む必要があります$this->data。への書き込みはできません$this->baz

于 2012-08-16T05:23:38.793 に答える
0

set_baz$sc->baz = 5;メソッドがそこにあることがわかり、この行を実行して$this->baz = $value;baz プロパティの値を設定します。

__get と __set がクラスでも機能している場合、クラスで $this->data にアクセスするにはどうすればよいでしょうか?

于 2012-08-16T05:25:13.997 に答える