Kirjautuminen

Haku

Tehtävät

Koodit: QB: CGI-ohjelmointia

Kirjoittaja: Antti Laaksonen

Kirjoitettu: 28.08.2007 – 28.08.2007

Tagit: koodi näytille, vinkki

Joskus on väitetty, että QBasic ei sovellu nykyaikaiseen ohjelmointiin. Tässä tulee kuitenkin esimerkki, miten QBasicista saa tehtyä PHP:n kaltaisen välineen nettisivujen muodostamiseen. Loppuhuipennuksena on yksinkertainen QBasic-vieraskirja. Jos nettisivujen luonti ei ole nykyaikaista, niin mikä sitten?

Ensimmäinen vaihe on luoda sopiva palvelinympäristö QBasic-ohjelmille. Windows-palvelin on melko välttämätön, koska Linuxissa ei QBasic-ohjelmia voi suorittaa. Apachen käyttäjä voi noudattaa muuten CGI-oppaan ohjeita, mutta mitään tiedostoja ei tarvitse noutaa ja asetustiedostoon lisätäänkin rivi "AddHandler cgi-script .QB". Tämän jälkeen palvelimen hakemistossa oleva QBasic-ohjelma suoritetaan, kun nettiselaimella mennään sennimiseen osoitteeseen. Ainoa ero tavalliseen on, että käännetyn tiedoston pääte ei ole tuttu .EXE vaan .QB.

Esimerkiksi jos hakemistossa "qbasic" on sivu "TESTI.QB", jolle annetaan parametri "a=3", sivun osoite omalla palvelimella on "localhost/qbasic/TESTI.QB?a=3". Sivun osoite muodostuu siis aivan samalla tavalla kuin PHP-skriptin osoite.

QBasic-ohjelmassa tulostetaan nettisivulle tulevaa tekstiä tavalliseen tapaan PRINT-komennolla. Ensin on kuitenkin syytä lähettää tiedotus sivun sisällöstä. Tämä tapahtuu tulostamalla "Content-type: text/html" ja tyhjä rivi. Jos sivu ei olekaan HTML:ää vaan jotain muuta, tätä kohtaa pitää tietysti muuttaa vastaavasti. Toinen mahdollisuus on ohjata käyttäjä saman tien jollekin toiselle sivulle tulostamalla "Location: uudensivunosoite" ja tyhjä rivi.

Ennen QBasic-ohjelman käynnistystä palvelin asettaa hyödyllisiä ympäristömuuttujia, joiden arvoja voi tutkia ENVIRON$-funktiolla. Esimerkiksi ENVIRON$("QUERY_STRING") sisältää osoitteen perään kirjoitetut muuttujat, kun palvelupyyntö on GET-tyyppinen. Jos kuitenkin lomake on lähetetty POST-metodilla, muuttujat täytyy lukea ohjelmaan kuin joku kirjoittaisi ne näppäimistöllä. Molemmissa tapauksissa yksittäiset muuttujat täytyy vielä erotella sekä käsitellä niissä olevat mahdolliset erikoismerkit.

Kaikkea edellä mainittua havainnollistetaan seuraavissa esimerkkiohjelmissa. Ensimmäinen ohjelma (KTAULU.QB) tulostaa sivulle kertotaulun HTML-taulukkona. Toinen ohjelma (OTAIE.QB) onkii selville käyttäjän selaimen ja toimii sen mukaisesti. Kolmas ohjelma (TEKIJAT.QB) pyytää käyttäjältä luvun GET-lomakkeella ja jakaa luvun tekijöihin. Neljäs ohjelma (VKIRJA.QB) on vieraskirja, jossa uusi viesti lähetetään POST-lomakkeella ja viestit tallennetaan tiedostoon VKIRJA.TXT.

PS. Suunnitelmissa on jo erillinen skriptikieli QBScript, jolla pystyy mm. muodostamaan kuvia suoraan QBasicin grafiikkakomennoilla, mutta siitä lisää myöhemmin...

PPS. Palvelimen ylläpitäjää voi ilahduttaa PLAY-komennolla.

kertotaulu (käännettynä KTAULU.QB)

PRINT "Content-type: text/html"
PRINT

PRINT "<h1>Kertotaulu</h1>"
PRINT "<table border>"
FOR i% = 1 TO 20
   PRINT "<tr>"
   FOR j% = 1 TO 20
      PRINT "<td>" + STR$(i% * j%) + "</td>"
   NEXT
   PRINT "</tr>"
NEXT
PRINT "</table>"

selaimen tunnistus (käännettynä OTAIE.QB)

selain$ = ENVIRON$("HTTP_USER_AGENT")
IF INSTR(selain$, "MSIE") = 0 THEN
   PRINT "Location: http://www.microsoft.com/windows/downloads/ie/getitnow.mspx"
   PRINT
