Der er meget mystisk og misvisende information om dette grundlæggende område af PHP. Enhver PHP-udvikler lærer, hvordan man får tekst til at blive vist på en side. Som regel er det ved hjælp af echo. Senere skal de finde ud af, hvad der egentlig er inde i en variabel, og de lærer/opdager enten print_r() eller var_dump().
I aften deltog jeg i en workshop, hvor der blev undervist i nogle aspekter af PHP for folk, der er nye i sproget. Den slags workshops er svære at give, fordi folk vil stille spørgsmål, som kun nye folk ville stille, og ofte handler de om områder af sproget, som for længst er glemt eller ignoreret af erfarne PHP-udviklere.
En af deltagerne spurgte, hvad forskellen var på echo og print, og straks tænkte jeg ganske bestemt på deres funktion. Så tænkte jeg på de subtile forskelle mellem alle de variable udskriftsfunktioner, og hvordan de aldrig rigtig bliver forklaret i detaljer. Lad os ændre det!
echo er en sprogkonstruktion, der ligner en funktion, men ikke er det. Ifølge dokumentationen; den udsender flere (streng-)parametre, men når jeg forsøger dette, genererer den en syntaksfejl:
php > echo("foo", "bar", "baz");
PHP Parse error: syntax error, unexpected ',' in php shell code on line 1
Hvad det end måtte være, så er parenteserne valgfrie:
php > echo "foo"; echo("bar");
foobar
echo returnerer ikke en værdi. Den har kun til opgave at udstede en streng.
Det ser ud til, at jeg skulle have prøvet flere strenge uden parenteserne. Tak til dem, der har gjort opmærksom på dette. ☺
I modsætning til echo; dokumentationen for print angiver korrekt, at den vil udgive en enkelt streng. Det er heller ikke strengt taget en funktion, men vil bizar nok altid returnere 1. Som følge heraf sker der følgende ting:
php > print "foo"; print("bar"); print print print "baz";
foobarbaz11
Samtidig. Absolut mærkeligt.
print_r
I forlængelse af disse praktisk talt ens konstruktioner begynder print_r at udvikle ideen om at udgive en variabel. Ideen bag print_r er at output/returnerer en menneskeligt læsbar repræsentation af en enkelt variabel:
php > print_r("foo"); print_r(2); print_r(true);
foo21
Den anden (boolske) parameter i print_r fortæller PHP, om værdien skal returneres eller outputes. true betyder return, false betyder output. Standardværdien er false.
php > echo print_r(, true);
Array
(
=> bar
)
print_r returnerer en masse oplysninger for dybt indlejrede objekter. Når den opdager rekursive referencer, vil den udelade dem og vise *RECURSION*. Du har måske også bemærket, at der er whitespace omkring dele af outputtet, hvilket gør outputtet lettere at læse.
var_dump
Sådan udsender var_dump() en repræsentation af en eller flere variabler. Ligesom echo står der i dokumentationen for var_dump(), at den kan håndtere flere variabler. I modsætning til echo ser det ud til at være sandt:
php > var_dump("foo", "bar");
string(3) "foo"
string(3) "bar"php > var_dump(new StdClass);
class stdClass#1 (0) {
}
var_dump() viser også indlejrede data, men installation af XDebug-udvidelsen vil begrænse dette til tre niveauer dybt og kræve en konfigurationsændring for at vise mere igen.
Denne XDebug-konfigurationsændring, du skal foretage, er xdebug.var_display_max_depth=n.
var_dump() udsender ikke ekstra whitespace, så dette gør det svært at læse output. Derudover vil XDebug-udvidelsen pakke alt ind i HTML-elementer (til syntaksmarkering), så det er et mareridt at læse var_dump()-output på kommandolinjen.
var_export
var_export() svarer til print_r(), idet den kan output direkte eller returnere en streng. Output/return er dog gyldig PHP-syntaks:
php > var_export();
array (
'foo' => 'bar',
)
Du vil ikke ofte finde en god anvendelse for denne metode, og når du gør det, vil du sandsynligvis returnere (i stedet for at output) repræsentationen. Når du overdrager en instans til den, får du en ret mærkelig repræsentation:
php > $instance = new Thing();
php > $instance->foo = "bar";
php > var_export($instance);
Thing::__set_state(array(
'foo' => 'bar',
))
Hvis denne kode blev analyseret; __set_state()-metoden ville blive kaldt på Thing-klassen. Her er et eksempel på, hvad du så kunne gøre:
class Thing
{
public $foo;
public static function __set_state($state)
{
$thing = new Thing();
$thing->foo = $state;
return $thing;
}
}
Du bør også bemærke, at ressourcevariabler ikke kan eksporteres:
php > var_export(fopen("http://google.com", "r"));
NULL
Dette er fantastisk til at løse et meget specifikt problem; at læse, opdatere og skrive PHP-konfigurationsfiler:
return ;
Det er fra config.php
$config = file_get_contents("config.php");
$config = "world";
file_put_contents(
"config.php",
"return " . var_export($config, true) . ";"
);
Dette er fra update.php
Dette er fra config.php