Ha metodo statico in PHP hanno alcuna differenza con il metodo non statico?
Domanda
class t {
public function tt()
{
echo 1;
}
}
t::tt();
vedi? La funzione non statica può anche essere chiamato in classe level.So cosa c'è di diverso se posso aggiungere una parola chiave static
prima public
?
Soluzione
Se non fosse che, se si tenta di utilizzare $this
nel metodo, in questo modo:
class t {
protected $a = 10;
public function tt() {
echo $this->a;
echo 1;
}
}
t::tt();
Si otterrà un errore fatale quando si chiama il metodo non statico statico:
Fatal error: Using $this when not in object context in ...\temp.php on line 11
vale a dire. il vostro esempio è un po ' troppo semplice , e in realtà non corrispondono a un vero e proprio caso; -)
Si noti inoltre che il vostro esempio dovrebbe ottenere un avvertimento severo ( citando ):
metodi non statici Calling staticamente genera un allarme per il livello
E_STRICT
.
E lo fa in realtà (Almeno, con PHP 5.3) :
Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12
1
Quindi: non che il bene; -)
Eppure, chiamando staticamente un metodo non statico doesnt't assomiglia a nessun tipo di buona pratica (che è probabilmente il motivo per cui genera un avviso Strict) , come metodi statici non hanno lo stesso significato di quanto non quelli -static:. metodi statici non fare riferimento a qualsiasi oggetto, mentre i metodi non statici lavorano sulla istanza della classe ci sono invitato
Ancora una volta: con voi anche se il PHP permette di fare qualcosa di (forse per ragioni storiche - di compatibilità come con le vecchie versioni) , ma non significa che si dovrebbe fare
Altri suggerimenti
Poiché i metodi statici sono richiamabili senza un'istanza dell'oggetto creato, il $ pseudo-variabile non è disponibile all'interno del metodo dichiarato come statico.
Le proprietà statiche non si può accedere attraverso l'oggetto utilizzando l'operatore freccia -.>
Chiamare i metodi non statici genera staticamente un allarme per il livello E_STRICT.
Solo perché è possibile chiamare i metodi non statici staticamente non significa che si dovrebbe. E 'di cattivo gusto.
In generale, un metodo statico viene anche chiamato metodo di classe mentre un metodo non statico è anche chiamato metodo oggetto o metodo esempio .
La differenza tra un metodo di classe e un metodo oggetto è che i metodi di classe può solo proprietà della classe di accesso (proprietà statiche) mentre i metodi di oggetto sono utilizzati per accedere alle proprietà dell'oggetto (proprietà della stessa istanza di classe).
Metodi e proprietà statici vengono utilizzati per condividere dati comuni sopra o per tutte le istanze di quella classe specifica.
Si potrebbe, ad esempio, utilizzare una proprietà statica per tenere traccia del numero di istanze:
class A {
private static $counter = 0;
public function __construct() {
self::counter = self::counter + 1;
}
public function __destruct() {
self::counter = self::counter - 1;
}
public static function printCounter() {
echo "There are currently ".self::counter." instances of ".__CLASS__;
}
}
$a1 = new A();
$a2 = new A();
A::printCounter();
unset($a2);
A::printCounter();
Si noti che la proprietà statica contatore è privato in modo che possa essere raggiunto solo dalla classe stessa e le istanze di quella classe, ma non al di fuori.
Una differenza principale che non è stato indicato si riferisce a polimorfismo .
metodi non statici, quando ridichiarato in una classe derivata, sostituiscono il metodo della classe base, e permettono polimorfismo in base al tipo dell'istanza che sono chiamati. Questo non è il caso per i metodi statici .
PHP 5.3 ha introdotto il concetto di legare ritardo statico che può essere utilizzato per fare riferimento alla classe denominata in un contesto di ereditarietà statica.
Sì, la differenza fondamentale è che i metodi dichiarati static
non hanno accesso alla variabile oggetto al contesto, $this
.
Inoltre, l'invocazione di un metodo non statico quando non in contesto dell'oggetto attiverà un evento di errore E_STRICT
. Se abilitata, il comportamento predefinito dell'evento è quello di emettere un messaggio al log degli errori (o STDERR), ma permetterà al programma di continuare l'esecuzione .
Inoltre, ogni tentativo di riferimento $this
quando non è in un contesto oggetto attiveranno un evento E_ERROR
. Il comportamento di questo evento è quello di emettere un messaggio al log degli errori (o STDERR) e per uscire dal programma con lo stato 255.
Ad esempio:
<?php
error_reporting(-1);
//error_reporting(E_ALL);
class DualNature {
public static function fnStatic() {
if ( isset( $this ) ) {
// never ever gets here
$myValue = $this->_instanceValue;
} else {
// always gets here
$myValue = self::$_staticValue;
}
return $myValue;
}
public function fnInstance() {
if ( isset( $this ) ) {
// gets here on instance (->) reference only
$myValue = $this->_instanceValue;
} else {
// gets here in all other situations
$myValue = self::$_staticValue;
}
return $myValue;
}
public static function fnStaticDeath() {
return $this->_instanceValue;
}
private static $_staticValue = 'no access to $this';
private $_instanceValue = '$this is available';
}
$thing = new DualNature();
echo "==========\n";
printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic() );
echo "==========\n";
printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic() );
echo "==========\n";
printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic() );
echo "==========\n";
printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance() );
echo "==========\n";
printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance() );
echo "==========\n";
printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance() );
echo "==========\n";
printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath() );
echo "==========\n";
echo "I'M ALIVE!!!\n";
L'output di quanto sopra è:
==========
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45
DualNature::fnStatic(): "no access to $this"
==========
$thing::fnStatic(): "no access to $this"
==========
$thing->fnStatic(): "no access to $this"
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47
==========
DualNature::fnInstance(): "no access to $this"
==========
$thing::fnInstance(): "no access to $this"
==========
$thing->fnInstance(): "$this is available"
==========
PHP Fatal error: Using $this when not in object context in example.php on line 29
La modifica del livello di segnalazione degli errori per E_ALL
sopprimerà i messaggi di avviso di default E_STRICT
(l'evento sarà comunque propagata), ma il riferimento non valido per $this
sarà ancora causare un errore fatale e si esce dal programma.
Oltre la sintassi e funzionali differenze c'è anche una differenza di prestazioni che conta.
È possibile fare riferimento a questo più o meno dettagliata confronto di metodi statici e non statici in PHP .