65
public static function __get($value)

機能しません。機能したとしても、同じクラスのインスタンス プロパティに対して魔法の __get ゲッターが既に必要な場合があります。

これはおそらくイエスかノーの質問なので、可能ですか?

4

6 に答える 6

68

いいえ、できません。

__getのマニュアルページを引用:

メンバーのオーバーロードは、オブジェクト コンテキストでのみ機能します。これらの魔法のメソッドは、静的コンテキストではトリガーされません。したがって、これらのメソッドを static と宣言することはできません。


PHP 5.3 では、__callStaticが追加されました。しかし、まだあり__getStaticませ__setStaticん。それらを持っている/コーディングするという考えがphp internals@メーリングリストに頻繁に戻ってきたとしても.

コメントのリクエストもあります: Static classes for PHP
しかし、まだ実装されていません (まだ?)

于 2009-08-14T18:27:15.953 に答える
20

多分誰かがまだこれを必要としています:

static public function __callStatic($method, $args) {

  if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
    $reflector = new \ReflectionClass(__CLASS__);
    $property = strtolower($match[2]). $match[3];
    if ($reflector->hasProperty($property)) {
      $property = $reflector->getProperty($property);
      switch($match[1]) {
        case 'get': return $property->getValue();
        case 'set': return $property->setValue($args[0]);
      }     
    } else throw new InvalidArgumentException("Property {$property} doesn't exist");
  }
}
于 2011-09-13T18:56:22.030 に答える
5

とても素敵なmbrzuchalski。ただし、パブリック変数でのみ機能するようです。プライベート/保護されたものにアクセスできるようにするには、スイッチを次のように変更します。

switch($match[1]) {
   case 'get': return self::${$property->name};
   case 'set': return self::${$property->name} = $args[0];
}

また、ステートメントを変更して、ifアクセス可能な変数を制限することをお勧めします。そうしないと、それらを非公開または保護するという目的が無効になります。

if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)

たとえば、ssh pear モジュールを使用してリモート サーバーからさまざまなデータを取得するように設計されたクラスがあり、どのサーバーを参照するように求められているかに基づいて、ターゲット ディレクトリに関する特定の仮定を作成する必要があります。mbrzuchalski の方法を微調整したバージョンは、そのために最適です。

static public function __callStatic($method, $args) {
    if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
        $reflector = new \ReflectionClass(__CLASS__);
        $property = strtolower($match[2]). $match[3];
        if ($reflector->hasProperty($property)) {
            if ($property == "server") {
                $property = $reflector->getProperty($property);
                switch($match[1]) {
                    case 'set':
                        self::${$property->name} = $args[0];
                        if ($args[0] == "server1") self::$targetDir = "/mnt/source/";
                        elseif($args[0] == "server2") self::$targetDir = "/source/";
                        else self::$targetDir = "/";
                    case 'get': return self::${$property->name};
                }
            } else throw new InvalidArgumentException("Property {$property} is not publicly accessible.");
        } else throw new InvalidArgumentException("Property {$property} doesn't exist.");
    }
}
于 2014-03-11T14:26:27.680 に答える
0

__callStaticand call_user_funcorを組み合わせるとcall_user_func_array、PHP クラスの静的プロパティにアクセスできます

例:

class myClass {

    private static $instance;

    public function __construct() {

        if (!self::$instance) {
            self::$instance = $this;
        }

        return self::$instance;
    }

    public static function __callStatic($method, $args) {

        if (!self::$instance) {
            new self();
        }

        if (substr($method, 0, 1) == '$') {
            $method = substr($method, 1);
        }

        if ($method == 'instance') {
            return self::$instance;
        } elseif ($method == 'not_exist') {
            echo "Not implemented\n";
        }
    }

    public function myFunc() {
        echo "myFunc()\n";
    }

}

// Getting $instance
$instance = call_user_func('myClass::$instance');
$instance->myFunc();

// Access to undeclared
call_user_func('myClass::$not_exist');
于 2019-04-22T14:50:37.490 に答える
-1

また、__get() を使用して、メンバー プロパティのように静的プロパティにアクセスすることもできます。

class ClassName {    
    private static $data = 'smth';

    function __get($field){
        if (isset($this->$field)){
            return $this->$field;
        }
        if(isset(self::$$field)){  
            return self::$$field;  // here you can get value of static property
        }
        return NULL;
    }
}

$obj = new ClassName();
echo $obj->data; // "smth"
于 2016-07-11T10:56:53.267 に答える