ELSE
   PRINT "Content-type: text/html"
   PRINT
   PRINT "<h1>Kaikki hyvin!</h1>"
END IF

tekijöihin jako (käännettynä TEKIJAT.QB)

DIM SHARED param$(20, 2), pmaara%

PRINT "Content-type: text/html"
PRINT

PRINT "<h1>Tekijöihin jako</h1>"

muuttujat$ = ENVIRON$("QUERY_STRING")

IF muuttujat$ = "" THEN
   PRINT "<form action='TEKIJAT.QB' method='get'>"
   PRINT "Kirjoita luku: <input type='text' name='luku'>"
   PRINT "<br><input type='submit' value='Laske'>"
   PRINT "</form>"
ELSE
   Kasittele muuttujat$
   luku& = VAL(Hae$("luku"))
   PRINT "<p>Luvun <b>"; luku&; "</b> tekijät:</p>"
   PRINT "<ul>"
   FOR i& = 2 TO SQR(luku&) + 1
      maara& = 0
      WHILE luku& MOD i& = 0
         luku& = luku& \ i&
         maara& = maara& + 1
      WEND
      IF maara& = 1 THEN
         PRINT "<li>"; i&
      ELSEIF maara& > 1 THEN
         PRINT "<li>"; i&; "<sup>"; maara&; "</sup>"
      END IF
   NEXT
   IF luku& > 1 THEN
      PRINT "<li>"; luku&
   END IF
   PRINT "</ul>"
END IF

FUNCTION Hae$ (nimi$)
   FOR i% = 1 TO pmaara%
      IF param$(i%, 1) = nimi$ THEN
         Hae$ = param$(i%, 2)
         EXIT FUNCTION
      END IF
   NEXT
END FUNCTION

SUB Kasittele (muuttujat$)
   tila% = 1
   FOR i% = 1 TO LEN(muuttujat$)
      merkki$ = MID$(muuttujat$, i%, 1)
      IF merkki$ = "+" THEN
         merkki$ = " "
      END IF
      IF merkki$ = "%" THEN
         merkki$ = CHR$(VAL("&H" + MID$(muuttujat$, i% + 1, 2)))
         i% = i% + 2
      END IF
      IF tila% = 1 THEN
         IF merkki$ = "=" THEN
            arvo$ = ""
            tila% = 2
         ELSE
            nimi$ = nimi$ + merkki$
         END IF
      ELSE
         IF merkki$ = "&" THEN
            Lisaa nimi$, arvo$
            nimi$ = ""
            tila% = 1
         ELSE
            arvo$ = arvo$ + merkki$
         END IF
      END IF
   NEXT
   IF nimi$ <> "" THEN
      Lisaa nimi$, arvo$
   END IF
END SUB

SUB Lisaa (nimi$, arvo$)
      pmaara% = pmaara% + 1
      param$(pmaara%, 1) = nimi$
      param$(pmaara%, 2) = arvo$
END SUB

vieraskirja (käännettynä VKIRJA.QB)

DIM SHARED param$(20, 2), pmaara%

IF ENVIRON$("REQUEST_METHOD") = "POST" THEN
   pituus% = VAL(ENVIRON$("CONTENT_LENGTH"))
   muuttujat$ = INPUT$(pituus%)
   Kasittele muuttujat$

   nimi$ = Hae("nimi")
   sposti$ = Hae("sposti")
   viesti$ = Hae("viesti")
   pvm$ = MID$(DATE$, 4, 2) + "." + LEFT$(DATE$, 2) + "." + RIGHT$(DATE$, 4)
   kello$ = TIME$

   OPEN "VKIRJA.TXT" FOR APPEND AS #1
   PRINT #1, "<hr>"
   PRINT #1, "<p><b>Lähettäjä:</b> "
   IF sposti$ = "" THEN
      PRINT #1, nimi$ + "</p>"
   ELSE
      PRINT #1, "<a href='mailto:" + sposti$ + "'>" + nimi$ + "</a></p>"
   END IF
   PRINT #1, "<p><b>Ajankohta:</b> " + pvm$ + " " + kello$ + "</p>"
   PRINT #1, "<p><b>Viesti:</b><br>" + viesti$ + "</p>"
   CLOSE #1
   PRINT "Location: " + ENVIRON$("SCRIPT_NAME")
   PRINT
   END
END IF

PRINT "Content-type: text/html"
PRINT

PRINT "<h1>Vieraskirja</h1>"
PRINT "<hr>"
PRINT "<form action='VKIRJA.QB' method='post'>"
PRINT "Nimi: <input type='text' name='nimi'><br>"
PRINT "Sähköposti: <input type='text' name='sposti'><br>"
PRINT "Viesti:<br>"
PRINT "<textarea name='viesti' cols='50' rows='5'></textarea><br>"
PRINT "<input type='submit' value='L&auml;het&auml;'>"
PRINT "</form>"

