Echo vs. Print

C’è molto mistero e disinformazione su questa area fondamentale del PHP. Ogni sviluppatore PHP impara come far apparire del testo su una pagina. Di solito è con l’aiuto di echo. Più tardi devono capire cosa c’è effettivamente dentro una variabile, e gli viene insegnato/scoperto o print_r() o var_dump().

Stasera ho partecipato ad un workshop, dove venivano insegnati alcuni aspetti di PHP a persone nuove del linguaggio. Questi tipi di workshop sono difficili da tenere, perché la gente farà domande che solo i nuovi farebbero, e spesso riguardano aree del linguaggio da tempo dimenticate o ignorate dagli sviluppatori PHP esperti.

Uno dei partecipanti ha chiesto quale fosse la differenza tra echo e print, e subito ho pensato abbastanza certo della loro funzione. Poi ho pensato alle sottili differenze tra tutte le funzioni di stampa variabili, e a come non sono mai spiegate in dettaglio. Cambiamo questo!

echo è un costrutto di linguaggio che sembra una funzione, ma non lo è. Secondo la documentazione, emette più parametri (stringhe), ma quando ci provo genera un errore di sintassi:

php > echo("foo", "bar", "baz");
PHP Parse error: syntax error, unexpected ',' in php shell code on line 1

Anche se le parentesi sono opzionali:

php > echo "foo"; echo("bar");
foobar

echo non restituisce un valore. Il suo unico compito è quello di emettere una stringa.

Sembra che avrei dovuto provare più stringhe senza le parentesi. Grazie a coloro che l’hanno fatto notare. ☺

print

A differenza di echo; la documentazione di print afferma correttamente che emette una singola stringa. Inoltre non è strettamente una funzione, ma bizzarramente restituisce sempre 1. Di conseguenza, accadono le seguenti cose:

php > print "foo"; print("bar"); print print print "baz";
foobarbaz11

Strano. Decisamente strano.

print_r

Seguendo questi costrutti praticamente simili, print_r inizia a sviluppare l’idea di emettere una variabile. L’idea dietro print_r è di emettere/restituire una rappresentazione leggibile per l’uomo di una singola variabile:

php > print_r("foo"); print_r(2); print_r(true);
foo21

Il secondo parametro (booleano) di print_r dice a PHP se restituire il valore o emetterlo. true significa restituire, false significa emettere. Il default è false.

php > echo print_r(, true);
Array
(
=> bar
)

print_r restituirà molte informazioni per oggetti profondamente annidati. Quando individua riferimenti ricorsivi, li omette e mostra *RECURSION*. Potreste anche aver notato che ci sono spazi bianchi che circondano parti dell’output, il che rende l’output più facile da leggere.

var_dump

Similmente, var_dump() restituisce una rappresentazione di una o più variabili. Come echo, la documentazione per var_dump() dice che gestirà variabili multiple. A differenza di echo questo sembra essere vero:

php > var_dump("foo", "bar");
string(3) "foo"
string(3) "bar"php > var_dump(new StdClass);
class stdClass#1 (0) {
}

var_dump() mostra anche dati annidati, ma l’installazione dell’estensione XDebug limiterà questo a tre livelli di profondità, e richiederà un cambiamento di configurazione per mostrare ancora di più.

Questa modifica alla configurazione di XDebug che dovrete fare è xdebug.var_display_max_depth=n.

var_dump() non mostra spazi bianchi extra, quindi questo rende difficile leggere l’output. Inoltre, l’estensione XDebug avvolgerà tutto in elementi HTML (per l’evidenziazione della sintassi), quindi leggere l’output di var_dump() è un incubo sulla linea di comando.

var_export

var_export() è simile a print_r(), in quanto può emettere direttamente o restituire una stringa. Tuttavia, l’output/return è una sintassi PHP valida:

php > var_export();
array (
'foo' => 'bar',
)

Non troverete spesso un buon uso per questo metodo, e quando lo farete probabilmente restituirete (piuttosto che output) la rappresentazione. Quando gli si passa un’istanza, si ottiene una rappresentazione piuttosto strana:

php > $instance = new Thing();
php > $instance->foo = "bar";
php > var_export($instance);
Thing::__set_state(array(
'foo' => 'bar',
))

Se questo codice fosse analizzato; il metodo __set_state() sarebbe chiamato sulla classe Thing. Ecco un esempio di ciò che si potrebbe fare allora:

class Thing
{
public $foo;
public static function __set_state($state)
{
$thing = new Thing();
$thing->foo = $state;
return $thing;
}
}

Si dovrebbe anche notare che le variabili risorsa non possono essere esportate:

php > var_export(fopen("http://google.com", "r"));
NULL

Questo è ottimo per risolvere un problema molto specifico; leggere, aggiornare e scrivere file di configurazione PHP:

return ;

Questo è da config.php

$config = file_get_contents("config.php");
$config = "world";
file_put_contents(
"config.php",
"return " . var_export($config, true) . ";"
);

Questo è da update.php

return array (
'foo' => 'bar',
'hello' => 'world',
);

Questo è da config.php

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.