Tästä PHP:n perustavanlaatuisesta osa-alueesta on paljon mystiikkaa ja väärää tietoa. Jokainen PHP-kehittäjä oppii, miten teksti saadaan näkymään sivulla. Yleensä se tapahtuu echon avulla. Myöhemmin heidän on selvitettävä, mitä muuttujan sisällä oikeastaan on, ja heille opetetaan/löydetään joko print_r() tai var_dump().
Tänä iltana osallistuin työpajaan, jossa opetettiin joitakin PHP:n osa-alueita ihmisille, joille kieli on uusi. Tällaisia työpajoja on vaikea pitää, koska ihmiset kysyvät kysymyksiä, joita vain uudet ihmiset kysyisivät, ja usein ne koskevat kielen osa-alueita, jotka kokeneet PHP-kehittäjät ovat jo kauan sitten unohtaneet tai jättäneet huomiotta.
Yksi osallistujista kysyi, mitä eroa on echo:lla ja print:llä, ja heti ajattelin, että melko varmaa niiden funktio on. Sitten ajattelin kaikkien muuttujien tulostusfunktioiden välisiä hienovaraisia eroja ja sitä, miten niitä ei koskaan selitetä yksityiskohtaisesti. Muutetaan se!
echo on kielen konstruktio, joka näyttää funktiolta, mutta ei ole sitä. Dokumentaation mukaan; se tulostaa useita (merkkijono)parametreja, mutta kun yritän tätä, se tuottaa syntaksivirheen:
php > echo("foo", "bar", "baz");
PHP Parse error: syntax error, unexpected ',' in php shell code on line 1
Oli miten oli, sulut ovat valinnaisia:
php > echo "foo"; echo("bar");
foobar
echo ei palauta arvoa. Sen ainoa tehtävä on tulostaa merkkijono.
Tuntuu, että minun olisi pitänyt kokeilla useita merkkijonoja ilman sulkuja. Kiitos niille, jotka ovat huomauttaneet tästä. ☺
Toisin kuin echo; printin dokumentaatiossa sanotaan oikein, että se tulostaa yhden merkkijonon. Se ei myöskään ole varsinaisesti funktio, mutta outoa kyllä, se palauttaa aina 1. Tämän seurauksena tapahtuu seuraavia asioita:
php > print "foo"; print("bar"); print print print "baz";
foobarbaz11
Kummallista. Ehdottomasti outoa.
print_r
Näiden käytännössä samankaltaisten konstruktioiden jälkeen print_r alkaa kehittää ajatusta muuttujan tulostamisesta. Print_r:n ideana on tulostaa/palauttaa ihmiselle luettava esitys yhdestä muuttujasta:
php > print_r("foo"); print_r(2); print_r(true);
foo21
Print_r:n toinen (boolean) parametri kertoo PHP:lle, palautetaanko arvo vai tulostetaanko se. true tarkoittaa palauttamista, false tulostamista. Oletusarvo on false.
php > echo print_r(, true);
Array
(
=> bar
)
print_r palauttaa paljon tietoa syvälle sisennetyistä objekteista. Kun se havaitsee rekursiivisia viittauksia, se jättää ne pois ja näyttää *RECURSION*. Olet ehkä myös huomannut, että tulosteen osien ympärillä on valkotilaa, mikä tekee tulosteesta helpommin luettavan.
var_dump
Samoin var_dump() tulostaa esityksen yhdestä tai useammasta muuttujasta. Kuten echo, myös var_dump():n dokumentaation mukaan se käsittelee useita muuttujia. Toisin kuin echo tämä näyttää pitävän paikkansa:
php > var_dump("foo", "bar");
string(3) "foo"
string(3) "bar"php > var_dump(new StdClass);
class stdClass#1 (0) {
}
var_dump() näyttää myös sisäkkäistä dataa, mutta XDebug-laajennuksen asentaminen rajoittaa tämän kolmeen tasoon syvälle, ja vaatii konfiguraatiomuutoksen näyttääksesi taas enemmän.
Tämä XDebug-konfiguraatiomuutos, joka sinun täytyy tehdä, on xdebug.var_display_max_depth=n.
var_dump() ei tulosta ylimääräisiä välilyöntejä, joten tämä hankaloittaa tuotoksen lukemista. Lisäksi XDebug-laajennus kietoo kaiken HTML-elementteihin (syntaksin korostusta varten), joten var_dump()-tulosteen lukeminen on painajainen komentorivillä.
var_export
var_export() on samanlainen kuin print_r()-funktio sikäli, että se voi antaa tulosteen suoraan tai palauttaa merkkijonon. Tulostus/palautus on kuitenkin kelvollinen PHP-syntaksi:
php > var_export();
array (
'foo' => 'bar',
)
Tälle metodille ei usein löydy hyvää käyttöä, ja kun löydät, palautat luultavasti (tulostuksen sijaan) esityksen. Kun annat sille instanssin, saat varsin oudon esityksen:
php > $instance = new Thing();
php > $instance->foo = "bar";
php > var_export($instance);
Thing::__set_state(array(
'foo' => 'bar',
))
Jos tuo koodi jäsennettäisiin; __set_state()-metodia kutsuttaisiin Thing-luokalle. Tässä on esimerkki siitä, mitä voisit silloin tehdä:
class Thing
{
public $foo;
public static function __set_state($state)
{
$thing = new Thing();
$thing->foo = $state;
return $thing;
}
}
Tulee myös huomioida, että resurssimuuttujia ei voi viedä:
php > var_export(fopen("http://google.com", "r"));
NULL
Tämä on loistava ratkaisu hyvin spesifiseen ongelmaan; PHP:n konfiguraatiotiedostojen lukemiseen, päivittämiseen ja kirjoittamiseen:
return ;
Tämä on peräisin config.php
$config = file_get_contents("config.php");
$config = "world";
file_put_contents(
"config.php",
"return " . var_export($config, true) . ";"
);
Tämä on tiedostosta update.php
return array (
'foo' => 'bar',
'hello' => 'world',
);
Tämä on tiedostosta config.php
.