Magic __get Getter für statische Eigenschaften in PHP
-
16-09-2019 - |
Frage
public static function __get($value)
funktioniert nicht, und selbst wenn es so wäre, benötige ich möglicherweise bereits die magischen __get Getter-Eigenschaften für Instanzen in derselben Klasse.
Dies ist wahrscheinlich eine Ja- oder Nein-Frage. Ist es also möglich?
Lösung
Nein, es ist nicht möglich.
Zitiert die -Seite des __get :
Überlastung Mitglied funktioniert nur in Objektkontext. Diese magischen Methoden wird nicht in statischen ausgelöst werden Kontext. Daher können diese Methoden nicht statisch deklariert werden.
In PHP 5.3, __callStatic
wurde hinzugefügt ; aber es gibt keine __getStatic
noch __setStatic
noch; auch wenn die Idee, / Codierung sie oft wieder auf der PHP-Interna @ mailling-Liste kommt.
Es gibt sogar eine Request for Comments: Statische Klassen für PHP
aber noch nicht umgesetzt (noch?)
Andere Tipps
Vielleicht hat jemand noch diese brauchen:
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");
}
}
Sehr schöner Mbrzuchalski.Aber es scheint nur mit öffentlichen Variablen zu funktionieren.Ändern Sie einfach Ihren Schalter wie folgt, um den Zugriff auf private/geschützte Dateien zu ermöglichen:
switch($match[1]) {
case 'get': return self::${$property->name};
case 'set': return self::${$property->name} = $args[0];
}
Und wahrscheinlich möchten Sie das ändern if
Anweisung, um die Variablen zu begrenzen, auf die zugegriffen werden kann, andernfalls würde der Zweck, sie privat oder geschützt zu halten, zunichte gemacht.
if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)
So habe ich zum Beispiel eine Klasse, die mithilfe eines SSH-Pear-Moduls verschiedene Daten für mich von einem Remote-Server abruft, und ich möchte, dass sie bestimmte Annahmen über das Zielverzeichnis trifft, basierend auf dem Server, den sie anzeigen soll.Eine optimierte Version der Methode von Mbrzuchalski ist dafür perfekt.
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.");
}
}
versuchen Sie dies:
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);
Sie können aber auch statische Eigenschaften erhalten sie wie Elementeigenschaften zugreifen, mit __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"
Die Kombination __callStatic
und call_user_func
oder call_user_func_array
kann den Zugriff auf statische Eigenschaften in PHP-Klasse geben
Beispiel:
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');