1. Dec 04

    Debugging kan være en plagsom ting. Frustrere deg godt og du kan tro all håp er ute. Du kan til slutt tro at det er ingenting feil med kodene dine, for du har gått igjennom alt. Her kommer en liten innføring i hvordan du kan debugge selv. Slik at mange unødvendige spørsmål kommer opp i PHP-forumet på NWF. Listen er satt opp etter hva du burde gjøre kronologisk. Start med punkt én, og jobb deg nedover listen.

    Det er store sjanser for at du løser problemet lenge før du i det hele tatt kommer nedover på listen. De fleste problemer blir løst på punkt 3 av listen.

    1. Les feilmeldingen nøye. Det er en grunn til at feilmeldingene kommer og de er faktisk ganske opplysende. Om det er noe du ikke skjønner i feilmeldingen, som hva T_VARIABLE er, burde du ta et kjapt på T_VARIABLE i google.
    2. Du får oppgitt linjenummer hvor det feiler i en feilmelding. Linjenummeret er veldig essensielt. Du går til linjen og sjekker hva som er galt. Noen ganger når det er PARSE-ERROR lønner det seg å se på linjen før det feilmeldingen sier. Dette kan være tegn som er glemt på linjen ovenfor, som å glemme å avslutte et if-statment, eller du har glemt å avslutte linjen med semikolon.
    3. Har du med MySQL og gjøre vil ikke MySQL feilene komme på lik linje som PHP-feil. Du vil bare ikke få noe resultat ut, og alt kan tyde på at det ikke er innhold i databasen/tabellen din. Er du sikker på at du har innhold med de kriteriene du er ute etter, må du printe ut mysql_error () for å finne ut hvilken feilmelding det er MySQL kommer med. Dette kan du gjøre på mange måter, men den mest brukte er som regel å legge til “or die (mysql_error());” etter siste ) i mysql_query eller tilsvarende som returnerer bool (returnere bool betyr enten sant eller ikke sant. (true|false)). Annen måte du kan gjøre det på er:
      1
      2
      3
      4
      5
      
      $query = mysql_query ("SELECT id FROM table");
      if(!$query) {
         echo "En feilmelding i spørringen:\n";
         echo mysql_error();
      }

      Har du problemer med å løse det som står i feilmeldingen, bruker du manualen til MySQL for å sjekke hva enkelte ting støtter, og hvordan det skal gjøres. Eventuelt tar du å kopierer feilmeldingen inn i google og søker etter lignende saker. Da finner du garantert ut hva som kan løse saken.

    4. Inneholder arrayen/objektet/variabelen det du vil den skal inneholde? Får du helt feil resultat ut på siden din, bruker du var_dump/print_r på objekt/arrays, mens echo/die på variabler, for å sjekke om de inneholder det de skal. Om de ikke gjør det bruker du punkt 5 til å finne hvor det blir feil, og hva det er som virkelig skjer.
    5. Finn ut hvor det feiler! Om du ikke får ut noen feilmelding av noe slag, men du kommer bare ikke frem til dit du vil komme frem betyr det at en if-sjekk slår inn der du ikke vil den skal slå inn. En funksjon returnerer noe feil. Da må du finne ut hvor dette skjer. I hvilken brakke er det nettleseren kommer til? Slik finner du ut hvor det feiler, og dermed hva som er feil. Ta utgangspunkt i der du forventet at du skal komme og sett f.eks die (‘Kom inn hit’); i det ytterste leddet. Kommer den dit? Nei? Da går du inn et nivå, og sjekker om den kommer inn dit. Slik jobber du deg innover for å ekskludere plasser hvor det feiler. Til slutt vil du komme til der den kommer inn. Du finner f.eks ut at det er en funksjon som returnerer false i stedet for true som du ville den skulle gjøre. Er det en selvdeklarert funksjon går du inn på funksjonen for å bruke samme metode for å komme inn til der den faktisk returnerer false.
    6. Siste punkt, er det i alle fall ikke ofte jeg kommer frem til når jeg har brukt metodene ovenfor. Uansett er siste punkt veldig enkelt. Det er nesten garantert at dette punktet vil løse opp problemet ditt også: Just Fucking Google it!

    Eksempel på debug

    Jeg har et nyhetsscript. Når jeg prøver å legge inn informasjon fra form der, vil det aldri bli satt inn noen verdier i tabellen min i databasen. Ingenting kommer. Jeg får ingen feilmelding, men det kommer bare ingenting. Derfor hopper jeg over punkt 1 og punkt 2, siden det ikke er noen feilmelding i PHP. Da kommer jeg rett på punkt 3, som er å se på mysql_error. Jeg legger til som eksemplet ovenfor, og finner at det er for $_POST-verdiene mine ikke får noe som helst slags verdi. Merkelig tenkte jeg. Så jeg går videre til punkt 4, som sier at jeg skal sjekke hva er det $_POST-arrayen inneholder. Så jeg tar en die (print_r($_POST));. Der finner jeg følgende:

    Array (
    [title] => Hei du kåre,
    [message] => Min tekst nedover her
    )

    Da ser jeg va nøkkel-verdiene er på $_POST arrayen. Og finner ut hva jeg gjør feil. Jeg har heletiden brukt $_POST['tittel'] og $_POST['melding'] i stedet for $_POST['title'] og $_POST['message'].

    Slik kan du bruke listen. Og som sagt er det veldig sjeldent at du i det heletatt kommer ned til å måtte google feilen.

    \\ emneord: ,

  2. Dec 04

    For litt siden kom noen til meg over MSN og lurte på hvordan de kunne bruke GROUP_CONCAT() men bare implodere de 3 nyeste (høyest ID). Og dette ville han da gjøre uten noen loop som helst. Jeg sier til han at han burde bruke PHPs implode()-funksjon, men det ville han visst ikke. MySQL skal vel egentlig ikke brukes til å manipulere date, men heller til å håndtere/deligere/lagre innhold (data).

    Uansett tenkte jeg at løsningen måtte være å bruke en subquery, hvor man sjekket at id var i id-ene som ble plukket ut av subqueriet. Nyere versjoner støtter ikke å bruke IN/ALL/ANY/SOME til subqueries i WHERE-clause, så da er løsningen ganske selvsigende.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    SELECT
       GROUP_CONCAT(
          a.id
          ORDER BY a.id DESC
          SEPARATOR ', '
       ) as imploded_idfield
    FROM myField a
    INNER JOIN
       (
          SELECT id
          FROM myField
          ORDER BY id DESC
          -- [WHERE ... ]
          LIMIT 3
       ) b
    ON a.id = b.id

    Da har vi alle de imploderte verdiene i imploded_idfield, og kan se ut noe som

    “300, 299, 298″

    \\ emneord: , ,

  3. Dec 04

    Syntaksen i regulære uttrykk kan deles opp i flere grupper. I alt har vi 5 forskjellige. Disse kan vi si er

    • Tegnsetting
    • Ankrer
    • Klassekoder
    • Klasser
    • Modifiers

    Disse gruppene dekker ikke alle felt, men de fleste. F.eks dekker de ikke hexadecimal som koden er \xTALL på.

    Tegnsetting

    Tegnsettingen er veldig essensielt i RegExp. De kan bestemme alt som skal foregå i et uttrykk.

    • \ » Den escaper andre tegn og klasser. Brukes forrann et annet tegn og du matcher tegnet. Bruker du den forrann klasser så blir det en annen sak, som vi kommer tilbake til. Eksempel: /(http:\/\/)/
    • | » Kan oversettes til eller. Eksempel: /(http|ftp):\/\//
    • { og } » Setter lengden den skal godta. Eksempel: /([\w]{10,20})/
    • ( og ) » Grupperer valgene og velger det en kan bruke senere. F.eks det som er mellom paranteser kan bli kalt med \\1 i en preg_replace. Eksempel: /([\w]{10,20})/
    • [ og ] » Setter klasser av tegn og rekkevidder. Eksempel: /[a-z]/
    • . » Alle tegn foruten \n Eksempel: /./
    • * » Matcher tegn fra 0 eller mer. Samme som {0,} Eksempel: /(.*)/
    • + » Matcher tegn fra 1 eller mer. Samme som {1,} Eksempel: /(.+)/
    • ? » Matcher tegn fra 1 eller ingen. Samme som {0,1} Eksempel: /(.?)/
    • ^ » Definerer starten på en streng.Eksempel: /^[a-z]{3,6}/ – Inneholder a-z på de 3-6 første tegnene av en streng
    • $ » Definerer slutten på en streng. Eksempel: /[a-z]{3,6}$/ – Inneholder a-z på de 3-6 siste tegnene av en streng

    Ankrer

    Ankerkoder vil definere hvor i strengen du mener. ^ og $ er to ankerkoder. Men det finnes flere.

    • \b » Setter en grense i et ord. Kutter ordet etter match.Eksempel: /MinStreng\b/
    • \B » Tar alt utenom grensenEksempel: /Rat\B/ – Tar Rattata, men ikke kun Rat.
    • \A » Definerer starten på en streng.
    • \Z » Definerer starten på en streng.

    Klassekoder og klasser

    Her er det som definerer rangen mellom strenger. Hvilke tegn den skal matche o.l. Det er flere måter å gjøre det på, bruke enkeltbokstaver med escape, f.eks \w og \d. Eller bruke range “manuelt”, f.eks [a-z] og [0-9].

    • \d == [0-9] » Matcher alle tall
    • \D == [^0-9] » Matcher alle ikke tall
    • \w == [a-zA-Z_0-9] » Matcher alle bokstaver fra a til z, store og små. Samt tall og understrek.
    • \W == [^a-zA-Z_0-9] » Matcher alt som ikke er a-z (små og stort), tall og understrek
    • \s == [ \t\n\r\f] » Matcher whitespace, tabulater, newline osv.
    • \S == [^ \t\n\r\f] » Matcher alt som ikke er whitespace, tabulater, newline osv.

    Modifiers

    Jeg mangler et norsk ord på dette. Alle har hørt om det, men er ikke sikkert de er klar over alle eller vet hva de gjør. De fleste vet hva i-modifieren gjør, men har du hørt om o? Eller g? Eller kanskje e? Vel, her er en liste over modifiers.

    • i » Gjør mønsteret case-insensitive
    • e » Bruk som callback i preg_replace i PHP.
    • x » Bruk utvidet regulært uttrykk
    • o » Kjør uttrykket kun èn gang.
    • g » Kjør uttrykket globalt. Over flere ganger. Som preg_match_all()
    • m » Behandle uttrykket som flere linjer
    • s » Behandle uttrykket som kun èn linjer

    Hvordan sette det sammen?

    Så nå har vi all informasjonen vi trenger til å sette sammen et uttrykk. Slik som dette:

    Eksempel

    Vi skal stoppe spam, og har sett at et fellestrekk med spam-postene er at postene ofte har “Hey”, “Hello” eller “Hi” i starten, og fulgt av to linker på neste linje. Den inneholder også tekst etter “Hey”, “Hello” eller “Hi”. Denne er observert som vanlig tekst mellom 14 og 25 tegn.

    Eksempel på kommentar ser slik ut:

    Hello! Great site, pal!
    <a href=”http://mikaelb.net/#”>SpamLink</a> | <a href=”http://mikaelb.net/#”>SpamLink</a>

    Vi skal lage et uttrykk som passer dette, hvordan?

    Tenk et ledd om gangen. Først starter vi med at alle starter med “H”. Da gjør vi slik:

    1
    
    /^H/i

    Men siden det er et ord der, kan vi videreutvikle den og skrive slik:

    1
    
    /^H[^\s]{1,6}/i

    Så hva har du mer av i strengen etter Hello/Hei/Hi? Jo, det kommer mellomrom og mer påfølgende tekst. Teksten kan være alle tegn utenom newline. Det kan skrives slik [^\n]. Og den teksten var mellom 14 og 25 tegn. Da utvider vi den og lar den bli slik:

    1
    
    /^H[^\s]{1,6}\s?[^\n]{14,25}/i

    Grunnen til at jeg har \s? er for det skal være space, men eventuelt ikke. Derav er det ? etter \s, for å få valgfriheten.

    Så kan vi tenke oss at et uttrykk for en link ser slik ut:

    1
    
    &lt;a[^&gt;]?href="[^&gt;]"[^&gt;]?&gt;(.*)&lt;\/a&gt;

    Så kan vi sette den sammen til ett uttrykk:

    1
    
    /^H[^\s]{1,6}\s?[^\n]{14,25}\s*(&lt;a[^&gt;]?href="[^&gt;]"[^&gt;]?&gt;(.*)&lt;\/a&gt;[^&gt;]?)*\z/

    \\ emneord: , ,

  4. Dec 04

    I sammenhengen med en DVD-liste jeg lagde en gang i tiden, la jeg til noe statistikk for moro skyld. Der fant jeg ut at jeg ville finne ut hvilken sjanger jeg ser mest av, og eier mest av. Derfor måtte jeg finne den verdien som forekommer oftest i et felt.

    Jeg tenkte det kunne være litt kjekt å fått denne servert i fanget, da den kan komme til nyttighet for noen senere. Dette er nesten samme som da jeg skulle finne motsatte av destinkte verdier.

    Så den jeg lagde, ble noe slik som den her:

    1
    2
    3
    4
    5
    6
    
    SELECT 
       COUNT( id ) AS quantity, field_name
    FROM table
    GROUP BY field_name
    ORDER BY quantity DESC
    LIMIT 1

    Så her er FIELD feltet som du teller opp i, og id er unike id til tabellen. Her vil du få noe resultat som dette:

    quantity  - field
    1233      - value

    Håper dere finner den nyttig.

    PS/Tips: Om dere vil ha full statistikk over forskjellige verdier og hvor mange det forekommer av de. Kan være kjekt for statistikk-applikasjoner for å telle forskjellige besøk av forskjellige IP-adresser.

    \\ emneord: , ,

  5. Dec 04

    Pseudo-klasser er CSS-mest fascinerende funksjoner. Du kan få utrettet så utrolig mye med de, det er bare synd at det er veldig dårlig støtte for disse i de fleste nettlesere. Vi finner best støtte av pseudo i følgende nettlesere: Safari, Mozilla Firefox og delvis Opera. IE 6 har nesten ingen støtte, mens IE 7, har noe mer.

    Jeg kommer til å gi en kjapp innføring av de forskjellige pseudoene. Det jeg vil gjøre er å ha en liste med navn, uthevd i bold, og så en liten forklaring. Noen, de jeg finner mest interessant, får et lite eksempel helt på bunnen. Listen vil bli slik som dette:

    navn » (Eks bruk:) element.klasse:pseudo » Forklaring

    Her kommer listen, starter med de med best støtte.

    • Hover, active, visited, link » a.postlinks:hover » Disse er de vanligste pseudo-klassene. De blir brukt til å lage forskjellig stil på linker, selv om de i overnevnte nettlesere fungerer på andre elementer enn a. I IE 6 har de kun støtte i a. Hover blir brukt når musen er over linken. Active er når du har trykt på siden, før du har lastet til ny side, eller det er en pop-up. Visited er på de som er besøkt. Link er på vanlige linker, altså ikke med hover, active eller visited. Det er ofte god skikk å skille fra visited til link. Link, visited og active er ment til a-elementet.
    • First-line, first-letter » p.postinfo:first-letter » Denne er veldig selvforklarende. first-line er brukt til den første linjen av en tekst, gjerne i paragraf, siden det er paragrafer som skal inneholde tekststykke. Når det blir neste linje, selv om du ikke bruker noe braker, vil ikke dette gjelde. First-letter sier seg også selv. Det gjelder kun for den første bokstaven. Den er genial til å f.eks gjøre slik som i bøker, der første bokstav er veldig stor, og de andre er normale.
    • Focus » textarea.commentField:focus » Denne brukes i sammenheng med forms og gjelder når du har trykt og fokuset er på input/textarea. Når du trykker på feltet og skal skrive i det, kommer det f.eks en annen farge eller lignende.
    • Before, after » h1.header:after » Om noen husker mitt gamle tema til denne bloggen og har sett den i forskjellige nettlesere kunne du noen gang se «.. Mikael Brevik ..» og andre ganger kun Mikael Brevik. Der har du before og after. Det legger til innhold før teksten i elementet og etter. I denne sammenhengen bruker du gjerne egenskapen content som legger til innhold. Eks. content: " ...";. Before er før og after er etter – logisk nok.
    • First-child, last-child » li.navigation:last-child » Denne er genial å bruke i eksempelvis navigasjoner. Har vi ikke alle hatt problemer med at du vil skille navelementene med en border og legger den til høyre, men vi vil ikke ha det på siste element. Da må vi til med en egen klasse for den som fjerner rammen. Med denne trenger du ikke det, og vi slipper å klure i markupen. First-child er altså det første elementet under parent, og last-child er det siste. F.eks antall paragrafer i en divisjon eller da liste elementer i en ul.
    • Only-child » p.info:only-child » Her har vi nok en selvforklarende pseudo. Denne gjelder kun om p.info er den eneste child av en parent. Om du har kun en p inne i en divisjon, og har denne så vil det gjelde den!
    • Empty » div.gallery:empty » Genial å bruke for å vise til f.eks en feilmelding. Om det skal være innhold der som du tar ut fra f.eks en database, men det kommer ikke ut (ja kanskje et galleri) så kan du gjøre noe spesiell styling med denne.
    • Root » :root » Ser den følger ikke helt strukturen. Denne trenger nok litt forklaring også, selv om den er temmelig logisk. Den velger altså den ytterste elementet bak alle ellement og blokker. Start tag-en med andre ord. Det er altså i HTML tagen html. Den kan du bruke til.. Ingen aning hva nytteverdien er. Du kan like greit bruke html { /*style */ } spør du meg. Men den har sikkert en dypere mening som jeg ikke har oppdaget.
    • Not » p.newsText *:not(code) » Denne velger å ha stylingen på alle elementer inne i .newsText men ikke på code-tagen. Dette er en av de mest avanserte pseudo-klassene spør du meg. * er alt som vi vet.
    • Target » p.newsText:target » Her har vi nok en genial pseudo-klasse fra CSS2! Denne gjelder på alle klasser som har id lik det som er oppgitt i url. Du har f.eks en klasse med id=”database” og linken www.domene.no/#database. Da vil stylingen gjelde for det elementet som har den id-en. Genial for highlighting?? Ja.
    • Selection » p.postinfo::target » Hehe, må le. Denne er fiffig rett og slett. Denne styler du markeringen av tekst på. Om du har en paragraf med klassen postinfo og noen merker teksten som står der, kan du style hvordan markeringen vil se ut. Rett og slett genialt, men unyttig?

    Der har vi det. En kjapp gjennomgang av pseudo-klasser. Nå ser jeg på klokken og vet jeg skal ha en stor nynorskprøve i morgen. Derfor kan jeg komme tilbake til eksempler senere en dag.

    Håper dere setter dere ned og prøver ut de forskjellige pseudo-klassene, og om dere gjør – bruk Safari eller Firefox, som har den beste støtten. Safari har som jeg har sett best støtte, og støtte for alt ovenfor! Dette blir fremtiden i alle nettlesere dere, det håper jeg i alle fall.

    God natt og lykke til!

    \\ emneord: , ,