captador __get mágica para propiedades estáticas en PHP
-
16-09-2019 - |
Pregunta
public static function __get($value)
no funciona, e incluso si lo hiciera, se da la circunstancia de que ya necesito la magia __get captador de propiedades de la instancia de la misma clase.
Esto probablemente es un sí o un no, por lo que, es posible?
Solución
No, no es posible.
Miembro sobrecarga sólo funciona en contexto del objeto. Estos métodos mágicos no se desencadenan en estático contexto. Por lo tanto estos métodos pueden No ser declarado estática.
En PHP 5.3, __callStatic
ha sido adicional ; pero no hay ni __getStatic
__setStatic
todavía; aunque la idea de tener / codificación de ellos regresa a menudo en la lista de elementos internos mailling-php @.
Hay incluso un href="http://wiki.php.net/rfc/static-classes" Solicitud rel="noreferrer">
Pero, aún así, no se han aplicado (¿todavía?)
Otros consejos
Tal vez alguien todavía necesita esto:
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");
}
}
Muy bonito mbrzuchalski. Pero parece que funciona sólo en las variables públicas. Sólo cambia el interruptor a esta para que pueda acceder a las protegidas / privadas:
switch($match[1]) {
case 'get': return self::${$property->name};
case 'set': return self::${$property->name} = $args[0];
}
Y lo que probablemente quiere cambiar la declaración if
para limitar las variables que son accesibles, o de lo contrario sería incompatible con el objetivo de que ellos sean privados o protegidos.
if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)
Así, por ejemplo, tengo una clase diseñada para tirar de varios datos para sacarme de un servidor remoto a través de un módulo ssh pera, y lo quiero hacer ciertas suposiciones sobre el directorio de destino en base a qué servidor se le pide que busque a. Una versión modificada del método de mbrzuchalski es perfecto para eso.
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.");
}
}
intente lo siguiente:
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);
Además, puede obtener acceso a las propiedades estáticas ellos como propiedades de miembro, utilizando __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"
Combinando __callStatic
y call_user_func
o call_user_func_array
puede dar acceso a las propiedades estáticas en la clase PHP
Ejemplo:
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');