OPEN "VKIRJA.TXT" FOR INPUT AS #1
WHILE NOT EOF(1)
   INPUT #1, rivi$
   PRINT rivi$
WEND
CLOSE #1

FUNCTION Hae$ (nimi$)
   FOR i% = 1 TO pmaara%
      IF param$(i%, 1) = nimi$ THEN
         Hae$ = param$(i%, 2)
         EXIT FUNCTION
      END IF
   NEXT
END FUNCTION

SUB Kasittele (muuttujat$)
   tila% = 1
   FOR i% = 1 TO LEN(muuttujat$)
      merkki$ = MID$(muuttujat$, i%, 1)
      IF merkki$ = "+" THEN
         merkki$ = " "
      END IF
      IF merkki$ = "%" THEN
         merkki$ = CHR$(VAL("&H" + MID$(muuttujat$, i% + 1, 2)))
         i% = i% + 2
      END IF
      IF tila% = 1 THEN
         IF merkki$ = "=" THEN
            arvo$ = ""
            tila% = 2
         ELSE
            nimi$ = nimi$ + merkki$
         END IF
      ELSE
         IF merkki$ = "&" THEN
            Lisaa nimi$, arvo$
            nimi$ = ""
            tila% = 1
         ELSE
            arvo$ = arvo$ + merkki$
         END IF
      END IF
   NEXT
   IF nimi$ <> "" THEN
      Lisaa nimi$, arvo$
   END IF
END SUB

SUB Lisaa (nimi$, arvo$)
      pmaara% = pmaara% + 1
      param$(pmaara%, 1) = nimi$
      param$(pmaara%, 2) = arvo$
END SUB

Kommentit

arcatan [29.08.2007 08:50:23]

#

Haha :D, miksipä ei, miksipä ei? Onhan sitä brainfuck-CGI:täkin tehty.

nomic [29.08.2007 11:17:42]

#

Tämähän oli minulle uutta! Propsit sinne. ;)

Mega-Ohjelmoija [29.08.2007 17:32:48]

#

Olihan tämä minullekkin aika uutta.
Mutta kokonaisuudessaan selkeää luettavaa.

kayttaja-4976 [30.08.2007 18:28:23]

#

Yhhyh, IE:n suosittelu >_<

gamehouse [30.08.2007 19:34:12]

#

Hieno!

moptim [04.09.2007 17:07:39]

#

Kertokaapas miten toi käännetään.

Antti Laaksonen [04.09.2007 17:10:44]

#

Ohjelma käännetään ihan tavallisesti, mutta ohjelman pääte muutetaan EXEstä QB:ksi.

Cornix [08.09.2007 19:21:54]

#

Joskus käytin QB:tä tähän tapaan jääkaapin sisällön listaamiseen. Kaapissa olevat tuotteet ohjelma tulosti tekstitiedostosta, mutta lopulta projekti kaatui siihen, että en jaksanut pitää listausta ajan tasalla. Joskus voisi toteuttaa PHP:llä ja jollain tietokannalla samanlaisen. :)

Olis aika siistiä, jos ois viivakoodinlukija jääkaapin vieressä. Sillä voisi sitten suoraan lisäillä tai poistaa tuotteita niin, että senhetkistä sisältöä voisi kurkkia lähiverkon koneilta suoraan veppiselaimella.

E.K.Virtanen [17.09.2007 15:02:38]

#

Oot sie Antti aika epeli :D

temu92 [22.09.2007 22:51:44]

#

Hienoo, saman systeemin saa toimimaan kanssa C++ exeillä :D Tuli testattua :D

Dude [17.10.2007 11:32:46]

#

Miten tuota käytetään? PLAY juttu on hyvä, aina ku joku lataa sivun alakaa palavelin piipittää.
Edit: saispa jotenki linuxilla tuon toimimaan(siis qbeen).
Edit2: Laittakaa vaikka sioux-servu johonki 38kutoseen ja sinne qb-viritelmiä.

nörtti [27.10.2007 16:18:01]

#

Mulla tulee vain ilmoitus 500 Error running CGI. http://juhanih.dy.fi/KTAULU.QB Palvelinsofta on Shttpd.

Juhko [27.03.2009 19:04:13]

#

IE = kakka

Mutta muuten tosi hyvä juttu. :)

kayttaja-11960 [09.11.2012 14:30:37]

#

nörtti kirjoitti:

Mulla tulee vain ilmoitus 500 Error running CGI. http://juhanih.dy.fi/KTAULU.QB Palvelinsofta on Shttpd.

Laitoitko chmod-arvot oikeiksi?

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta