Twee keer per maand bekijken we enkele van onze favoriete lezers uit de geschiedenis van Nettuts+.
Zelfs na jarenlang gebruik van PHP, komen we op functies en functies die we niet wisten. Sommige hiervan kunnen behoorlijk nuttig zijn, maar zijn nog te weinig gebruikt. Met dat in gedachten heb ik een lijst samengesteld van negen ongelooflijk nuttige PHP-functies en functies waarmee je bekend moet zijn.
Je weet misschien al dat PHP je toestaat om functies te definiëren met optionele argumenten. Maar er is ook een methode om een volledig arbitrair aantal functieargumenten toe te staan.
Ten eerste, hier is een voorbeeld met slechts optionele argumenten:
// functie met 2 optionele argumenten functie foo ($ arg1 = ", $ arg2 =") echo "arg1: $ arg1 \ n"; echo "arg2: $ arg2 \ n"; foo ('hallo', 'wereld'); / * prints: arg1: hello arg2: world * / foo (); / * prints: arg1: arg2: * /
Laten we nu kijken hoe we een functie kunnen bouwen die een willekeurig aantal argumenten accepteert. Deze keer gaan we gebruik maken van func_get_args ():
// ja, de argumentenlijst kan leeg zijn functie foo () // retourneert een array van alle doorgegeven argumenten $ args = func_get_args (); foreach ($ args als $ k => $ v) echo "arg". ($ k + 1). ": $ v \ n"; foo (); / * drukt niets * / foo ('hallo') af; / * prints arg1: hallo * / foo ('hallo', 'wereld', 'opnieuw'); / * prints arg1: hello arg2: world arg3: again * /
Veel PHP-functies hebben lange en beschrijvende namen. Het kan echter moeilijk zijn om te bepalen wat een functie met de naam glob () doet, tenzij u al bekend bent met die term van elders.
Zie het als een meer capabele versie van de functie scandir (). Het kan je laten zoeken naar bestanden met behulp van patronen.
// krijg alle php-bestanden $ files = glob ('*. php'); print_r ($ bestanden); / * uitvoer ziet eruit als: Array ([0] => phptest.php [1] => pi.php [2] => post_output.php [3] => test.php) * /
U kunt meerdere bestandstypen zoals dit ophalen:
// krijg alle php-bestanden EN txt-bestanden $ files = glob ('*. php, txt', GLOB_BRACE); print_r ($ bestanden); / * uitvoer ziet eruit als: Array ([0] => phptest.php [1] => pi.php [2] => post_output.php [3] => test.php [4] => log.txt [5 ] => test.txt) * /
Merk op dat de bestanden daadwerkelijk kunnen worden geretourneerd met een pad, afhankelijk van uw vraag:
$ files = glob ('? /images/a*.jpg'); print_r ($ bestanden); / * uitvoer ziet eruit als: Array ([0] =>? /images/apple.jpg [1] =>? /images/art.jpg) * /
Als u het volledige pad naar elk bestand wilt krijgen, kunt u gewoon de functie realpath () op de geretourneerde waarden aanroepen:
$ files = glob ('? /images/a*.jpg'); // past de functie toe op elk arrayelement $ files = array_map ('realpath', $ files); print_r ($ bestanden); / * uitvoer ziet eruit als: Array ([0] => C: \ wamp \ www \ images \ apple.jpg [1] => C: \ wamp \ www \ images \ art.jpg) * /
Door het geheugengebruik van uw scripts te observeren, kunt u uw code mogelijk beter optimaliseren.
PHP heeft een garbage collector en een behoorlijk complexe geheugenbeheerder. De hoeveelheid geheugen die door uw script wordt gebruikt. kan tijdens het uitvoeren van een script op en neer gaan. Om het huidige geheugengebruik te krijgen, kunnen we de memory_get_usage () -functie gebruiken en om de hoogste hoeveelheid geheugen te krijgen die op een bepaald punt wordt gebruikt, kunnen we de memory_get_peak_usage () -functie gebruiken.
echo "Initial:" .memory_get_usage (). "bytes \ n"; / * prints Oorspronkelijke: 361400 bytes * / // laten we wat geheugen gebruiken voor ($ i = 0; $ i < 100000; $i++) $array []= md5($i); // let's remove half of the array for ($i = 0; $i < 100000; $i++) unset($array[$i]); echo "Final: ".memory_get_usage()." bytes \n"; /* prints Final: 885912 bytes */ echo "Peak: ".memory_get_peak_usage()." bytes \n"; /* prints Peak: 13687072 bytes */
Hiervoor gaan we de functie getrusage () gebruiken. Houd er rekening mee dat dit niet beschikbaar is op Windows-platforms.
print_r (getrusage ()); / * prints Array ([ru_oublock] => 0 [ru_inblock] => 0 [ru_msgsnd] => 2 [ru_msgrcv] => 3 [ru_maxrss] => 12692 [ru_ixrss] => 764 [ru_idrss] => 3864 [ru_minflt] => 94 [ru_majflt] => 0 [ru_nsignals] => 1 [ru_nvcsw] => 67 [ru_nivcsw] => 4 [ru_nswap] => 0 [ru_utime.tv_usec] => 0 [ru_utime.tv_sec] => 0 [ ru_stime.tv_usec] => 6269 [ru_stime.tv_sec] => 0) * /
Dat ziet er misschien een beetje cryptisch uit, tenzij je al een systeembeheer-achtergrond hebt. Hier is de uitleg van elke waarde (je hoeft deze niet te onthouden):
Om te zien hoeveel CPU-kracht het script heeft verbruikt, moeten we kijken naar de waarden voor 'gebruikerstijd' en 'systeemtijd'. De delen van seconden en microseconden worden standaard apart aangeboden. U kunt de waarde van microseconden delen met 1 miljoen en deze aan de waarde voor seconden toevoegen om de totale seconden als een decimaal getal te krijgen.
Laten we een voorbeeld zien:
// slaap gedurende 3 seconden (niet-bezette) slaap (3); $ data = getrusage (); echo "Gebruikstijd:". ($ data ['ru_utime.tv_sec'] + $ data ['ru_utime.tv_usec'] / 1000000); echo "Systeemtijd:". ($ data ['ru_stime.tv_sec'] + $ data ['ru_stime.tv_usec'] / 1000000); / * prints Gebruikstijd: 0.011552 Systeemtijd: 0 * /
Hoewel het script ongeveer 3 seconden duurde om te draaien, was het CPU-gebruik erg laag. Omdat tijdens de slaapbewerking het script feitelijk geen CPU-bronnen verbruikt. Er zijn veel andere taken die realtime kunnen duren, maar mogelijk geen CPU-tijd gebruiken, zoals wachten op schijfbewerkingen. Dus zoals je ziet, zijn het CPU-gebruik en de werkelijke lengte van de runtime niet altijd hetzelfde.
Hier is nog een voorbeeld:
// loop 10 miljoen keer (bezet) voor ($ i = 0; $ i<10000000;$i++) $data = getrusage(); echo "User time: ". ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000); echo "System time: ". ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000); /* prints User time: 1.424592 System time: 0.004204 */
Dat kostte ongeveer 1,4 seconden CPU-tijd, bijna allemaal gebruiksduur, omdat er geen systeemaanroepen waren.
Systeemtijd is de hoeveelheid tijd die de CPU besteedt aan het uitvoeren van systeemaanroepen voor de kernel namens het programma. Hier is een voorbeeld van:
$ start = microtime (true); // blijf gedurende ongeveer 3 seconden microtime aanroepen (microtime (true) - $ start < 3) $data = getrusage(); echo "User time: ". ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000); echo "System time: ". ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000); /* prints User time: 1.088171 System time: 1.675315 */
Nu hebben we behoorlijk wat systeemtijdgebruik. Dit komt omdat het script de functie microtime () vele malen oproept, waardoor een aanvraag via het besturingssysteem wordt uitgevoerd om de tijd op te halen.
Het kan ook zijn dat de cijfers niet helemaal oplopen tot 3 seconden. Dit komt omdat er waarschijnlijk ook andere processen op de server waren en het script gedurende de gehele duur van de 3 seconden geen 100% CPU gebruikte.
PHP biedt nuttige magische constanten voor het ophalen van het huidige regelnummer (__LIJN__
), bestandspad (__HET DOSSIER__
), mappad (__DIR__
), functienaam (__FUNCTIE__
), naam van de klasse (__KLASSE__
), methode naam (__METHOD__) en naamruimte (__NAMESPACE__
).
We zullen dit niet allemaal in dit artikel behandelen, maar ik zal u enkele gebruiksgevallen laten zien.
Wanneer u andere scripts opneemt, is het een goed idee om de scripts te gebruiken
__HET DOSSIER__
constant (of ook__DIR__
, vanaf PHP 5.3):
// dit is relatief ten opzichte van het pad van het geladen script // het kan problemen veroorzaken bij het uitvoeren van scripts uit verschillende mappen require_once ('config / database.php'); // dit is altijd relatief aan het pad van dit bestand // maakt niet uit waar het is opgenomen van require_once (dirname (__ FILE__). '/config/database.php');
Gebruik makend van __LIJN__
maakt debugging eenvoudiger. U kunt de regelnummers opzoeken:
// wat code //? my_debug ("some debug message", __LINE__); / * print Regel 4: een foutopsporingsbericht * / // wat meer code //? my_debug ("een ander debugbericht", __LINE__); / * print Regel 11: een ander debugbericht * / function my_debug ($ msg, $ line) echo "Line $ line: $ msg \ n";
Er kunnen situaties zijn waarin u een unieke reeks moet genereren. Ik heb veel mensen de md5 ()
functie hiervoor, ook al is het niet precies voor dit doel bedoeld:
// genereer unieke string echo md5 (time (). mt_rand (1,1000000));
Er is eigenlijk een PHP-functie genaamd uniqid () die hiervoor moet worden gebruikt.
// genereer unieke string echo uniqid (); / * prints 4bd67c947233e * / // genereren een andere unieke string echo uniqid (); / * prints 4bd67c9472340 * /
Je merkt misschien dat hoewel de snaren uniek zijn, ze voor de eerste paar personages hetzelfde lijken. Dit komt omdat de gegenereerde string gerelateerd is aan de servertijd. Dit heeft eigenlijk een leuk neveneffect, omdat elke nieuw gegenereerde ID later in alfabetische volgorde komt, zodat ze kunnen worden gesorteerd.
Om de kans op een duplicaat te verkleinen, kunt u een prefix of de tweede parameter voor het verhogen van de entropie opgeven:
// met prefix echo uniqid ('foo_'); / * prints foo_4bd67d6cd8b8f * / // met meer entropy echo uniqid (", true); / * prints 4bd67d6cd8b926.12135106 * / // beide echo uniqid ('bar _', true); / * prints bar_4bd67da367b650.43684647 * /
Deze functie genereert kortere reeksen dan md5 ()
, wat je ook wat ruimte zal besparen.
Heb je ooit een complexe variabele in een database of een tekstbestand moeten opslaan? U hoeft geen fancy oplossing te bedenken om uw arrays of objecten om te zetten in opgemaakte strings, want PHP heeft al functies voor dit doel.
Er zijn twee populaire methoden om variabelen te serialiseren. Hier is een voorbeeld dat de serialize () en unserialize () gebruikt:
// een complexe array $ myvar = array ('hallo', 42, array (1, 'two'), 'apple'); // convert to a string $ string = serialize ($ myvar); echo $ string; / * drukt een: 4: i: 0; s: 5: "hallo"; i: 1; i: 42; i: 2; a: 2: i: 0; i: 1; i: 1; s af : 3: "two"; i: 3; s: 5: "apple"; * / // u kunt de originele variabele reproduceren $ newvar = unserialize ($ string); print_r ($ newvar); / * prints Array ([0] => hallo [1] => 42 [2] => Array ([0] => 1 [1] => twee) [3] => appel) * /
Dit was de native PHP serialisatiemethode. Omdat JSON de laatste jaren echter zo populair is geworden, hebben ze besloten om ondersteuning toe te voegen in PHP 5.2. Nu kunt u de gebruiken json_encode ()
en json_decode ()
functies ook:
// een complexe array $ myvar = array ('hallo', 42, array (1, 'two'), 'apple'); // convert to a string $ string = json_encode ($ myvar); echo $ string; / * prints ["hallo", 42, [1, "twee"], "apple"] * / // je kunt de originele variabele $ newvar = json_decode ($ string) reproduceren; print_r ($ newvar); / * prints Array ([0] => hallo [1] => 42 [2] => Array ([0] => 1 [1] => twee) [3] => appel) * /
Het is compacter en het beste van alles, compatibel met javascript en vele andere talen. Voor complexe objecten kan echter wat informatie verloren gaan.
Als het over compressie gaat, denken we meestal aan bestanden, zoals ZIP-archieven. Het is mogelijk om lange strings in PHP te comprimeren zonder archiefbestanden te betrekken.
In het volgende voorbeeld gaan we de functies gzcompress () en gzuncompress () gebruiken:
$ string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ut elit id mi ulité adipiscing. , consectetur adipisciserende elit Aliquam pretium ullamcorper urna quis iaculis Etiam ac massa sed turpis tempor luctus Curabitur sed nibh eu elit mollis congue Praesent ipsum diam, consectetur vitae ornare a, aliquam a nunc. non mi metus, op lacinia augue. Sed magna nisi, ornare in mollis in, mollis sed nunc. Etiam at justo in leo congue mollis. Nullam in neque eget metus hendrerit scelerisque eu non enim. Ut malesuada lacus eu nulla bibendum id euismod urna sodales . "; $ gecomprimeerd = gzcompress ($ string); echo "Oorspronkelijke grootte:". strlen ($ string) "\ n". / * prints Oorspronkelijke grootte: 800 * / echo "Gecomprimeerde grootte:". strlen ($ gecomprimeerd) "\ n". / * prints Gecomprimeerde grootte: 418 * / // krijgt het terug $ original = gzuncompress ($ gecomprimeerd);
We konden bijna 50% verkleinen. Ook de functies gzencode () en gzdecode () krijgen vergelijkbare resultaten door een ander compressie-algoritme te gebruiken.
Er is een functie genaamd register_shutdown_function (), waarmee je een code kunt uitvoeren vlak voordat het script klaar is.
Stel u voor dat u aan het einde van uw scriptuitvoering enkele benchmarkstatistieken wilt vastleggen, zoals hoe lang het duurde om te worden uitgevoerd:
// capture the start time $ start_time = microtime (true); // doe wat dingen //? // laat zien hoe lang het script echo nam "execution took:". (microtime (true) - $ start_time). "seconden.";
In eerste instantie lijkt dit misschien triviaal. U voegt de code gewoon helemaal onderaan het script toe en deze wordt uitgevoerd voordat deze is voltooid. Als u echter de functie exit () gebruikt, wordt die code nooit uitgevoerd. Als er zich een fatale fout voordoet of als het script door de gebruiker wordt beëindigd (door op de knop Stoppen in de browser te drukken), kan het opnieuw worden uitgevoerd.
Wanneer u register_shutdown_function () gebruikt, wordt uw code uitgevoerd, ongeacht waarom het script niet meer wordt uitgevoerd:
$ start_time = microtime (true); register_shutdown_function (my_shutdown); // doe wat dingen //? function my_shutdown () global $ start_time; echo "uitvoering duurde:". (microtime (true) - $ start_time). "seconden.";
Kent u andere PHP-functies die niet algemeen bekend zijn, maar wel heel nuttig kunnen zijn? Gelieve te delen met ons in de commentaren. En bedankt voor het lezen!