php PHP中静态属性的魔术__get getter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1279382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Magic __get getter for static properties in PHP
提问by treznik
public static function __get($value)
does not work, and even if it did, it so happens that I already need the magic __get getter for instance properties in the same class.
不起作用,即使它起作用了,碰巧我已经需要魔术 __get getter 用于同一类中的实例属性。
This probably is a yes or no question, so, it is possible?
这可能是一个是或否的问题,所以,有可能吗?
回答by Pascal MARTIN
No, it is not possible.
不,这是不可能的。
Quoting the manual page of __get:
Member overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods can not be declared static.
成员重载仅适用于对象上下文。这些魔术方法不会在静态上下文中触发。因此这些方法不能被声明为静态的。
In PHP 5.3, __callStatichas been added ; but there is no __getStaticnor __setStaticyet ; even if the idea of having/coding them often comes back on the php internals@ mailling-list.
在 PHP 5.3 中,__callStatic已添加;但没有__getStatic也不__setStatic之中; 即使拥有/编码它们的想法经常出现在 php internals@mailling-list 上。
There is even a Request for Comments: Static classes for PHP
But, still, not implemented (yet ? )
甚至还有一个评论请求:PHP 的静态类
但是,仍然没有实现(还没有实现?)
回答by mbrzuchalski
Maybe someone still need this:
也许有人还需要这个:
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");
}
}
回答by kmuenkel
Very nice mbrzuchalski. But it seems to only work on public variables. Just change your switch to this to allow it to access private/protected ones:
非常好的姆布祖哈尔斯基。但它似乎只适用于公共变量。只需将您的开关更改为此即可允许它访问私有/受保护的:
switch($match[1]) {
case 'get': return self::${$property->name};
case 'set': return self::${$property->name} = $args[0];
}
And you'd probably want to change the ifstatement to limit the variables that are accessible, or else it would defeat the purpose of having them be private or protected.
并且您可能希望更改if语句以限制可访问的变量,否则会破坏将它们设为私有或受保护的目的。
if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)
So for example, I have a class designed to pull various data for me out of a remote server using an ssh pear module, and I want it to make certain assumptions about the target directory based on what server it's being asked to look at. A tweaked version of mbrzuchalski's method is perfect for that.
例如,我有一个类旨在使用 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.");
}
}
回答by Jokerius
Also, you can get static properties accessing them like member properties, using __get():
此外,您可以使用 __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"
回答by Gilberto
try this:
尝试这个:
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);
回答by Jonny
Combining __callStaticand call_user_funcor call_user_func_arraycan give access to static properties in PHP class
组合__callStatic和call_user_func或call_user_func_array可以访问 PHP 类中的静态属性
Example:
例子:
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');

