web-dev-qa-db-fra.com

Comment obtenir la propriété protégée de l'objet dans PHP

J'ai un objet ayant une propriété protégée que je veux obtenir et définir. L'objet ressemble à

Fields_Form_Element_Location Object
(
[helper] => formText
[_allowEmpty:protected] => 1
[_autoInsertNotEmptyValidator:protected] => 1
[_belongsTo:protected] => 


[_description:protected] => 
[_disableLoadDefaultDecorators:protected] => 
[_errorMessages:protected] => Array
    (
    )

[_errors:protected] => Array
    (
    )
[_isErrorForced:protected] => 
[_label:protected] => Current City


[_value:protected] => 93399
[class] => field_container field_19 option_1 parent_1
)

Je veux obtenir la propriété value de l'objet. Quand j'essaie $obj->_value ou $obj->value il génère une erreur. J'ai cherché et trouvé la solution à utiliser PHP Reflection Class. Cela a fonctionné sur mon local mais sur le serveur PHP la version est 5.2.17 Je ne peux donc pas utiliser cette fonction ici. Donc, une solution comment obtenir une telle propriété?

49
Awais Qarni

C’est ce que "protégé" est destiné, comme l'explique le chapitre Visibilité :

Les membres déclarés protégés ne sont accessibles que dans la classe elle-même et par les classes héritées et parent.

Si vous avez besoin d'accéder à la propriété de l'extérieur, choisissez-en une:

  • Ne le déclarez pas comme protégé, rendez-le public
  • Écrivez quelques fonctions pour obtenir et définir la valeur (getters et setters)

Si vous ne souhaitez pas modifier la classe d'origine (car il s'agit d'une bibliothèque tierce, vous ne voulez pas déranger), créez une classe personnalisée qui étend la classe d'origine:

class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}

... et ajoutez votre getter/setter là.

22
Álvaro González

Voici l'exemple très simple (sans erreur de vérification) de l'utilisation de ReflectionClass:

function accessProtected($obj, $prop) {
  $reflection = new ReflectionClass($obj);
  $property = $reflection->getProperty($prop);
  $property->setAccessible(true);
  return $property->getValue($obj);
}

Je sais que vous avez dit que vous étiez limité à la version 5.2, mais c'était il y a 2 ans, 5.5 est la version la plus ancienne prise en charge et j'espère pouvoir aider les gens avec les versions modernes.

88
drewish

Object peut être transtypé dans un tableau (associatif) et les membres protégés ont des clés précédées de chr(0).'*'.chr(0) (voir le commentaire de @ fardelian ici ). En utilisant cette fonctionnalité non documentée, vous pouvez écrire un "exposer":

function getProtectedValue($obj,$name) {
  $array = (array)$obj;
  $prefix = chr(0).'*'.chr(0);
  return $array[$prefix.$name];
}

Alternativement, vous pouvez analyser la valeur de serialized string, où (il semble) que les membres protégés ont le même préfixe (j'espère que php 5.2 ne l'a pas changé).

44
Jan Turoň

Si vous voulez bricoler avec une classe sans ajouter de getters et de setters ...

PHP 7 ajoute une méthode d'appel ($ obj) (plus rapide que l'ancien bindTo) lors des fermetures vous permettant d'appeler une fonction de sorte que le $this variable agira comme dans une classe avec des autorisations complètes.

 //test class with restricted properties
 class test{
    protected $bar="protected bar";
    private $foo="private foo";
    public function printProperties(){
        echo $this->bar."::".$this->foo;   
     }
 }

$testInstance=new test();
//we can change or read the restricted properties by doing this...
$change=function(){
    $this->bar="I changed bar";
    $this->foo="I changed foo";
};
$change->call($testInstance);
$testInstance->printProperties();
//outputs I changed bar::I changed foo in php 7.0 
10
user2782001

Si vous ne pouvez pas modifier la classe d'origine et que son extension n'est pas une option non plus, vous pouvez utiliser l'interface ReflectionProperty.

La bibliothèque phptoolcase a une méthode pratique pour cela:

$value = PtcHandyMan::getProperty( $your_object , ‘propertyName’);

Propriété statique d'une classe singleton:

$value = PtcHandyMan::getProperty( ‘myCLassName’ , ‘propertyName’);

Vous pouvez trouver l’outil ici: http://phptoolcase.com/guides/ptc-hm-guide.html

3
Charlie