phphacker er en side med tips og tricks, vedligeholdt af Jonathan Holst
Genererer et (relativt) tilfældigt kodeord. Tager et valgfrit parameter som specificerer længden. Hvis ingen længde er defineret, vil kodeordet blive på otte tegn. Kodeordet genereres som standard ud fra store og små latinske bogstaver og tal, inden for ASCII-rammen. Variablen $chr
kan ændres, hvis dette ikke er optimalt.
function genPass($len = 8) {
$str = '';
$chr = 'abcdefghijklmnopqrstuvwxyz'.
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
'0123456789';
for($i=0;$i<$len;$i++) {
$str .= $chr[(rand(0, (strlen($chr)-1)))];
}
return $str;
}
Jeg er meget stor tilhænger af læsbare URL‘er, og meget inspireret af hvordan Wordpress håndterer det, skrev jeg denne funktion. Den udfører nogle få simple kommandoer:
array
kan udbygges, hvis man føler at der mangler nogle tegn.function sanitize($str) {
$str = strtolower($str);
$str = strtr($str, array('æ' => 'ae', 'ä' => 'ae', 'å' => 'aa',
'ø' => 'oe', 'ö' => 'oe', 'ü' => 'u'));
$str = preg_replace('/[^a-z0-9 ]*/', '', $str);
$str = str_replace(' ', '-', $str);
return $str;
}
En funktion til at udregne alderen på noget. Den tager tre parametre, som repræsenterer året, måneden og dagen.
function calcAge($year, $month, $day) {
$dif = date('Y') - $year;
if(($month > date('n')) || ($month == date('n') && $day > date('j'))) {
$dif--;
}
return $dif;
}
En ofte udført handling er at finde ud af, hvorvidt en given streng findes i en anden.
I mange sprog ville man gøre brug af regulære udtryk til at finde ud af dette, men PHP har nogle streng-funktioner, som er en smule hurtigere (og som man generelt betragter som best practice). Mange bruger strstr()
til formålet, men der er faktisk et hurtigere alternativ: strpos()
.
strpos()
har dog en lille tvist, som man skal være opmærksom på når man bruger den: Hvis den streng man søger efter befinder sig i starten af den streng man søger i, vil PHP returnere 0, fordi det er derfra indekset starter. Da 0 bliver betragtet som den boolske værdi false
, skal man lave et typetjek:
if(strpos($haystack, $needle) !== false) {
// Udfør kode hvis nålen er i høstakken
}
Den dobbelte brug af = laver et sådant typetjek. Den kan i øvrigt også bruges til at tjekke normalt — her bruges i stedet ===
.
Når man udvikler med databaser i PHP, hvor MySQL er det generelt foretrukne valg, vil man nogle gange løbe ind i en fejl ala denne:
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /var/www/index.php on line 2
Denne kryptiske fejl afslører ikke hvad der er galt, men det kan man godt finde ud af. Man vil oftest have en mysql_query
på linjerne inden, og det er her fejlen ligger. Løsningen er at tilføje brugen af mysql_error
, en funktion der afslører eventuelle fejl i SQL-forespørgslen, så man kommer frem til noget der ligner det følgende:
mysql_query($sql) or die(mysql_error());
Så får man en brugbar fejlbeskrivelse. Det er dog en god idé at fjerne disse så snart man har lokaliseret fejlen, ellers kan man potentielt afsløre sikkerhedskompromitterende informationer.
Når kode vokser over nogle få linjer vil man som regel møde en eller anden form for kontrolstruktur. Dette være sig en if
, switch
, function
, for
, while
eller lignende.
For at opnå læsbar kode (ja, det er faktisk vigtigt), bør man derfor brug indryk. Jeg har en tommelfingerregel der hedder, at hver {
efterfølges af et linjeskift og et indryk.
Sammenlign disse to stykker kode:
<?php
$something = true;
$somethingElse = false;
if($something == true) {
print 'a';
switch($somethingElse) {
case true:
print 'b';
break;
case false:
print 'c';
break;
}
}
<?php
$something = true;
$somethingElse = false;
if($something == true) {
print 'a';
switch($somethingElse) {
case true:
print 'b';
break;
case false:
print 'c';
break;
}
}
?>
(Bemærk at jeg bruger case
og break
som en slags tuborgklammer. Dette er mit personlige valg, fordi jeg synes der er en logisk sammenhæng.)
Hvilken er mest overskuelig? Brug indryk.
PHP’s konfigurationsfil, php.ini, tillader at man lader PHP parse kode indenfor <?
som tilføjelse til den normale <?php
. Dette er dumt at benytte sig af, af to årsager:
<?xml
-deklaration i toppen af sit dokument, får man en PHP-parse error, fordi parseren ikke kan håndtere XML-deklarationen.Undgå short tags. De sparer dig for nogle tegn, men giver dig en masse besvær.
PHP tilbyder tre forskellige muligheder for kommentering af kode:
//
fra C#
fra Perl/* */
fra CGør brug af dem. Ikke al kode er så krystalklar som den oprindelige udvikler måske anser det for. Lad være med at tage chancen.
En tommelfingerregel er i øvrigt at man skal skrive hvorfor fremfor hvad man gør.
PHP har en ternary (trefoldig) operatør. Dette giver mulighed for at forsøge et udtryk, og agere hvis udtrykket er sandt og hvis det er falsk.
I praksis kan dette lette tilskrivelsen af en værdi, hvis man har to mulige værdier:
<?php
$a = true;
$b = ($a == true) ? 'sand' : 'falsk';
?>
Reelt kan man godt lave nestede ternaries, men for at lette læsbarheden bør noget som det følgende undgåes:
<?php
$a = true;
$b = false;
$c = ($a == true) ? ($b == true) ? 1 : 2 : 3;
?>
($c
ville indeholde 2 i ovenstående eksempel, men den er ikke helt nem at udlede.)
Der er flere forskellige metoder til at undersøge hvorvidt der er noget indhold i en streng i PHP. isset
og empty
er begge ofte brugte metoder til dette, men de har begge deres mangler:
isset
undersøger ikke om variablen indeholder noget, blot om den er sat. (Således vil $var = ''; return isset($var);
returnere true, fordi variablen er sat.)empty
undersøger om der er noget indhold i variablen, men virker af uransagelige årsager kun på variable — dette er uholdbart, for hvis man eksempelvis på et senere tidspunkt vælger at variablen skal køres gennem en funktion, vil empty
gøre vrøvl.En bedre metode, der virker både på variable og almindelige strenge, er følgende snippet:
strlen(trim($var)) > 0
Denne vil undersøge på længden, og hvis denne er over nul vil man antage at der er indhold. Kan eventuelt krydres med også at erstatte newlines mv. med ingenting, for at få den mest optimale definition af “ingenting”.
PHP’s strtotime() funktion er smart at bruge, især til relative datoer. Den tillader stor frihed, så man eksempelvis kan skrive ting som:
date('Y-m', strtotime('+1 month'));
Der er dog en hage ved dette: den er ikke videre intelligent vedrørende disse; således vil man, sidste dag i en måned med 31 dage, få den samme måned, fordi måneden før ikke har 31 dage. (Dette gælder naturligvis ikke august og juli.)
Hvis man, som i eksemplet, blot skal bruge året og måneden, kan man skrive udtrykket lidt om:
date("Y-m", strtotime("+1 month", mktime(0, 0, 0, date('n'), 28, date('Y'))));
28 er naturligvis valgt, fordi det er det laveste antal dage i en måned. Et hvilket som helst tal under det kan dog bruges med samme resultat.