- Index
Op de webpagina moet de gebruiker enkel deze eevoudige kode opnemen op de plaats waar de teller moet komen:
<script src=http://myserver.com/cgi-bin/counter></script>Een enkele programma zorgt voor alle tellers op alle pagina's van al je gebruikers:
DEFWORD a-z FUNCTION PBMAIN() $aa = "document.write('": $zz = "');" ' De browser verwacht javascript, geen HTML, homepage$ = ENVIRON$("HTTP_REFERER") ' We moeten de output "inpakken". ipaddr$ = ENVIRON$("REMOTE_ADDR") filename$ = $userpath + PARSE$(homepage$, "/", -2) + "_" + PARSE$(homepage$, "/", -1) + ".txt" ' We maken een filenaam aan gebaseerd op de gebruiker (user directory) ' en de pagina zelf (referer) ' We zouden ook kunnen testen dat de domein name wel van onze server afkomstig is zodat ' niet-klanten onze tellers niet gebruiken. er = ERRCLEAR OPEN filename$ FOR INPUT AS #1 IF ERRCLEAR THEN count = 0 ELSE LINE INPUT #1, count$: count = VAL(count$) LINE INPUT #1, oldipaddr$ CLOSE #1 END IF IF ipaddr$ <> oldipaddr THEN ' In geval de gebruiker meer dan één teller op zijn pagina zou plaatsen INCR count ' of de pagina meermalen na elkaar zou inlezen om de tellen kunstmatig op te voeren OPEN filename$ FOR OUTPUT AS #1 PRINT #1, count PRINT #1, ipaddr$ CLOSE #1 END IF OPEN ENVIRON$("CGI_STDOUT") FOR OUTPUT AS #1 PRINT #1, $aa count $zz END FUNCTION |
Een grafische teller is even gemakkelijk: maak 10 gifs aan, allemaal met dezelfde hoogte en met een transparante achtergrond en noem ze 0.gif, 1.gif, enz. Dit is de kode:
.... OPEN ENVIRON$("CGI_STDOUT") FOR OUTPUT AS #1 count$ = FORMAT$(count, "000000") FOR i = 1 TO 6 PRINT #1, $aa "<img src=http://myserver.com/counterpix/" MID$(count$, i, 1) ".gif align=left>" $zz NEXT i END FUNCTION |
TYPE orderlayout ok AS BYTE ' Om een order te wissen maken we order.ok = 0 customer AS DWORD ' in plaats van het record te wissen. date AS STRING * 6 ' Veel gemakkelijker te recupereren... trackingnumber AS DWORD ... ' enz (alle velden van het order komen hier) message AS DWORD END TYPE DIM order AS orderlayout |
Hoe kunnen we een volledig bericht in 4 bytes schrijven? Heel eenvoudig:
... IF LEN$(msg$) THEN order.message = writerecord($path + "order.mes", msg$) ELSE order.message = 0 END IF OPEN $path + "order.dat" FOR RANDOM ACCESS WRITE AS #1 LEN = LEN(order) PUT #1, iorder, order CLOSE #1 ... |
En zo lezen we een eventueel bericht:
... OPEN $path + "order.dat" FOR RANDOM ACCESS READ AS #1 LEN = LEN(order) GET #1, iorder, order CLOSE #1 IF order.message THEN msg$ = readrecord$($path + "order.mes", order.message) ELSE msg$ = "" END IF ... |
Bericht wijzigen? Oude wissen en nieuwe aanmaken:
... OPEN $path + "order.dat" FOR RANDOM AS #1 LEN = LEN(order) GET #1, iorder, order IF order.message THEN killrecord($path + "order.mes", order.message) END IF order.message = writerecord($path + "order.mes", msg$) PUT #1, iorder, order ... |
Alle handelingen gebeuren in writerecord, readrecord en killrecord. Dit is de source:
|
Een klein minpunt is dat je geen $CRLF in je bericht kan hebben, aangezien deze combinatie als recordseparator wordt gebruikt. Indien je verder toch met HTML zal werken, kan je $CRLF omzetten naar <BR> voor het schrijven.
Het is veel efficienter om records achteraan het bestand bij te voegen dan de gewijzigde records tussen te voegen en de inhoud van de rest van het bestand te verschuiven. Na een tijdje bekom je wel een bestand met ongebruikte delen. Dit is echter geen groot probleem, omdat het bestand met direct access werkt (directe toegang tot iedere record). Maar het is altijd mogelijk de gaten op te vullen:
OPEN $path + "order.mes" FOR INPUT ACCESS READ SHARED AS #1 i = 0 WHILE NOT EOF(1) LINE INPUT #1, a$ IF TRIM$(a$) = "" THEN i = i + LEN(a$) + 2 END IF WEND j = LOF(1) CLOSE #1 percent = i * 100 / j IF percent > 40 THEN OPEN $path + "order.dat" FOR RANDOM ACCESS READ WRITE AS #1 LEN = LEN(order) FOR iorder = 1 TO norder GET #1, iorder, order IF order.ok and order.message THEN a$ = TRIM$(readrecord$($path + "order.mes", order.message)) IF LEN(a$) THEN order.message = writerecord($path + "order.tmp", a$) ELSE order.message = 0 PUT #1, iorder, order END IF NEXT iorder CLOSE #1 KILL $path + "order.mes" NAME $path + "order.tmp" AS $path + "order.mes" END IF |
Deze verwerking doe je best als de server minder belast is. Voor een webtoepassing is het aangeraden de database te locken gedurende de compressie. En natuurlijk maak je gebruik van de gelegenheid om eveneens een back-up te maken.
De volledige compressie is zo gebeurd. Op een oude server (Dell Poweredge 2450, PII 600 MHz, 512MB RAM, SCSI RAID 0-1) duurt de compressie minder dan 10 seconden voor een berichtenbestand van 1 MB (dus duizenden berichten).
Individuele landingspage bezoekers: