2009-11-19 5 views
10

J'ai tiré une classe de Exception, essentiellement comme ceci:accès variable privée de fonction membre en PHP

class MyException extends Exception { 

    private $_type; 

    public function type() { 
     return $this->_type; //line 74 
    } 

    public function __toString() { 

     include "sometemplate.php"; 
     return ""; 

    } 

} 

Puis, je tirais de MyException comme ceci:

class SpecialException extends MyException { 

    private $_type = "superspecial"; 

} 

Si je throw new SpecialException("bla") de une fonction, l'attraper, et aller echo $e, puis la fonction __toString devrait charger un modèle, afficher cela, puis ne pas réellement retourner quoi que ce soit à l'écho.

Ceci est essentiellement ce qui est dans le fichier modèle

<div class="<?php echo $this->type(); ?>class"> 

    <p> <?php echo $this->message; ?> </p> 

</div> 

dans mon esprit, cela devrait certainement travailler. Cependant, je reçois l'erreur suivante lorsqu'une exception est levée et je tente de l'afficher:

Erreur fatale: propriété privée Impossible d'accéder à SpecialException :: type $ _ dans C: \ chemin \ \ exceptions. php en ligne

quelqu'un peut-il expliquer pourquoi j'enfreint le règlement ici? Est-ce que je fais quelque chose d'horriblement spirituel avec ce code? Existe-t-il une façon beaucoup plus idiomatique de gérer cette situation? Le point de la variable $_type est (comme indiqué) que je veux utiliser une classe div différente en fonction du type d'exception interceptée.

+0

Comme je l'ai écrit là-bas: Il est très très très laid à faire __toString() renvoie une chaîne vide. Je ne peux vraiment pas voir n'importe quel usage pour de telles choses. – tuergeist

+0

Le retour vide de __toString() pour une exception est encore plus douteux. – tuergeist

Répondre

32

Nom de la variable protégée:

* Public: anyone either inside the class or outside can access them 
* Private: only the specified class can access them. Even subclasses will be denied access. 
* Protected: only the specified class and subclasses can access them 
+1

+1 directement au point – Andrew

+1

Note: En PHP 'protected' signifie que vos parents peuvent également y accéder. – soulmerge

+0

D'accord, je l'ai fait - mais maintenant je ne peux pas utiliser '$ this-> message' - pas d'erreur, il n'affiche rien ... pourquoi? –

0

Vous devez définir l'accès à la protection. Privé signifie qu'il ne peut être accédé qu'à partir de sa propre classe et ne peut pas être hérité. Protected lui permet d'être inhérent, mais il n'est toujours pas accessible directement depuis l'extérieur de la classe.

0

Si vous consultez la documentation visibility, enterré dans un commentaire est:

// On peut redéclarer la méthode publique et protégée, mais pas privé

Vous devez faire protected faire ce que vous essayez de faire.

Soit dit en passant, il semble que vous mettez juste être le nom de la classe - vous pouvez simplement utiliser get_class():

<div class="<?php echo get_class($this); ?>class"> 
+0

sûr, mais si je changeais le nom de la classe (php) je devrais changer le nom de la classe (css), et aussi, si je veux utiliser plus d'informations dans le fichier de modèle d'exception, je l'ajouterais probablement De la même manière j'ai ajouté la propriété "type". –

0

Vous devez en effet changer le typeAccès à protected quand you'e builing classes d'héritage.

Un point supplémentaire cependant; ne pas utiliser return ""; mais il suffit d'utiliser return;

+0

votre point supplémentaire provoque une erreur fatale, j'ai déjà essayé - '__toString()' ** DOIT ** retourner une chaîne –

+0

Ah je suis désolé! J'ai regardé votre fonction __toString .. juste vu que vous retourniez 'rien'. Vous avez absolument raison! – Ben

+0

Il est très très très moche de laisser __toString() retourner une chaîne vide. Je ne peux vraiment pas voir n'importe quel usage pour de telles choses. Mais vous avez raison, __toString() doit renvoyer une chaîne. – tuergeist

32

juste un exemple comment accéder à la propriété privée

<?php 
class foo { 
    private $bar = 'secret'; 
} 
$obj = new foo; 


if (version_compare(PHP_VERSION, '5.3.0') >= 0) 
{ 

     $myClassReflection = new ReflectionClass(get_class($obj)); 
     $secret = $myClassReflection->getProperty('bar'); 
     $secret->setAccessible(true); 
     echo $secret->getValue($obj); 
} 
else 
{ 
    $propname="\0foo\0bar"; 
    $a = (array) $obj; 
    echo $a[$propname]; 
} 
+4

Vous, monsieur, êtes brillants. –

5

Voir ma réponse ici: https://stackoverflow.com/a/40441769/1889685


Au PHP 5.4, vous peut utiliser la classe Closure prédéfinie pour lier une méthode/propriété d'une classe à une fonction delta ayant accès même aux membres privés.

The Closure class

Par exemple, nous avons une classe avec une variable privée et nous voulons y avoir accès en dehors de la classe:

class Foo { 
    private $bar = "Foo::Bar"; 
} 

PHP 5.4+

$foo = new Foo; 
$getFooBarCallback = function() { 
    return $this->bar; 
}; 

$getFooBar = $getFooBarCallback->bindTo($foo, 'Foo'); 
echo $getFooBar(); // Prints Foo::Bar 

A partir de PHP 7, vous pouvez utiliser le nouveau Closure::call meth od, pour lier toute méthode/propriété d'un obect à une fonction de rappel, même pour les membres privés:

PHP 7+

$foo = new Foo; 
$getFooBar = function() { 
    return $this->bar; 
} 

echo $getFooBar->call($foo); // Prints Foo::Bar 
Questions connexes