PHPでの静的プロパティのマジック__getゲッター
-
16-09-2019 - |
質問
public static function __get($value)
仕事、そしてそれがなかったとしても、ので、私はすでに同じクラスのインスタンスプロパティのゲッター__get魔法が必要であることを起こるません。
これはおそらく、それが可能である、yesまたはnoの質問ですので、?
解決
いいえ、それは不可能です。
__get のマニュアルページはhref="http://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members" rel="noreferrer"> :
メンバーのみで動作のオーバーロード オブジェクトコンテキスト。これらのマジックメソッド 静的でトリガされることはありません 状況。したがって、これらのメソッドはできます 静的に宣言されていない。
PHP 5.3では、 __callStatic
にはされています追加;しかし、何の__getStatic
も__setStatic
はまだありません。それらをコーディング/持つのアイデアは、多くの場合、PHPの内部構造の@のmaillingリストに戻ってきた場合でもます。
はコメントのためにも、要求があります
しかし、まだ、実装されていないの(まだ?)の
他のヒント
たぶん誰かがまだこれを必要とします:
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梨モジュールを使用してリモートサーバのうち、私のために様々なデータを取得するために設計されたクラスを持っている、と私は見えるように頼まれているもののサーバーに基づいてターゲットディレクトリについて一定の仮定を作りたいのでで。 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.");
}
}
この方法を試してください。
class nameClass{
private static $_sData = [];
private static $object = null;
private $_oData = [];
public function __construct($data=[]){
$this->_oData = $data;
}
public static function setData($data=[]){
self::$_sData = $data;
}
public static function Data(){
if( empty( self::$object ) ){
self::$object = new self( self::$_sData );
}
return self::$object;
}
public function __get($key) {
if( isset($this->_oData[$key] ){
return $this->_oData[$key];
}
}
public function __set($key, $value) {
$this->_oData[$key] = $value;
}
}
nameClass::setData([
'data1'=>'val1',
'data2'=>'val2',
'data3'=>'val3',
'datan'=>'valn'
]);
nameClass::Data()->data1 = 'newValue';
echo(nameClass::Data()->data1);
echo(nameClass::Data()->data2);
また、あなたは、静的プロパティは__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"
__callStatic
とcall_user_func
または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');