Deze FAQ is ontstaan naar aanleiding van de vele vragen die regelmatig in de nieuwsgroep nl.internet.ontwerp worden gesteld. Zodra de FAQ van Kristian Koehntopp Kristian Koehntopp ook aan de Open Publication License voldoet zal er een samenwerking volgen waarbij vooral moet worden gedacht aan het uitwisselen van tips, nieuwtjes, etc.
Deze FAQ valt sinds 22 maart 2000 onder de Open Publication License. Je kan hem bekijken op de volgende url: http://www.opencontent.org/openpub/
Ja natuurlijk, graag zelfs. Op dit moment heb ik de FAQ nog niet op een CVS account staan maar zodra dat het geval zal zijn zal dat hier worden vermeld.
De nieuwste versie zal binnenkort zijn te vinden op 2 sites in Nederland, te weten:
PHP:
MySQL:
PHP is een server side script taal dat op allerlei manieren kan worden ingezet. Het is voor de gemiddelde persoon vrij snel op te pikken. Mensen die al enige/veel programmeer/scripting ervaring hebben zullen zeer snel in staat zijn om een webapplicatie er mee te maken. PHP is ook als CGI parser in te zetten.
PHP is voor vele doeleinden geschikt. Het beste komt het tot zijn recht als je het inzet voor dynamische websites. Hierbij kan je denken aan:
Eigenlijk is dit maar een kleine greep van wat er mogelijk is. De grote kracht van PHP is eigenlijk het feit dat je support kan meecompileren voor een groot aantal database(servers).
Het is de bedoeling dat deze FAQ zal uitgroeien tot een document waarin je veel antwoorden zal kunnen terugvinden. Naast deze FAQ zijn er een aantal plekken op het internet waar je informatie kan terug vinden.
Engelstalige websites.
Naast de hierboven genoemde websites kan je ook terecht op usenet. Op usenet is er op dit ogenblik maar 1 nieuwsgroep waar je terecht kan met je vragen. Het is de Duitstalige nieuwsgroep news://de.comp.lang.php/. De mensen beantwoorden niet alleen Duitstalige vragen.
Naast die Duitstalige nieuwsgroep kan je met je vragen ook terecht bij de Nederlandstalige nieuwsgroep news://nl.internet.ontwerp.
Er is een Engelstalig php kanaal op irc (#php) maar daar is een ban op alle mensen gezet die uit Nederland komen. Zelf is het me niet gelukt om met de operaters in contact te treden en te vragen wat er aan de hand is.
Bij het samenstellen van de FAQ ben ik uitgegaan van PHP4.0 (Beta4). Dit aangezien de verwachting is dat PHP4 binnenkort overal in gebruik zal worden genomen.
Op dit moment staat PHP4 nog niet op een mirror in Nederland. Je kan de nieuwste versie downloaden vanaf.
http://www.php.net/version4/downloads.php
Voor het installeren van PHP4.0 ben ik uitgegaan van de volgende configuratie.
Deze configuratie heb ik op een Red Hat 6.0 distributie draaien maar dit mag op zich niets uitmaken. Mocht je MySQL en Apache via een package system zoals rpm hebben geïnstalleerd zorg er dan voor dat je ook de development packages laat installeren.
Zorg dat je een directory hebt waar je php kan compileren en pak de source uit op de volgende manier en ga naar de directory die is aangemaakt:
$tar -zxf php*.tar.gz
$cd php-4.0b4pl1
Controleer of apxs op je machine aanwezig is. Dit kan met locate danwel whereis. Deze locatie heb je nodig om als parameter mee te geven aan het configure script.
Aan configure script kan je een heleboel opties mee geven. Deze opties kan je bekijken door het volgende in te typen:
$ ./configure --help | less
Om PHP te installeren met de opties die wij nodig hebben (MySQL) heb je in ieder geval de volgende opties nodig:
$ ./configure --with-apxs=/path/apxs --with-mysql --enable-track-vars
--enable-trans-id
Als het script klaar is is het tijd om de module te maken:
$ make
Hierna moet je als root de module installeren:
$ su
(Geef je wachtwoord op)
# make install
Het script heeft als het goed is alle opties in de configuratie bestanden van Apache aangepast en de php.ini op de juiste plek gezet. Maak een bestandje aan waarin je de volgende code zet:
<?phpinfo()?>
Plaats dit bestand in de root van de apache server en roep het op via de browser. Let op dat PHP4.0 de bestanden ziet met een extensie .php. Als alles goed is gegaan dan zie je een informatie scherm waarin alle opties van PHP zichtbaar worden.
Op http://prometheus.zerodivide.net/apache_kit/about/ kan je een Apache Compile Kit downloaden die het zware werk voor je doet. Op dit moment heb ik er nog geen ervaring mee opgedaan. Volgens de website werkt het i.i.g. met Apache 1.3.12 en PHP3/4 (t/m Beta3).
Tip van Alfred Munnikes.
MySQL is een Client/Server SQL database server. Het is voornamelijk gericht op snelheid. Veel mensen maken de vergissing dat je alleen kleine databases kan gebruiken met MySQL. Dit is echter afhankelijk van andere factoren (mogelijkheden voor transakties, e.d.).
Zelf heb ik tot volle tevredenheid gewerkt met aanzienlijke databases (600.000 records).
Voor het benaderen van een MySQL server zijn er twee mogelijkheden. Je kan een default server opgeven in je php.ini en je kan het rechtstreeks vanuit de code regelen. Die eerste optie heeft als groot nadeel dat mensen die php scripts op dezelfde server kunnen draaien zeer snel het wachtwoord uit de configuratie kunnen ophalen.
Om contact te leggen naar een MySQL server heb je de volgende drie gegevens nodig:
De functie om de connectie op te bouwen is mysql-connect:
mysql_connect("servernaam","user","wachtwoord");
Als er een connectie naar de database server tot stand is gebracht moet je de database selecteren die je wilt gebruiken. Daarvoor gebruik je de mysql-select-db functie. Ook controleer je of het is gelukt om die database te selecteren:
mysql_select_db("databasenaam") or die ("Verdorie, kan de database
niet openen");
Afhankelijk van de rechten die de gebruiker heeft kan hij/zij toegang hebben tot meerdere tabellen. Deze tabellen zijn op te vragen met de mysql-list-tables functie:
<?php
/*
Connectie naar de database
*/
mysql_connect( "server", "inlognaam", "wachtwoord");
/*
Uit welke database wil je de tabellen ophalen.
*/
$tabellen = mysql_list_tables( "database");
/*
Tellertje en loop om de tabellen te tonen.
*/
$i=0;
while ($i < mysql_num_rows($tabellen)){
$t_name[$i] = mysql_tablename ($tabellen, $i);
echo $t_name[$i]. "<br>";
$i++;
}
?>
Elke MySQL tabel zal verschillende velden bevatten. Om deze velden op te halen pas je de de volgende code toe:
/*
Connectie opzetten.
*/
mysql_connect( "server", "inlognaam", "wachtwoord");
/*
Geef de database en de tabelnaam op bij de functie mysql-list-fields
*/
$fields = mysql_listfields( "database", "tabel");
/*
Kijk hoeveel velden er totaal zijn en zet de teller $i op 0.
*/
$field_num = mysql_num_fields($fields);
$i=0;
/*
Toon het totaal aantal velden ($field_num) in de browser.
*/
echo $field_num . " veld(en) gevonden<br>\n";
/*
Zet een html tabel op en toon de veldtypes, veldnamen en
de veldlengte van die velden in een loop.
*/
echo "<table width=\"90%\" border=1><tr><td>";
echo
"Naam</td><td>VeldType</td><td>Lengte</td><td>Vlag</td></tr>";
while ($i < $field_num){
$type = mysql_field_type ($fields, $i);
$name = mysql_field_name ($fields, $i);
$len = mysql_field_len ($fields, $i);
$flags = mysql_field_flags ($fields, $i);
echo "<tr><td>";
echo $name. "</td><td>".$type.
"</td><td>".$len. "</td><td>".$flags.
"</td></tr>";
$i++;
}
echo "</table>";
Als je via een html form gegevens laat invoeren in de database kan het gebeuren dat mensen gebruik maken van (o.a.) single en double quotes. Als je geen gebruik maakt van de functie stripslashes() bij het uitlezen van die data krijg je voor iedere quote een \' te zien in plaats van het normale quote teken.
Het is mogelijk om (b.v.) plaatjes op te slaan in MySQL. Of het slim is is een andere vraag. Veel beter is het om de plaatjes een logische benaming te geven (product_id) en een kleine functie in je code te zetten die kijkt of een bepaald plaatje in een bepaalde directory aanwezig is. Dit heeft als voordeel dat je zelfs de url naar die plaatjes niet in de database hoeft op te slaan.
Om te kijken of het plaatje aanwezig is maak je gebruik van de file_exists() functie:
<?php
/*
Zet een connectie naar de database op en voer de gewenste
query uit.Je kan dan een variabele aanmaken ($product_id)
waarin je het gewenste recordnr van het product dumpt. Daarna
voer je de volgende check uit.
*/
if (file_exists("/path/$product_id.jpg")){
echo "<img src=\"/path/$product_id\" border=0
alt=\"$row[product_omschrijving]\">;
}
?>
Hiervoor moet je de limit functie gebruiken. Voorbeeld:
<?php
/*
Connectie is al gemaakt. Via de parameter $start weten we op
welke plek in de resultset we de limit moeten laten starten, als
$start leeg is weten we dat we op 0 moeten beginnen. $view is het
totaal aantal records dat we willen tonen
*/
$view = 5;
$query = "SELECT * FROM tabela WHERE conditie = 'blauw'";
$result = mysql("database", $query);
/*
Om te weten hoeveel records er in de resultset zitten vragen
we eerst het aantal rijen op.
*/
$total = mysql_num_rows($result);
/*
We weten nu dat er bijvoorbeeld 45 records in zitten. We vullen
dan de query aan met de limitfunctie zodat we de volgende X
records kunnen opvragen.
*/
$query .= " limit $start, $view";
/*
We runnen de query nog een keer.
*/
$result = mysql("database", $query);
/*
We hebben nu een resultset met 5 records die beginnen op
$start. Je kan het tonen door een simpele lus.
*/
while ($row=mysql_fetch_array($result)){
echo $row[veldnaam];
}
?>
Als laatste zou je dan nog een volgende/vorige pagina functie kunnen bouwen door naar het totaal aantal records te kunnen kijken in samenhang met de $start en $view.
Er zijn op het internet diverse kant en klare oplossingen te vinden. Men hoeft alleen de configuratie aan te passen en de scripts te installeren.
Sessions maken het mogelijk om variabelen te gebruiken binnen een hele website. Op het moment dat een bezoeker een site bezoekt kan je een sessie id opvragen. Zo'n id is een uniek nummer. Het unieke nr komt te vervallen op het moment dat de bezoeker de browser zal afsluiten. Je kan met sessions werken via een cookie of via de session_id in de url. De onderstaande voorbeelden gaan uit van een cookie.
Om variabelen mee te geven in een session moet je eerst de variabele de gewenste waarde geven. Daarna moet je die sessie nog een keer registreren:
<?php
/*
Session starten.
*/
session_start();
/*
Zet de waarde in de variabele.
*/
$log = "Dit is de waarde die ik wil meegeven";
/*
Registreer de session
*/
session_register("log");
?>
PHP maakt aan de hand van de bovenstaande code een bestandje aan in de /tmp directory met als bestandsnaam het session_id. In het bestand worden alle variabelen opgeslagen. Hierna kan je in elke willekeurige php pagina (zolang die session nog intact is) de waarde $log opvragen:
<?php
session_start();
session_register("log");
echo $log;
?>
Echo is geen functie maar een commando, je gebruikt het om strings waarmee je geen aparte bewerkingen hoeft uit te voeren op het scherm te zetten:
<?php
echo "Hello World";
?>
Met print heb je iets meer mogelijkheden dan met echo. Zo kan je bijvoorbeeld op meerdere regels printen zonder gebruik te maken van <br> en/of "\n".
Printf geeft je de mogelijkheid om een formatted output te genereren.
Voor het samenvoegen van string gebruik je een . (eventueel in combinatie met een = teken):
<?php
$a = "foo";
$b = "bar";
$c = $a . $b;
/*
Gebruik van het = teken.
*/
$a = "foo";
$a .= " bar";
?>
Je kan heel snel een gedeelte van een string vervangen. Je gebruikt daarvoor de ereg_replace() functie voor:
<?php
$a = "Dit is de orginele string";
$b = ereg_replace( " is", " was", $a );
?>
Afhankelijk van de http server waarop PHP staat zijn er diverse manieren om php code op te nemen in je bestanden. In de meeste gevallen zullen de bestanden een aparte extensie hebben. Dit kan afhankelijk van de PHP versie variëren in o.a. phtml, php3 en php.
De code kan op elke willekeurige plek in een bestand worden opgenomen. Dit doe je d.m.v. openings en sluit tags:
<?php
/*
Hiertussen kan je de php code opnemen.
*/
?>
Het is gebruikelijk om commentaar regels op te nemen in de C programmeer style. Normaal gesproken neem je geen code op in een document als het onzinnig is om het door php te laten parsen. Dit doe je dan gewoon in html.
Het is mogelijk om bestanden te includen. Dit is vooral handig als je code schrijft die je in meerdere bestanden wilt aanroepen. Op die manier kan je de code overzichtelijk houden. Je kan hiervoor het include of het require commando gebruiken. Het grote verschil tussen deze twee commando's zit hem hierin dat het include commando waarden kan teruggeven. Om een bestand te includen ga je als volgt te werk:
<?php
include ("/path/bestand.php");
?>
Je kan in de php.ini een default plek aangeven voor bestanden die je wilt includen zodat je alleen de bestandsnaam hoeft aan te roepen. Je kan ze natuurlijk ook op een logische plek op de webserver neerzetten. Zorg in dat laatste geval wel dat je de bestanden een extensie geeft die wordt geparsed door de PHP interpreter zodat mensen niet de inhoud van die bestanden kunnen lezen. Ook is het verstandig om een disallow op te nemen voor zo'n directory in je robots.txt zodat de bestanden niet worden geïndexeerd door zoekmachines.
Als je gebruik maakt van de standaard packages voor het installeren van PHP dan zit daar vaak geen support voor MySQL bij in. Je zult de source zelf moeten compileren.
Er zit een vervelende bug in de PHP4 (beta4) configuratie. In de php.ini kan je het path aangeven naar sendmail. Standaard is die regel leeg in de eerdere versies. Als je het leeg laat in de php.ini kan PHP het path niet vinden. De oplossing is heel eenvoudig. Zet een ; voor de regel, PHP gebruikt dan de default instellingen.
Om gegevens te bewerken, verwijderen en op te vragen uit MySQL maak je gebruik van SQL, oftwel Structured Query Language. Dit is een taal die in veel database(servers) voor handen is. De SQL die gebruikt wordt zal verschillen per databaseserver.
Om gegevens op te vragen in MySQL maak je gebruik van het SELECT statement. In combinatie met een paar eventuele voorwaardes kan je precies de gegevens opvragen die je nodig hebt. We gaan nu even uit van een database met twee tabellen. Samen vormen ze een database waarin links en omschrijvingen van programma's staan. De database naam is internet en de tabelnamen zijn link_soort en links:
$mysql -u guest -p internet
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 19 to server version: 3.23.1-alpha
Type 'help' for help.
mysql>
We kunnen nu eerst eens gaan bekijken welke velden er in de tabellen staan:
mysql> show fields from links;
+------------+--------------+------+-----+---------+----------------+----------------------+
| Field | Type | Null | Key | Default | Extra | Privileges |
+------------+--------------+------+-----+---------+----------------+----------------------+
| id | int(11) | | PRI | NULL | auto_increment | select,insert,update |
| url | varchar(255) | | MUL | | | select,insert,update |
| url_naam | varchar(255) | YES | | NULL | | select,insert,update |
| license | varchar(60) | YES | | NULL | | select,insert,update |
| discript | tinyblob | YES | | NULL | | select,insert,update |
| link_soort | int(11) | | | 0 | | select,insert,update |
+------------+--------------+------+-----+---------+----------------+----------------------+
mysql> show fields from link_soort;
+-------+-------------+------+-----+---------+----------------+----------------------+
| Field | Type | Null | Key | Default | Extra | Privileges |
+-------+-------------+------+-----+---------+----------------+----------------------+
| id | int(11) | | PRI | NULL | auto_increment | select,insert,update |
| naam | varchar(50) | YES | | NULL | | select,insert,update |
+-------+-------------+------+-----+---------+----------------+----------------------+
Op die manier krijg je een overzicht van de velden, rechten en veldtypes die er in de database staan. Om nu alle velden uit de link_soort tabel te selecteren gebruik je de volgende code:
mysql> select * from link_soort;
+----+---------------------------+
| id | naam |
+----+---------------------------+
| 33 | security_sites |
| 31 | w-managers |
| 32 | wm-tools |
.................
Je ziet dat er een hele rij gegevens te voorschijn komen die bestaan uit een id en een naam. Als je nu alleen wilt weten hoeveel records er in die tabel staan dan kan je dat opvragen met COUNT:
mysql> select count(id) from link_soort;
+-----------+
| count(id) |
+-----------+
| 51 |
+-----------+
Als je nu gegevens wilt toevoegen aan deze tabel dan kan je dat met het INSERT commando doen. Bij het opvragen van de tabel gegevens heb je kunnen zien dat het veld id een veld is dat de eigenschap auto_increment heeft. Je hoeft in dat geval dus geen eigenlijke waarde mee te geven voor dat veld als je een nieuw record wilt invoeren. Je gebruikt in dat geval de null waarde. MySQL zal zelf bekijken welk nummer er zal worden gebruikt voor het id:
mysql> insert into link_soort values (null, 'test');
Query OK, 1 row affected (0.13 sec)
Om het record te verwijderen kan je DELETE gebruiken. In dit voorbeeld zou het niet kunnen aangezien de gebruiker geen rechten heeft om records te verwijderen maar de syntax die iemand met voldoende rechten moet gebruiken is de volgende:
mysql> DELETE FROM link_soort WHERE naam = 'test';
Query OK, 1 row affected (0.02 sec)
Om site bezoekers gegevens uit een database te kunnen laten opvragen moet je bepaalde rechten toekennen. Dit is het snelste te realiseren in de mysql monitor. We gebruiken hiervoor het GRANT statement:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4 to server version: 3.23.1-alpha
Type 'help' for help.
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql>
Je kan ook gelijk vanaf de prompt de database selecteren die je wilt gebruiken, je doet dit vanaf de prompt door mysql aan te roepen met als argument de database die je wilt gebruiken:
$mysql mysql
Je kan de gebruiker verschillende rechten toekennen. De meest voorkomende rechten zijn SELECT, INSERT en UPDATE. Dit doe je op de volgende manier:
GRANT SELECT, INSERT ON gb.gb TO guest@localhost IDENTIFIED BY 'hallo';
We hebben de gebruiker guest nu rechten gegeven om records toe te voegen en te selecteren in de gb database waarbij hij alleen rechten heeft in de tabel gb. Dit alles kan alleen op de machine waarop MySQL staat. Het wachtwoord voor die gebruiker is hallo.
Mocht je de gebruiker nu ook UPDATE rechten willen geven en hij moet alles vanaf een andere machine kunnen doen dan gebruik je het volgende:
GRANT SELECT, INSERT, UPDATE ON gb.gb TO guest@domeinnaam IDENTIFIED BY 'hallo';
Mocht de database gb uit diverse tabellen bestaan waarop de gebruiker allemaal moet kunnen lezen, schrijven en aanpassen dan gebruik je de volgende syntax:
GRANT SELECT, INSERT, UPDATE ON gb.* TO guest@domeinnaam IDENTIFIED BY 'hallo';