13
Vakker bruk av strstr() i PHP
Innspill: 11 kommentarer · Kategori: Data og teknologi · Tagger: php, programmering, triks

Av: Svend Andreas Horgen, høgskolelektor, faglærer i PHP, forfatter av phpbok.no
Dette innlegget beskriver en snedig måte å bruke PHP-funksjonen strstr() på. Ja, en kan rett og slett si «vakker» bruk av strstr(). La oss si at du ønsker å sjekke for eksempel mimetypen til en opplastet fil, og vil godta flere typer. Går dette an å gjøre det på en enkel måte? Tenk over hvordan du ville gått frem for å løse dette før du leser videre.
Mange synes det er morsomt å programmere litt «out-of-the-box», så la oss se hvordan vi kan tenke alternativt og kanskje få en liten aha-opplevelse på kjøpet
En rett fram løsning er å bruke strengbehandlingsfunksjonen strstr() for å sjekke om noe fins i en tekststreng eller ikke (i andre språk heter tilsvarende funksjon kanskje substring eller noe i den duren). Her lager vi en if-setning som har tre delbetingelser (med OR mellom)
if ( strstr($filtype, "jpg")) || strstr($filtype, "png")) || strstr($filtype, "gif")) ) { //if slår til hvis filtypen er jpg, png eller gif }
Går det an å gjøre det enda mer kompakt? Se nøye på strstr()-koden over før du leser videre. Hvis vi tenker litt motsatt, kan vi gjøre dette enda mer kompakt. Tenk over hvordan strstr() fungerer. Den leter etter nåla i høystakken, slik:
strstr(høystakk, nål)
Hva med å tenke at høystakken blir nål, og motsatt? Helt konkret blir koden slik:
//tar ut filtypen, f.eks. "png" //siden mimetypen er på form 'image/png' $filtype = substr($mimetypen, 6); //har nå f.eks. "png", men det vet vi ikke helt. //Må teste for å være sikker, og heri ligger trikset... //Triks: Smart bruk av strstr. Godtar kun "lovlige" typer if ( strstr("jpg-png-gif", $filtype) ) { //godtar jpg, png og gif }
Ser du hvorfor dette fungerer? Er denne fremgangsmåten strengt tatt lettere enn den første? Tenk deg at du skulle teste på 10 ulike filtyper, og du ser da gevinsten tydeligere. En kunne selvsagt brukt matriser (arrays), evt. regulære uttrykk, men strstr er altså også mulig!
Det jeg liker med denne typen kode, er hvordan den alternative måten å tenke på (der en snur ting på hodet) kan løse problemet på en smart måte. men det er morsomt som en digresjon. I tillegg vil jeg si det er viktig i en læringssituasjon for å få en utvidet forståelse av programmering. Legg merke til at det ikke nødvendigvis er anbefalt å skrive denne form for kode til vanlig. Hvis du legger inn slike lure triks i koden din, så skriv også en liten kommentar på hvorfor det er lurt eller i det minste at dette er et triks. Andre som leser koden i ettertid kan ellers stusse, og i verste fall tro at dette er en feil…
Har du andre snedige måter å bruke strengbehandlingsfunksjoner i PHP på? Bruk gjerne kommentarfeltet!
Dette innlegget har 11 kommentarer. Gjerne bidra :-)
Skrevet av: Svend Andreas Horgen (totalt 133 blogginnlegg)
11 comments
<< Bevegelsesfangst og visualisering av menneskelig bevegelse i sanntid
Hans Nordhaug · 14. oktober, 2010, kl. 10:09
Hei!
Først må jeg si meg enig i at løsningen din er litt elegant. Det beste er at løsning samtidig unngår problemer med Mime-typer som inneholder samme substring – f.eks. «xml» som brukes i «text/xml», «image/svg+xml», osv
Så den kjedelig obligatoriske kommentaren:
PHP-dokumentasjonen anbefaler strpos istedenfor strstr for det du prøver å gjøre. (Det er du sikkert klar.) Dermed blir mitt kjedelige forslag:
if (strpos($mimetypen, array(«/jpg», «/png», «/gif»)) {
// Mime-typen er jpg, png eller gif
}
PS! Kan jeg markere kode i kommentarfeltet? Det burde være mulig hvis du vil ha kode i kommentarene. Og jeg savner veldig en «Preview»-knapp slik at jeg vet hvordan ting blir seende ut før jeg sender inn …
Christian Aune Thomassen · 14. oktober, 2010, kl. 14:48
Morsom vinkling på problemstillingen Sven Andreas!
Hans: Jeg liker å benytte
if (strpos($mimetypen, array(«/jpg», «/png», «/gif») !== false) {
// Mime-typen er jpg, png eller gif
}
i og med at strpos kan returnere 0 som vil bli false. Selv om det ikke blir aktuelt for dette tilfellet når du kun sjekker enden av mimetypene synes jeg det er ryddigere å ha det med.
Author comment by Svend Andreas Horgen · 14. oktober, 2010, kl. 13:39
Jeg var ikke klar over forskjellen i hurtighet på strstr() og strpos(), så takk for godt innspill, Hans!
Når det gjelder forhåndsvisning av bloggkommentarer, så skal vi få installert en plugin som håndterer det. Når en kommenterer går det an å bruke HTML-kode (ser jeg etter å ha testet litt) og også pre-taggen fungerer.
UPDATE 15.10.2010: Det går ikke enda, men skal prøve å fikset det slik at også pre fungerer. Foreløpig virker bare code, og da kommer ikke tab/innrykk med
Christian Aune Thomassen · 14. oktober, 2010, kl. 15:21
Etter innspillet fra Hans kan vel koden om ønskelig tunes fra:
if ( strstr(«jpg-png-gif», $filtype) ) {
//godtar jpg, png og gif
}
til:
if (strpos(«jpg-png-gif», $filtype) !== false) {
//godtar jpg, png og gif
}
For de som vurderer å benytte denne koden til sjekking at bilder av type jpg/png/gif er det lurt å legge til jpeg også i og med at jpg bilder ofte sendes med mimetype image/jpeg.
Author comment by Svend Andreas Horgen · 14. oktober, 2010, kl. 15:31
Godt poeng med å huske jpeg, og lurt å eksplisitt angi !==false. Takk for innspill, Christian!
Hans Nordhaug · 14. oktober, 2010, kl. 15:29
@Christian: Jeg regnet nesten med at noen kom til å kommentere det (selv om jeg med hensikt utelot det). Når du først sjekker for type og dermed godtar 0 som svar, synes jeg du bør skrive Mime-typen helt ut – «image/jpeg» istedenfor «/jpeg» osv – men hvis du skriver Mime-type helt ut er det bedre å sjekke eksakt:
if (in_array($mimetypen, array(“image/jpg”, “image/png”, “image/gif”)) {
// Mime-typen er jpg, png eller gif
}
Og sånn kan vi holde 😉
@Svend: Det er sjelden man har lov til å bruke HTML i kommentarer så det er fint hvis du informerer om det under Submit-knappen.
Author comment by Svend Andreas Horgen · 14. oktober, 2010, kl. 15:41
@Hans: Det var lurt – har lagt til litt info mellom submit-knappen og kommentarfeltet nå 🙂
Egil Kvaleberg · 14. oktober, 2010, kl. 18:06
«Løsningen» din er nok desverre litt for «smart». Den fungerer kanskje for ditt lille tilfelle her, men ikke hvis du ikke vet hva du kan få av inndata: F.eks vil inndata «pg» matche.
Author comment by Svend Andreas Horgen · 15. oktober, 2010, kl. 14:29
Takk Egil for god observasjon angående at også «pg» og «g» og «gi», … vil matche.
Det kommer nok en del flere programmeringsrelaterte innlegg fremover fra ulike faglærere (ulike språk). Siden det trolig vil bli en del kommentarer der folk vil skrive litt kodeeksempler, har vi nå slått på slik at det er mulig for alle å bruke pre-taggen. Da rammes koden inn med gul bakgrunn, blå skrift og innrykk støttes, slik:
Forhåndsvisning kommer etterhvert. Takk for fin erfaringsutveksling så langt!
Om blogg.itfag.no | Blogg for faget sosiale medier · 8. september, 2013, kl. 13:24
[…] http://blogg.itfag.no/2010/10/13/vakker-bruk-av-strstr-i-php/#more-401 […]
Itfag-bloggen | egenside.no · 22. september, 2013, kl. 14:23
[…] er det litt aktivitet i kommentarfeltet under noen av innleggene som går på programmering, som for eksempel dette innlegget. Her er det meningsutveksling der kommentarene gir alternative løsninger og merverdi for […]