2009-11-19 16 views
10

ho derivato una classe da Exception, in fondo in questo modo:accesso variabile privata dalla funzione membro in PHP

class MyException extends Exception { 

    private $_type; 

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

    public function __toString() { 

     include "sometemplate.php"; 
     return ""; 

    } 

} 

Poi, ho derivato da MyException in questo modo:

class SpecialException extends MyException { 

    private $_type = "superspecial"; 

} 

Se throw new SpecialException("bla") da una funzione, rilevala e vai a echo $e, quindi la funzione __toString dovrebbe caricare un modello, visualizzarlo e quindi non restituire effettivamente alcunché all'eco.

Questo è fondamentalmente ciò che è nel file di modello

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

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

</div> 

nella mia mente, questo dovrebbe sicuramente lavorare. Tuttavia, ottengo il seguente errore quando viene generata un'eccezione e cerco di visualizzarlo:

Fatal error: Impossibile accedere proprietà privata SpecialException :: $ _ tipo in C: \ percorso \ to \ eccezioni. php on line

qualcuno può spiegare perché sto infrangendo le regole qui? Sto facendo qualcosa di orribilmente spiritoso con questo codice? C'è un modo molto più idiomatico per gestire questa situazione? Il punto della variabile $_type è (come mostrato) che desidero utilizzare una classe div diversa a seconda del tipo di eccezione rilevata.

+0

Come ho scritto laggiù: E 'molto molto molto brutto per lasciare __toString() restituisce una stringa vuota. Non riesco davvero a vedere QUALSIASI caso per queste cose. – tuergeist

+0

Il ritorno vuoto di __toString() per un'eccezione è ancora più dubbio. – tuergeist

risposta

32

Nome variabile protetta:

* 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 direttamente al punto – Andrew

+1

Nota: in PHP 'protected' significa che anche i tuoi genitori possono accedervi. – soulmerge

+0

ok, l'ho fatto - ma ora non posso usare '$ this-> message' - nessun errore, non mostra nulla ... perché? –

0

È necessario impostare l'accesso ai protetti. Privato significa che è possibile accedervi solo dalla propria classe e non può essere ereditato. Protetto consente di essere ereditato ma non è ancora possibile accedervi direttamente dall'esterno della classe.

0

Se si controlla la documentazione visibility, sepolto in un commento è:

// Possiamo ridichiarare il metodo pubblico e protetto, ma non privato

si dovrebbe fare protected fare cosa stai cercando di fare.

Per inciso, sembra che si sta appena impostando che sia il nome della classe - si potrebbe utilizzare get_class():

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

sicuro, ma poi se ho cambiato il nome della classe (php) dovrei cambiare il nome della classe (css), e anche, se voglio usare più informazioni nel file del modello di eccezione, probabilmente lo aggiungerei allo stesso modo ho aggiunto la proprietà "type". –

0

Si dovrebbe davvero cambiare l'accessmodifier a protected quando you'e builing classi di successione.

Un punto in più però; non utilizzare return "";, ma basta usare return;

+0

il tuo punto extra causa un errore fatale, l'ho già provato - '__toString()' ** DEVE ** restituire una stringa –

+0

Ah mi dispiace! Ho esaminato la tua funzione __toString .. ho appena visto che stavi restituendo "niente". Hai assolutamente ragione! – Ben

+0

È molto molto brutto lasciare che __toString() restituisca una stringa vuota. Non riesco davvero a vedere QUALSIASI caso per queste cose. Ma hai ragione, __toString() deve restituire una stringa. – tuergeist

32

solo un esempio di come accedere alla proprietà privata

<?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

Lei, signore, è brillante. –

5

Vedere la mia risposta qui: https://stackoverflow.com/a/40441769/1889685


Dal PHP 5.4, è possibile utilizzare la classe predefinita Closure per associare un metodo/proprietà di una classe a funzioni di delta che ha accesso anche a membri privati.

The Closure class

Per esempio abbiamo una classe con una variabile privata e vogliamo accedere al di fuori della 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 partire da PHP 7, è possibile utilizzare la nuova metrica Closure::call od, di legare qualsiasi metodo/proprietà di un obect a una funzione di callback, anche per i soci privati:

PHP 7+

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

echo $getFooBar->call($foo); // Prints Foo::Bar 
Problemi correlati