public static function __get($value)
ne fonctionne pas, et même si c'est le cas, il se trouve que j'ai déjà besoin du getter magique __get pour les propriétés d'instance dans la même classe.
C'est probablement une question oui ou non, alors, c'est possible?
Non ce n'est pas possible.
Citant le page de manuel de __get :
La surcharge des membres ne fonctionne que dans le contexte de l'objet. Ces méthodes magiques ne seront pas déclenchées dans un contexte statique. Par conséquent, ces méthodes ne peuvent pas être déclarées statiques.
Dans PHP 5.3, __callStatic
a été ajouté; mais il n'y a pas __getStatic
ni __setStatic
encore ; même si l'idée de les avoir/les coder revient souvent sur php internals @ mailling-list.
Il y a même un Request for Comments: Static classes for PHP
Mais, toujours pas implémenté (encore?)
Peut-être que quelqu'un a encore besoin de ça:
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");
}
}
Très beau mbrzuchalski. Mais cela ne semble fonctionner que sur des variables publiques. Modifiez simplement votre commutateur sur celui-ci pour lui permettre d'accéder à ceux privés/protégés:
switch($match[1]) {
case 'get': return self::${$property->name};
case 'set': return self::${$property->name} = $args[0];
}
Et vous voudrez probablement changer l'instruction if
pour limiter les variables qui sont accessibles, sinon cela irait à l'encontre du but de les avoir privées ou protégées.
if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)
Ainsi, par exemple, j'ai une classe conçue pour extraire pour moi diverses données d'un serveur distant à l'aide d'un module ssh pear, et je veux qu'il fasse certaines hypothèses sur le répertoire cible en fonction du serveur qu'il est invité à consulter. Une version modifiée de la méthode de mbrzuchalski est parfaite pour cela.
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.");
}
}
essaye ça:
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);
Combiner __callStatic
et call_user_func
ou call_user_func_array
peut donner accès aux propriétés statiques dans la classe PHP
Exemple:
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');
De plus, vous pouvez obtenir des propriétés statiques y accédant comme les propriétés des membres, en utilisant __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"