public static function __get($value)
機能しません。機能したとしても、同じクラスのインスタンス プロパティに対して魔法の __get ゲッターが既に必要な場合があります。
これはおそらくイエスかノーの質問なので、可能ですか?
public static function __get($value)
機能しません。機能したとしても、同じクラスのインスタンス プロパティに対して魔法の __get ゲッターが既に必要な場合があります。
これはおそらくイエスかノーの質問なので、可能ですか?
いいえ、できません。
__getのマニュアルページを引用:
メンバーのオーバーロードは、オブジェクト コンテキストでのみ機能します。これらの魔法のメソッドは、静的コンテキストではトリガーされません。したがって、これらのメソッドを static と宣言することはできません。
PHP 5.3 では、__callStatic
が追加されました。しかし、まだあり__getStatic
ませ__setStatic
ん。それらを持っている/コーディングするという考えがphp internals@メーリングリストに頻繁に戻ってきたとしても.
コメントのリクエストもあります: Static classes for PHP
しかし、まだ実装されていません (まだ?)
多分誰かがまだこれを必要としています:
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");
}
}
とても素敵な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.");
}
}
__callStatic
and call_user_func
orを組み合わせると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');
また、__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"