PHP & MySQL gevorderd PHP & MySQL gevorderd Inhoudsopgave Inleiding! 4 Voorkennis voor PHP & SQL! 4 Database resources! 4 De werking van een PHP-module op een webserver! 5 Opbouw web-pages (php)! 6 MySQL! 7 Het beveiligen van phpMyAdmin! 7 De opbouw van een database! 8 PHP koppelen met een Database! 8 Gegevens uit een database opvragen! 10 Invoegen van records! 13 Formuliergegevens toevoegen aan een Database! 14 Query met WHERE en gegevens uit meerdere tabellen! 15 ORDER BY statement! 16 Update van records! 17 Verwijderen van records! 18 Meer PHP functies voor MySQL bewerkingen! 19 PHP security ! 21 Wachtwoord onleesbaar voor database- administrators! 21 Validatie op invoervelden.! 24 Capcha (no-robot invoer beveiliging)! 26 IP- highjacking! 27 Invoerveld beveiligingen tegen sql-injections.! 28 Sessies! 29 Sessie beveiliging! 29 Sessie-tijd! 31 Mailen met PHP! 32 Basis tekst e-mail verzenden! © 2011 32 2 PHP & MySQL gevorderd Een HTML-mail verzenden! 33 Een HTML-mail verzenden met een attachment! 34 PDFʼs maken met PHP! 38 Cookies! 38 Toepassingen! 41 Toepassing1: SQL – database koppeling! 41 Toepassing2: SQL – toevoegen van een tupel in een database! 41 Toepassing3: SQL – opvragen en beheren database gegevens! 42 Toepassing4: update tabelvelden vanuit een VIEW! 44 © 2011 3 PHP & MySQL gevorderd Inleiding Deze handleiding is een vervolg op basis en gevorderde PHP. De focus ligt volledig op de koppeling tussen PHP en een MySQL- database. Onderwerpen die aanbod komen zijn: hoe gegevens uit een MySQL-database gehaald kunnen worden, toegevoegd, geupdate en andere bewerkingen. De derde PHP-handleidingen geven een goede basis voor het toepassen van PHP met de juiste gereedschappen om zelf meer functionaliteit aan een website toe te voegen. Het vinden van de juiste, simpele en eenduidige code voor een behoefte blijft een combi van: zelf bedenken of vinden in ander (online) handleidingen of forums. Na de twee beschikbare handleidingen en de juiste drive, zal het zeker moeten lukken :-) Voorkennis voor PHP & SQL Ervaring hebben met inzicht in het volgende moeten hebben: · · · · HTML-code (en of XHTM). Gebruik en installatie van een webservers en een databases (bijv: Apache als web-server, MySQL als database of gecombineerd in: XAMPP of MAMP) Basiskennis van PHP. Basis SQL-statements (query- syntax en database begrippen) Database resources Om de PHP-code die in deze handleiding gebruikt word toe te passen is een database nodig. De eenvoudigste manier om dit te doen is door XAMPP of MAMP te installeren. Activeer naast Apache ook MySQL en maak hierin een database aan die benaderbaar is. De databasenaam moet bekend zijn, een gebruikersnaam en wachtwoord met uitsluitend de rechten die nodig zijn om de gewenste acties uit te kunnen voeren. Zie meer informatie hierover; zie materiaal over databases op ‘kerssies64.net’. Hier zijn ook exports te vinden van databases, die geïmporteerd kunnen worden in een eigen gemaakte database, waarna deze te gebruiken zijn om de gebruikte voorbeelden in deze handleiding uit te voeren uit te voeren. Door zelf databases met tabellen en content op te zetten wordt deze vaardigheid uiteraard verbeterd! © 2011 4 PHP & MySQL gevorderd De werking van een PHP-module op een webserver Ter opfrissing; PHP is een module die aan de server-kant werkt. De client krijgt uiteindelijk pure HTML-code toegestuurd waarmee een page wordt weergegeven. Hoe deze page tot stand is voor de client onzichtbaar. Hieronder staan wat gebeurt er als een php-webpagina wordt opvraagt door een client: 1. Aan de client zijde wordt een verzoek gedaan naar een (php)webpagina op een bepaalde webserver, bijvoorbeeld: www.kerssies64.net client 7. De ontvangen code wordt ontvangen door de client. In de browser wordt deze omgezet in een leesbare pagina 2. De webserver zoekt deze pagina op in z’n filesysteem. 6. Het resultaat van de php-module wordt samengevoegd met eventueel aanwezige html-code. Deze code wordt door de webserver verstuurd naar de client 3. Omdat het een .php pagina is, stuurt de webserver deze pagina naar de php-module. Deze module moet op de webserver zijn geïnstalleerd 4. De php-module benaderd een database en voert hierop acties uit en geeft evt waarden terug database webserver .php 5. De php-module voert het phpscript uit en geeft het resultaat terug aan de webserver php-module © 2011 5 PHP & MySQL gevorderd Opbouw web-pages (php) Bij het maken van uitgebreidere websites wordt al snel duidelijk dat het overzicht al snel zoek is. Bij pure HTML-websites alleen al kan het overzicht zoek raken. De eerste stap ter verbetering is regels afbreken en vaker enteren. Door gebruik te maken van tabs, wordt het overzicht nog beter. Zeker wanneer er consequent wordt ingesprongen per tag en een tab wordt terug genomen wanneer deze wordt gesloten. Een uitkomst is het scheiden van opmaak en html-code, wat met CSS gebeurt. Dit scheiden en overzichtelijk houden van code wordt steeds belangrijker. Zo kunnen bepaalde delen met includes in andere documenten worden gezet. Sessies moeten als eerste worden opgezet, en zo meer. Hieronder is een grafische weergave gegeven, als advies, hoe een phpdocument opgebouwd kan worden: <?php sessies starten variabelen instellen includes naar andere bronnen ?> <html> <head> <title> titel browser-tab </title> link favicon.ico META voor "description" META voor "keywords" link CSS-bestand tbv opmaak HTML </head> <?php Alle PHP-logica en berekeningen ?> <body> document opbouw en weergeven formulieren en content, evt dmv PHP-echo’s </body> </html> © 2011 6 PHP & MySQL gevorderd MySQL MySQL is het populairste open-source databasesystemen, omdat deze database vrij te installeren en te gebruiken is, stabiel is en een goede ondersteuning heeft. De MySQL database wordt zeer vaak gebruikt in combinatie met PHP. De gegevens die in MySQL worden opgeslagen in tabellen. Een tabel is verzameling van ingevoerde gegevens die bestaan uit kolommen en rijen. Elke rij is een unieke set informatie die is opgebouwd uit meerdere kolomen elk met specifieke gegevens. De databases zijn handig voor het opslaan van informatie in categorieën. Een bedrijf zou een database kunnen hebben met de volgende tabellen: “Werknemers”, “Producten”, “Klanten” en “Orders”. Het beveiligen van phpMyAdmin Tijdens de ontwikkeling van een website met daaronder een MySQL-database is het handig om de testomgeving op het locale-systeem te beveiligen. Als dit niet wordt gedaan, dan kan iedereen binnen het lokale-netwerk (LAN) de database benaderen en daarin wijzigingen maken. Dit komt door: Het beheer van de database gebeurt namelijk altijd met phpMyAdmin phpMyAdmin heeft een standaard login en geen wachtwoord Netwerk scanners kunnen up IP-adres vinden en zien dat er een webserver actief is en de database benaderen. (http://<ip-adres>/phpmyadmin , ) De phpMyAdmin beveiligen kan als volgt: Maak een nieuwe gebruiker aan bij ‘Rechten’ en geef die volledige toegang (ALL PRIVILEGES) Open config.inc.php in de XAMPP-map Zoek de volgende regels, of voeg ze toe: $cfg['blowfish_secret'] = $cfg['PmaAbsoluteUri'] = $cfg['Servers'][$i]['auth_type'] = $cfg['Servers'][$i]['user'] = $cfg['Servers'][$i]['password'] = $cfg['Servers'][$i]['AllowNoPassword'] = 'wachtwoord'; ‘http://127.0.0.1/phpmyadmin/'; 'cookie'; 'gebruikersnaam'; 'wachtwoord'; false; Uiteraard moeten de eigen gegevens tussen de quotes komen. © 2011 7 PHP & MySQL gevorderd De opbouw van een database Een database bevat altijd één, maar mestal meerdere tabellen. Elke tabel moet en naam hebben (b.v. “Klanten” of “Orders”). De tabellen bevatten records (rijen) met gegevens. Hieronder is een voorbeeld van een tabel genoemd “Personen”: ID achternaam 1 Pietersen 2 Kracht 4 Steijn tussenv van voornaam adres hnr plaats Hans Doorweg 100 Zwolle Jip Straatlaan 3 Zwolle Janneke Hobbelpad 28 Amersfoort De tabel bevat hierboven drie records (voor elke contactpersoon) zijn zes kolommen (AchterNaam, Tussen, VoorNaam, Adres, Nummer en Stad). Meer over de opbouw en constructie van databases is te vinden in de kerssies64.net readers ”databases en SQL”, of andere (online) handleidingen. PHP koppelen met een Database Het maken van een koppeling met een database is de minimale vereiste om met PHP (of een andere taal) bewerkingen uit te voeren of vragen aan een database te stellen. In PHP, wordt de koppeling tussen het PHP- script en de database gedaan met de mysql_connect () functie. Syntaxis mysql_connect (servernaam, gebruikersbenaming, wachtwoord); Parameter Beschrijving servernaam Optioneel; Specificeert de server om te verbinden met. De standaard waarde is “localhost: 3306” Optioneel; Specificeert de gebruikersbenaming om het programma te openen. De standaardwaarde is de gebruiker die rechten heeft op het serverproces Optioneel; Specificeert het wachtwoord om in te loggen op de database. Standaard is: “” . login wachtwoord Tip: Er zijn meer beschikbare parameters, maar de hierboven vermelde zijn het belangrijkst. Voor meer details wordt verwezen naar andere (online) materiaal. © 2011 8 PHP & MySQL gevorderd Het is verstandig meerdere gebruikers op de database aan te maken, zodat afhankelijk van de ingelogde gebruiker gespecificeerde database rechten beschikbaar komen. Bijvoorbeeld: · · · · een administrator met alle rechten een administrator met alle rechten als reserve (wordt allen in nood gebruikt) een hoofdgebruiker waarmee online beheer op de database wordt uitgevoerd gebruiker(s) met beperkte rechten die afhankelijk van hun profiel gespecificeerde rechten op de database hebben De kerssies64.net site bevat enkele geëxporteerde tabellen die in een eigen database geïmporteerd kunnen worden, waarna de PHP-script code direct uitgevoerd kan worden. Let op dat de server, de databasenaam, het login en wachtwoord anders kunnen zijn... Voorbeeld: In het volgende voorbeeld slaat de koppeling in een variabele ($con) voor recenter gebruik in het script op. Het “die” gedeelte zal worden uitgevoerd als de koppeling niet opgebouwd kan worden: <html> <?php $con = mysql_connect('localhost',"login","ww"); //host kan ook IP-adres bevatten bijv: 127.0.0.1, of 10.0.2.100 if (!$con) { die('Geen connectie kunnen maken: ' . mysql_error()); } // eigen code else { echo 'connectie opgebouwd'; } mysql_close($con); //verbinding wordt gesloten met de database ?> </html> Bij de servernaam wordt hier “localhost” gebruikt, maar dit is afhankelijk van de servernaam waarop de database is opgestart. In plaats van een naam kan er ook een IP-adres worden gebruikt. “Localhost” heeft altijd IP-adres 127.0.0.1, dit werkt gewoon. Net als elke ander IP-adres waar een server met database actief is, mits de poorten in de firewall open staan ;-). Een koppeling met een database zal automatisch worden gesloten wanneer het script beëindigt. Om de koppeling eerder te sluiten, gebruik dan de mysql_close () functie. © 2011 9 PHP & MySQL gevorderd Gegevens uit een database opvragen Een query is een vraag of een verzoek om gegevens uit een database. Met MySQL, kunnen specifieke gegevens worden opgevraagd en een recordset met gewenste informatie terug geven. Een voorbeeld van een simpele SQL- query: SELECT AchterNaam FROM Gebruikers De vraag selecteert hierboven alle gegevens in de kolom “AchterNaam” uit de tabel “Gebruikers” en kan een recordset zoals hieronder terug geven: AchterNaam Moes Blijvers Zetters Syntaxis SELECTEER kolom_naam FROM tabel_naam Om PHP het SQL- statement uit te laten voeren is de functie: mysql_query () nodig. Deze functie wordt gebruikt om een query of een opdracht naar een MySQL- koppeling te verzenden. Voorbeeld: <?php $con = mysql_connect('localhost',"login","ww"); if (!$con) { die('Geen koppeling met de database: ' . mysql_error()); } else { echo 'connectie opgebouwd <br><br>'; mysql_select_db('PHPsql', $con); //selecteerd de database $resultaat = mysql_query("SELECT * FROM Gebruikers"); //zet query resultaat in een PHP-array while($row = mysql_fetch_array($resultaat)) { echo $row["VoorNaam"] . " " . $row["AchterNaam"]; echo '<br />'; //voor elke record in de php-array wordt een regel gemaakt. } } mysql_close($con); ?> © 2011 10 PHP & MySQL gevorderd Het voorbeeld slaat hierboven de gegevens op die door de functie mysql_query () zijn teruggekeerd in de variabele $resultaat. Daarna wordt mysql_fetch_array () functie gebruikt om de eerste rij van recordset als een array terug te geven. Elke vraag aan mysql_fetch_array () geeft de volgende rij in recordset. De whileloop loop door alle records in recordset om de waarden van elke rij te printen. Hiervoor wordt de $row variabele gebruikt: $row [“FirstName”] en: $row [“AchterNaam”]. Op het scherm wordt als uitkomst weergegeven: connectie opgebouwd Hans Pietersen Jip Kracht Janneke Steijn Natuurlijk kunnen de gegevens ook in een HTML- tabel worden weergegeven. Zie hiervoor PHPbasis materiaal van kerssies64.net. © 2011 11 PHP & MySQL gevorderd Syntaxen voor SQL-statements <? $con = mysql_connect (“localhost”, “login”, “ww”); if (! $con) { die (“kon niet verbinden met: “. mysql_error ()); } mysql_select_db (“my_db”, $con); $resultaat = mysql_query (“<SQL-STATEMENT>"); while ($row = mysql_fetch_array ($resultaat)) { echo $row [“ <Kolom1> “]. “ “. $row [“<Kolom2>“]; echo “<br/>“; } ?> <? $con = mysql_connect (“localhost”, “login”, “ww”); if (! $con) { die (“kon niet verbinden met: “. mysql_error ()); } mysql_select_db (“my_db”, $con); $resultaat = mysql_query (“<SQL-STATEMENT>“); while ($row = mysql_fetch_array ($resultaat)) { echo $row [“<Kolom1>“]; echo “ “. $row [“<Kolom2>“]; echo “ “. $row [“<Kolom3>“]; echo “<br/>“; } mysql_close ($con); ?> TIP: Zet alle queries in één bestand en geef elke query een eigen variabele. Doormiddel van een include per web- page zijn alle variabelen queries beschikbaar. Bij wijzigingen in de database staan alle query bij elkaar, dit is makkelijker te beheren. TIP: Echo uit te voeren queries en probeer deze uit direct in de MySQL- database. Zo is het eenvoudig te controleren of een query wel correct is uitgewerkt. © 2011 12 PHP & MySQL gevorderd Invoegen van records Het INSERT INTOTO statement wordt gebruikt om nieuwe records aan een tabel toe te voegen in een aangegeven tabel. Syntaxis Het is mogelijk om het INSERT INTO statement op twee manieren te gebruiken. De eerste vorm specificeert niet de kolomnamen waarin de gegevens worden geplaatst, dus alleen de waarden worden genoemd in de juiste kolomvolgorde: INSERT INTO tabel_naam VALUES (Waarde1, Waarde2, Waarde3,…) De waarden worden ook op de zelfde volgorde in de kolommen geplaatst, deze vorm van invoeren wordt veel gebruikt wanneer altijd alle kolommen een waarde moeten hebben. De tweede vorm specificeert zowel de op te nemen kolomnamen als de waarden: INSERT INTO tabel_naam (kolom1, kolom2, kolom4,…) VALUES (Waarde1, Waarde2, waarde4,…) Om PHP deze sql- statements uit te laten voeren moet de mysql_query () functie gebruiken worden. Voorbeeld: In de tabel “Gebruikers” worden de kolommen: “VoorNaam”, “AchterNaam” en “Plaats” gevuld. Het volgende voorbeeld voegt twee nieuwe records toe aan de tabel “Gebruikers”: <? $con = mysql_connect (“localhost”, “login”, “ww”); if (! $con) { die (“kon niet verbinden met: “. mysql_error ()); } mysql_select_db (“PHPsql”, $con); mysql_query (“INSERT INTO Gebruikers (VoorNaam, AchterNaam, Plaats) VALUES (“Piet”, “Koetsier”, “Rotterdam”)”); mysql_query (“INSERT INTO Gebruikers (VoorNaam, AchterNaam, Plaats) VALUES (“Glenn”, “Azar”,”Naarden”)”); mysql_close ($con); ?> © 2011 13 PHP & MySQL gevorderd Formuliergegevens toevoegen aan een Database Doormiddel van een HTML –formulier worden de kolommen van een nieuw record gevult. Daarnaast wordt één veld gevuld door middel van ‘autoincrement’ van MySQL en één veld wordt gevuld met een waarde uit een variabele. Het HTML-formulier: <html> <head> <title>Invoegen Gebruiker</title> </head> <body> <form action="invoegen.php" method="post"> Voornaam: <input type="text" name="VoorNaam"> Tussen: <input type="text" name="Tussen"> Achternaam: <input type="text" name="AchterNaam"><br> Adres: <input type="text" name="Adres" /><input type="text" name="HuisNr"><br> Plaats: <input type="text" name="Plaats"><br> <input type="submit" /> </form> </body> </html> Het bestand “invoegen.php” verbindt zich met een server en daarna met een database. De mysql_query () functie bevat een variabele met daarin het INSERT INTO statement, en zal de gegevens uit het formulier toevoegen. Hier is de pagina “invoegen.php”: <html> <title>Voer gegevens in </title> <body> <?php $con = mysql_connect ('localhost',"login","ww"); // koppeling met de database-server, gebruikersnaam en wachtwoord if (! $con) { die ('kon niet verbinden met: '. mysql_error ()); } echo 'OK, er is een verbinding <br>'; mysql_select_db ('PHPsql', $con); // PHPsql is de naam van de MySQL-database echo 'OK, de database is geselecteerd <br>'; $MemberDatum = date("y-m-d"); // datum wanneer een gebruiker is toegevoegd. echo 'Waarde nieuw record '.$MemberDatum.'<br>'; © 2011 14 PHP & MySQL gevorderd // ID in de tabel is 'autoincrement' en wordt automatisch door MySQL opgehoogd. $sql = "INSERT INTO Gebruikers (MemberDatum, AchterNaam, Tussen, VoorNaam, Adres, HuisNr, Plaats) VALUES ('$MemberDatum','$_POST[AchterNaam]', '$_POST[Tussen]', '$_POST[VoorNaam]', '$_POST[Adres]', '$_POST[HuisNr]', '$_POST[Plaats]')"; mysql_query ($sql,$con); // Tabelnaam en alle genoemde kolom-namen waarin de waarden vervolgens worden geplaatst if (! $con) { echo "error";} else { echo "1 record toegevoegd"; } mysql_close ($con); ?> </html> Query met WHERE en gegevens uit meerdere tabellen Syntax SELECT kolom(en) FROM tabel_naam WHERE kolom(en) en operator waarde AND tabel1.kolom-x = tabel2.kolom-x Voorbeeld: <?php $con = mysql_connect("localhost","login","ww"); if (!$con) { die('Geen verbinding met de database: ' . mysql_error()); } mysql_select_db("PHPsql", $con); $sql = "SELECT AchterNaam, User, WachtWoord FROM Gebruikers, Login WHERE VoorNaam= ‘Hans’ AND Gebruikers.ID = Login.ID”; $resultaat = mysql_query($sql) while($row = mysql_fetch_array($resultaat)) { echo $row['AchterNaam'] . " " . $row[User] . " " . $row[WachtWoord]; echo "<br />"; } ?> © 2011 15 PHP & MySQL gevorderd ORDER BY statement Syntax SELECT kolom(en) FROM tabel_naam ORDER BY kolom(en) ASC|DESC <?php $con = mysql_connect("localhost","login","ww"); if (!$con) { die('Geen verbinding met de database: ' . mysql_error()); } mysql_select_db("PHPsql", $con); $sql = “SELECT AchterNaam, VoorNaam FROM Gebruikers WHERE Plaats = 'Zwolle' ORDER BY AchterNaam DESC”; $resultaat = mysql_query($sql); while($row = mysql_fetch_array($resultaat)) { echo $row['AchterNaam'] . " " . $row[VoorNaam]; echo "<br />"; } ?> © 2011 16 PHP & MySQL gevorderd Update van records De statement UPDATE wordt gebruikt om gegevens in een record van een tabel te wijzigen. Syntaxis UPDATE tabel_naam UPDATE kolom1=VALUES, kolom2=VALUES2,… WHERE een_kolom=een_VALUES Tip: Merk op dat de WHERE clausule in de syntaxis bij het UPDATE statement. WHERE specificeert welk record moeten worden bijgewerkt. Wordt de WHERE weglaten, dan zullen alle records worden bijgewerkt! Voorbeeld: Het volgende voorbeeld werkt sommige gegevens in de tabel van “Personen bij”: <? $con = mysql_connect ("localhost", "login", "ww"); if (! $con) { die ('kon niet verbinden: '. mysql_error ()); } mysql_select_db ("PHPsql", $con); mysql_query ("UPDATE Gebruikers SET Plaats = 'Groningen' WHERE VoorNaam = 'Hans' AND AchterNaam = 'Pietersen'"); echo 'update van record uitgevoerd'; mysql_close ($con); ?> © 2011 17 PHP & MySQL gevorderd Verwijderen van records Het DELETE statement wordt gebruikt om records uit een tabel te verwijderen. Syntaxis DELETE FROM tabel_naam WHERE enkele_ kolom= enkele_WAARDEN Tip: Merk op dat de WHERE clausule in de syntaxis bij het DELETE statement. WHERE specificeert welk record moeten worden verwijdert. Wordt WHERE weglaten, dan zullen alle records worden verwijdert! Het volgende voorbeeld verwijdert alle records in de tabel van “Gebruikers” waar AchterNaam “Pietersen” is: <? $con = mysql_connect ("localhost", "test", "test"); if (! $con) { die ("kon niet verbinden: ". mysql_error ()); } mysql_select_db ("PHPsql", $con); mysql_query ("DELETE FROM Gebruikers WHERE AchterNaam='Pietersen'"); echo "record verwijderd <br>" mysql_close ($con); ?> © 2011 18 PHP & MySQL gevorderd Meer PHP functies voor MySQL bewerkingen (engelse uitleg) Functie Beschrijving mysql_affected_rows() mysql_close() Returns the number of affected rows in the previous MySQL operation Deprecated. Changes the user of the current MySQL connection Returns the name of the character set for the current connection Closes a non-persistent MySQL connection mysql_connect() Opens a non-persistent MySQL connection mysql_create_db() Deprecated. Creates a new MySQL database. Use mysql_query() instead Moves the record pointer mysql_change_user() mysql_client_encoding() mysql_data_seek() mysql_db_name() mysql_db_query() mysql_drop_db() mysql_errno() mysql_error() mysql_escape_string() mysql_fetch_array() mysql_fetch_assoc() mysql_fetch_field() Returns a database name from a call to mysql_list_dbs() Deprecated. Sends a MySQL query. Use mysql_select_db() and mysql_query() instead Deprecated. Deletes a MySQL database. Use mysql_query() instead Returns the error number of the last MySQL operation Returns the error description of the last MySQL operation Deprecated. Escapes a string for use in a mysql_query. Use mysql_real_escape_string() instead Returns a row from a recordset as an associative array and/or a numeric array Returns a row from a recordset as an associative array Returns column info from a recordset as an object mysql_fetch_object() Returns the length of the contents of each field in a result row Returns a row from a recordset as an object mysql_fetch_row() Returns a row from a recordset as a numeric array mysql_field_flags() mysql_field_len() Returns the flags associated with a field in a recordset Returns the maximum length of a field in a recordset mysql_field_name() Returns the name of a field in a recordset mysql_field_seek() Moves the result pointer to a specified field mysql_field_table() Returns the name of the table the specified field is in mysql_field_type() Returns the type of a field in a recordset mysql_free_result() Free result memory mysql_get_client_info() Returns MySQL client info mysql_get_host_info() Returns MySQL host info mysql_get_proto_info() Returns MySQL protocol info mysql_get_server_info() Returns MySQL server info mysql_info() Returns information about the last query mysql_insert_id() Returns the AUTO_INCREMENT ID generated from the previous INSERT operation mysql_fetch_lengths() © 2011 19 PHP & MySQL gevorderd mysql_list_dbs() Lists available databases on a MySQL server mysql_list_fields() Deprecated. Lists MySQL table fields. Use mysql_query() instead Lists MySQL processes mysql_list_processes() mysql_num_fields() Deprecated. Lists tables in a MySQL database. Use mysql_query() instead Returns the number of fields in a recordset mysql_num_rows() Returns the number of rows in a recordset mysql_pconnect() Opens a persistent MySQL connection mysql_ping() mysql_query() Pings a server connection or reconnects if there is no connection Executes a query on a MySQL database mysql_real_escape_string() Escapes a string for use in SQL statements mysql_result() Returns the value of a field in a recordset mysql_select_db() Sets the active MySQL database mysql_stat() Returns the current system status of the MySQL server Deprecated. Returns the table name of field. Use mysql_query() instead Returns the current thread ID mysql_list_tables() mysql_tablename() mysql_thread_id() mysql_unbuffered_query() © 2011 Executes a query on a MySQL database (without fetching / buffering the result) 20 PHP & MySQL gevorderd PHP security Beveiliging van de database is erg belangrijk, er staan namelijk allerlei belangrijke gegevens in zoals: gebruikersnamen, wachtwoorden, adresgegevens, mail- adressen, rekeningnummers/ creditcardnummers, etc. Wachtwoord onleesbaar voor database- administrators Met dit onderdeel worden enkele mogelijkheden getoond waarmee gegevens geverifieerd kunnen worden of worden versleuteling worden opgeslagen in de database. Een database- administrator heeft dan wel toegang tot de database, maar kan gegevens niet lezen, zoals bijvoorbeeld een wachtwoord. Zo is het mogelijk strings en bestanden te coderen. Maar ook om aangeboden bestanden te controleren of ze wel een origineel zijn van de aanbieder. Encryptie mogelijkheden zijn: Functie Beschrijving crc32() crc32(string) Berekend een 32-bit CRC (cyclisch redundantie checksum) voor een string crypt(string,moeilijkheid) de moeilijkheid is standaard 1, de hoger het cijfer, de moeilijker te kraken str_rot13(string) Het coderen met ROT13 verplaatst elke karakter 13 plaatsen in het alfabet. De numerieke en nietalfabetische karakters blijft staan. sha1(string,raw) sha1 op een string crypt() str_rot13() sha1() Optie: Specifcaties voor hex of binary output formaat: • TRUE - exacte 20 character binary format • FALSE - standaard. 40 character hex number sha1_file() md5() md5_file() sha1_file(bestand,raw) Sha1 op een bestand. $bestand = "voorbeeld.txt"; $sha1B = sha1_file($bestand); md5(string,raw) Berekend de MD5 hash van een string Optie: • TRUE - Raw 16 karakter binary formaat • FALSE - Standaard. 32 karakter hex nummer md5_file(file,raw) Berekend de MD5 hash van een bestand CRC32 op een string: © 2011 21 PHP & MySQL gevorderd <html> <?php $string = crc32("Kerssies 64"); // het verschil met of zonder %u ligt in de spatie echo 'zonder %u: '.$string."<br />"; echo 'met %u: '; printf("%u",$string); ?> </html> Het resultaat, de verschillen liggen in de speciale tekens in een string: zonder %u: -1712303409 met %u: 2582663887 MD5 toegepast op een string: <html> <?php $str = "Hello"; echo md5($str); ?> </html> Het MD5 resultaat: 8b1a9953c4611296a827abf8c47804d7 Door gebruik te maken van encryptie kunnen gegevens gecodeerd worden bewaard in een tekstbestand of database. Gebruikers en (sub)beheerders kunnen dan gevoelige informatie, zoals wachtwoorden of privé gevoelige data, niet zomaar lezen... © 2011 22 PHP & MySQL gevorderd Verschillende coderingen en encryptie toegepast: <html> <?php if (CRYPT_STD_DES == 1) { echo "Standard DES: ".crypt("kerssies64.net applying knowlegde")."\n<br />"; } else { echo "Standard DES wordt niet ondersteund.\n<br />"; } if (CRYPT_EXT_DES == 1) { echo "Extended DES: ".crypt("kerssies64.net applying knowlegde ")."\n<br />"; } else { echo "Extended DES wordt niet ondersteund.\n<br />"; } if (CRYPT_MD5 == 1) { echo "MD5: ".crypt("kerssies64.net applying knowlegde ")."\n<br />"; } else { echo "MD5 wordt niet ondersteund.\n<br />"; } if (CRYPT_BLOWFISH == 1) { echo "Blowfish: ".crypt("kerssies64.net applying knowlegde "); } else { echo "Blowfish DES wordt niet ondersteund."; } ?> </html> Het resultaat op basis van het operating systeem kan zijn: Standard DES: 8kGC9cr6g59Sg Extended DES: s65gP10pQ3tSs MD5 wordt niet ondersteund. Blowfish DES wordt niet ondersteund. © 2011 23 PHP & MySQL gevorderd Validatie op invoervelden. Lege invoervelden of incorrecte gegevens in een formulier zorgen ervoor dat er vervuiling van de database ontstaat. Door de ingevoerde gegevens aan een bepaalde opmaak te controleren wordt ervoor gezorgd dat alleen de juiste informatie in een query wordt gezet. De functie preg_match is hierbij erg handig. Wanneer de validatie van de voornaam niet klopt, dan wordt er een uitroepteken voor het invoerveld geplaatst. Dit staat in een tabel-cel zodat de uitlijning met eventuele regels daaronder intact blijft... Tevens wordt er de variabele $v_fouten opgehoogd als er een incorrecte validatie is waargenomen. Deze variabele kan weer worden gebruikt .... code .... <?php $v_fouten = 0; //startwaarde fouten bij validatie if (!preg_match ($vp_naam,$_POST['voornaam'])) { echo '<b><FONT COLOR="red">!</FONT><B>'; $v_fouten = $v_fouten+1; } ?> <INPUT TYPE="text" NAME="voornaam" value="<?php echo $_POST['voornaam'];?>" SIZE="25" MAXLENGTH="25"> ... meer code ... echo 'het aantal validatie fouten bij de invoer is: '. $v_fouten; if(isset($_POST[bewaar]) && $v_fouten != 0 ) {} elseif (isset($_POST[bewaar]) && $v_fouten == 0) { if ($_SESSION['profiel'] == 0 ) { $_SESSION['profiel'] = 1; } else ?> include ("SaveAccount.php"); // php script waar update query wordt uitgevoerd. } { echo '<br>er is een problemen, neem contact op met de beheerder'; } © 2011 24 PHP & MySQL gevorderd validatie.php, bevat diverse variabelen met validatie- strings voor preg_match. <?php //naam validatie $vp_naam = '/^[A-Z]{1}[A-Za-z -]{1,}+$/D'; //tussen $vp_tussen = '/^[a-z\-]{2,8}+$/D'; // ook "" akkoord //nummer $vp_nummer = '/^([0-9])+$/D'; // toevoegsel bij huisnummer van een adres // Toevoegsel $vp_toev = '/^([a-zA-Z-0-9]{1,3})+$/D'; // ook "" akkoord // nederlands postcode $vp_postcode ='/^[0-9]{4}+([a-z]{2}|[A-Z]{2})$/D'; //landsnaam validatie $vp_land ='/^[A-Z]{1}[a-z]{1,}$/D'; // ook "" akkoord //Huistelefoon $vp_telefoon ='/^(0[1-9]{2}\-[0-9]{7})|(0[1-9]{3}\-[0-9]{6})$/D'; // ook "" akkoord //mobiel nummer $vp_mobiel ='/^(0[0-9]{1}\-[0-9]{8})$/D'; // ook "" akkoord // email $vp_mail = '/^[a-zA-Z0-9&\.\-_]+@[a-zA-Z0-9\-_]+\.([a-zA-Z0-9\-]+\.)*+[a-z]{2,3}$/D'; // ook "" akkoord //datum $vp_datumEU = '/^0[1-9]{1}|1[0-9]{1}|2[0-9]{1}|3[01]{1}\-0[1-9]{1}|1[012]{1}\-19|20[0-9]{2}$/D'; $vp_datumEU2 = '00-00-0000'; $vp_datumUS = '/^19|20[0-9]{2}\-0[1-9]{1}|1[012]{1}\-0[1-9]{1}|1[0-9]{1}|2[0-9]{1}|3[01]{1}$/D'; //tijd $vp_tijd = '/^0[0-9]{1}|1[0-9]{1}|2[0-4]{1}[\:]0[0-9]{1}|1[0-9]{1}|2[0-9]{1}|3[0-9]{1}|4[0-9]{1}|5[0-9]{1}$/D'; //geldbedrag $vp_geld ='/^[0-9]{1,}.[0-9]{2}$/D'; // ook "" akkoord © 2011 25 PHP & MySQL gevorderd vervolg validatie.php // rekeningnummer IBAN voorbeeld: DE05.1002.0500.0003.2873.00 $vp_giroNr = '/^[0-9]{7}+$/D'; $vp_rekeningNr = '/^[0-9]{9}+$/D'; $vp_IBAN = '/^[A-Z]{2}[0-9]{2}+[\.-]+[0-9]{4}+[\.-]+[0-9]{4}+[\.-]+[0-9]{4}+[\.-]+[0-9]{4}+ [\.-]+[0-9]{2}+$/D'; // ook "" akkoord // gebruiker tbv accountnaam (minimaal 6 karakters) $vp_account = '/^[a-zA-Z0-9&\.\-_\+\!@#$%&]{6,}$/D'; // wachtwoord (minimaal 8 karakters) $vp_ww = '/^[a-zA-Z0-9&\.\-_\+\!@#$%&]{8,}$/D'; // memo (minimaal 2 karakters) $vp_memo= '/^[a-zA-Z0-9&\.\-_\+\!?%&]{2,}$/D'; ?> De validatie kan nog beter met look-forward en look-backward optiesin preg_match. Capcha (no-robot invoer beveiliging) Om te voorkomen dat robot’s ofwel computers allerlei combinaties los laten op invoervelden kan een capcha worden. Er wordt een willekeurige code ( aantal cijfers, letters of een combinatie) gegenereerd die de gebruiker moet intypen voordat hij verder mag. Grbruik van capcha’s worden vaak gebruikt bij: · · Vanaf een website e-mail versturen naar een gebruiker Een nieuw wachtwoord aanvragen Op het internet zijn gratis code-blokken te vinden die hier geschikt voor zijn. De kunst is om een gewenste uitvoervorm te vinden die tevens eenvoudig is in te voegen tussen de bestaande code. © 2011 26 PHP & MySQL gevorderd IP- highjacking Bij IP-highjacking maakt een hacker gebruik van sessie gegevens van een ingelogde gebruiker. Wat echter (meestal) ongelijk is is het IP-adres waarvandaan een hacker toegang verschaft tot de site. Door het IP-adres bij het inloggen in een sessie te zetten en deze te controleren met het IP-adres van de gebruiker die een web-page opend kan dit worden voorkomen. actie bij het inloggen: $_SESSION['remoteIPlogin'] = $_SERVER['REMOTE_ADDR']; // eerder opgeslagen ip gebruiker (normaal moeten deze waarde tijdens inloggen worden ingesteld) acties bij het openen van elke webpage (evt met een include toegoegen): <?php ini_set(display_errors, 0); // error niet weergegeven --> fout opnieuw sessie starten session_start(); if ( ) ?> mysql_real_escape_string($_SESSION['remoteIPlogin']) mysql_real_escape_string($_SERVER['REMOTE_ADDR']) != { session_destroy(); mysql_close($con); echo '<meta http-equiv="refresh" content="0; url= index.php">'; } © 2011 27 PHP & MySQL gevorderd Invoerveld beveiligingen tegen sql-injections. Bij capcha’s is al aanbod gekomen dat invoervelden een zwak punt zijn van een website met daar achter een database. Het is handig om de volgende tips in ieder geval op te volgen: Maximaliseer het aantal in te voeren karakters invoervelden door ‘maxlength’ te gebruiken. <input name="userName" size="15" maxlength =”20” type="text"> <br> <input name="passWord" size="8" maxlength =”8” type="password"> Ook is het mogelijk om gebruik te maken van zogenaamde “sql injections”, hierbij wordt er in een invoerveld code geplaatst waardoor er een stukje script tussen het originele script wordt gezet. De ‘geposte’ waarden (met code) worden in een query naar de database gestuurd en uitgevoerd. Het gevolg kan zijn dat er een query wordt uitgevoerd die gegevens of delen van de database bloot geeft. Gebruik daarvoor een escape-string, deze haal slahes, punt-komma’s en andere programmeercode karakters uit de geposte string. (oa / en ; ), waardoor de sql-injection zijn noodzakelijke karakters verliest. $wachtwoord = mysql_real_escape_string($_POST['wachtwoord']); of $wachtwoord © 2011 = addslashes($_POST['wachtwoord']); 28 PHP & MySQL gevorderd Sessies In sessie kunnen gegevens worden opgeslagen die later worden gebruikt in de web-site. Hiervoor moet helemaal in het begin wan een php-page het volgende stukje code staan. : <?php session_start(); Als er een web-pagina wordt geopend zonder deze functie, dan vervalt de sessie. Sessie beveiliging Door gebruik te maken van de sessies kan er een nieuw soort beveiliging worden toegepast op web-pages. Zonder deze techniek heeft inloggen geen enkele zin.Door in de browser-historie halen URL’s te benaderen of gewoon URL’s te proberen kan een gebruiker web-pages benaderen die niet gezien mogen worden, hoewel de link niet wordt weergegeven in een van de publiekelijk te benaderen webpages. Acties die per webpage ingesteld moeten zijn of worden: <?php ini_set(display_errors, 0); // error niet weergegeven --> fout opnieuw sessie starten session_start(); // initiatie - input tbv simulatie $_SESSION['profiel'] = 3; // profiel gebruiker instellen (normaal moeten deze waarde tijdens inloggen worden ingesteld) $level = 3; // welk profiel deze page mag zien (deze waarde voor elke page instellen op de page zelf) $pass $level = mysql_real_escape_string($_SESSION['profiel']); = mysql_real_escape_string($level); Controle of de gebruiker de webpage mag zien, dit wordt bepaald door de waarde van het profiel: level <=0; geen rechten level 1; toegang als gebruiker level 2; toegang als user level 3 overal toegang, admin level >=4; geen rechten © 2011 29 PHP & MySQL gevorderd Valt het profiel buiten de toegestane waarden of is het level om een web-page te zien hoger dan het profiel dat is ingelogd, dan wordt een andere web-page weergegeven. if ($pass != 0 && $pass != 1 && $pass != 2 && $pass != 3) { // voorkomt doorlaten van webpages door het intypen van URL's in de adresbalk van de browser // beveiliging: Lege profiel variabelen proberen pages te openen zonder in te loggen session_destroy(); mysql_close($con); echo '<meta http-equiv="refresh" content="0; url= NietToegestaan.html">'; } elseif ($pass < $level) { // gebruiker heeft geen rechten op pages hoger dan zijn eigen profiel echo '<meta http-equiv="refresh" content="0; url= NietToegestaan.html">'; } ?> <html> <body> <h2>Webpage </h2> Inhoud website </body> </html> © 2011 30 PHP & MySQL gevorderd Sessie-tijd Wanneer een gebruiker is ingelogd en wegloopt bij zijn website, dan kunnen onbevoegden gebruikmaken van functionaliteiten waartoe ze geen rechten hebben. Door een sessietijd in te stellen op de webserver of met php-code aan de site toe te voegen, zal de site na een ingestelde tijd uitloggen en de index-pagina weergeven. $aantal_min = 1; //minuten instellen $inactief = 60 * $aantal_min; // aantal minuten in seconden $nu = time(); $sessie_duur = $nu - $_SESSION['timeout']; echo 'sessie duur: '.$session_duur.'<br>'; echo 'sessie: '.time().' - '.$_SESSION['timeout'].' = '.$sessie_duur.'<br>'; echo 'inactief: '.$inactief.' seconden<br>';*/ // sessietijd als idle-tijd te lang is if(isset($_SESSION['timeout']) ) { $sessie_duur = time() - $_SESSION['timeout']; if($sessie_duur > $inactief) { session_destroy(); header("Location: sessietijdverkopen.html"); } // } <html> <body> <h2>Webpage </h2> <FORM METHOD="post" ACTION="index.php"> <I>klik voor herladen:</I> <INPUT TYPE="submit" VALUE="herladen"> </FORM> </body> </html> Onderaan de webpage wordt de huidige tijd (laatste actie) opnieuw in een sessie gezet: // huidige tijd in de sessie zetten $_SESSION['timeout']=time(); © 2011 31 PHP & MySQL gevorderd Mailen met PHP Basis tekst e-mail verzenden Met PHP is het mogelijk berichten via mail te versturen. Dit kan alleen als de webserver ook een maildienst (SMTP) heeft draaien. Een eenvoudig script om te mailen: ini_set ( 'SMTP' , ''smtp_server''); ini_set ( 'smtp_port' , ''smtp_poort''); $to = $subject = $txt = 'Beste gebruiker, //(optioneel) servernaam, bijv: mail.provider.nl // (optioneel) poort, meestal: 110 “[email protected]”; “Mail onderwerp”; Hier volgt de body van het mail bericht. Type gewoon enkele regels tekst, eventueel met daarin variabelen verwerkt. '.$mail_bericht['mailbody1'].' mvg, kerssies64.net ‘; $headers = 'From: beheerder <'.$array['mailadres'].'>'; mail($to,$subject,$txt,$headers); Uiteraard moet het e-mail adres waarnaar verstuur wordt kloppen, dit hoeft echter niet voor het mailadres waarvan het verstuurd wordt. Bedenk wel spammen is strafbaar!!! Denk bij e-mail adressen waar je vanaf verstuurd ook aan: [email protected] of [email protected] © 2011 32 PHP & MySQL gevorderd Een HTML-mail verzenden Wanneer een simpele mail met PHP verstuurd kan worden is het vrij eenvoudig om er een HTMLmailtje van de maken. Er worden de header krijgt andere inhoud en de boodschap bevat HTMLtags en opmaak. Hieronder is een simpel voorbeeld weergegeven: <html> <head> <title>html-mail</title> </head> <body bgcolor="#HBD9FF"> <?php if (isset($_POST[zend])) { $newLine = "\r\n"; $headers = "MIME-Version: 1.0" . $newLine; $headers .= "Content-type: text/html; charset=utf-8" . $newLine; $headers .= "From: blabla <[email protected]>" . $newLine; $to = $_POST[email]; $subject = "Test mail"; $message = '<html><body bgcolor = "grey">'; $message .= '<img height ="50" src="http://www.backups.nl/images/windows%20mail.png" /><hr>'; $message .= 'Hallo,<br>Bedankt voor uw reactie.<br>Uw gegevens zijn bewaard.<br>'; $message .= 'groet, de Beheerder<hr></body></html>'; mail($to,$subject,$message,$headers); ?> <script type="text/javascript"> <!-alert ("de html-mail is verstuurd \r\n<?php echo $_POST[email];?>" ) --> </script> <?php } ?> <form name="form1" method="post" action="index.php"> <div align="center"> <h1>html-mail versturen</h1><br /> <input name="email" type="text" value=""><br /> <input type="submit" name="zend" value="verstuur mail"> </div> </form> </body> </html> © 2011 33 PHP & MySQL gevorderd Een HTML-mail verzenden met een attachment Een werkende HTML-mailer kan eenvoudig worden uitgebouwd. Het voorbeeld hieronder upload bestanden naar een vaste map, waarna deze worden toegevoegd aan een HTML-mailtje. ook is er een prioriteiten veld aan toegevoegd. <html> <head> <title>html-mail + att</title> </head> <body bgcolor="#HBD9FF"> <?php // >> uploaden bestand naar map "upload" $targetfolder = "attachments/"; //uploadfolder bepalen (pad) $targetfolder = $targetfolder .basename( $_FILES['uploaded']['name']); $uploaded_size = filesize($_FILES['uploaded']['size']); $uploaded_type = filesize($_FILES['uploaded']['type']); $ok=1; // >> beperkingen uploads $max_mb = 5000; if (isset($_POST[upload]) && $uploaded_size > $max_mb) { // beperk bestands grootte echo "Het bestand is groter dan ".($maxMB/1000). "MB <br> Upload een kleiner bestand<br>"; $ok=0; } if (isset($_POST[upload]) && $uploaded_type == "text/php") // pregmatch op extentie { //Beperk het soort bestanden echo "PHP-bestanden mogen niet worden geupload<br>"; $ok=0; } if (isset($_POST[upload]) && $ok==0 ) { //Error-melding wanneer $ok == 0 echo "Het bestand voldoet niet aan de voorwaarden"; } else { //Er is voldaan aan upload-voorwaarden -> uploaden bestand if(move_uploaded_file($_FILES['uploaded']['tmp_name'], $targetfolder)) { echo "Het bestand <b>". basename( $_FILES['uploadedfile']['name']). "</b> is geupload naar de map"; } } unset($_POST[submit]); © 2011 34 PHP & MySQL gevorderd //Bekijk eerst de bronversie van een ontvangen e-mail in je mail-applicatie (mail-format) if (isset($_POST[zend])) { $newLine = PHP_EOL; //"\r\n" $separator = md5(time()); $prioriteit = $_POST['prioriteit']; // 1 of 0 $to = $_POST[email]; $subject = "Test mail"; $headers .= "From: blabla <[email protected]>".$newLine; if ($prioriteit == 1) { $headers .="X-Priority: 1" . $newLine. "Priority: Urgent" . $newLine. "Importance: high" . $newLine; // basis = 0 - Normal - normal } $headers .= "MIME-Version: 1.0".$newLine; $headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$newLine. $newLine; $headers .= "Content-Transfer-Encoding: 7bit".$newLine; $headers .= "This is a MIME encoded message.".$newLine.$newLine; // start header voor message $headers .= "--".$separator.$newLine; $headers .= "Content-type: text/html; charset=utf-8" . $newLine; $headers .= "Content-Transfer-Encoding: 8bit".$newLine.$newLine; // afbeeldingen (embedded) in message $source_file = "globe.png"; // link naar bestand $handle = fopen($source_file,'rb'); // b-flag om binary-bestanden toe te voegen, anders alleen tekst $file_content = fread($handle,filesize($source_file)); fclose($handle); $encoded = chunk_split(base64_encode($file_content)); $headers .= '<html><body bgcolor = "green">'; //$headers .= 'afb van een exteren link: <img height ="50" src="http://www.backups.nl/images/windows%20mail.png" /><hr>'; //$headers .= '<br>'; //$headers .= 'afb embedded met base64: <object type="image/png" data="data:image/png;base64,'.$encoded.'" width="150" height="150"/></OBJECT><hr>'; $headers .= '<br>'; $headers .= 'Hallo,<br> '.$_POST[mail_content].'<br>'. 'Bedankt voor uw reactie.<br><br> Er volgt nog een attachement...<br>'; $headers .= 'groet, de Beheerder<hr></body></html>'; $headers .= $newLine; © 2011 35 PHP & MySQL gevorderd // >>>> voe attachments uit map toe aan mail $path = 'attachments/'; $dir = scandir($path); // was "attachments" // print_r($dir); $aantal_files = count($dir); for ($i =0; $i < $aantal_files; $i++) { if ($dir[$i] != '.' && $dir[$i] != '..') { $full_path = $path.$dir[$i]; $size = filesize($full_path); $attach = fopen($full_path,"rb"); $data = fread($attach,$size); $attachment = chunk_split(base64_encode($data)); $headers .= $newLine."--".$separator.$newLine; $headers .= "Content-Transfer-Encoding: base64".$newLine; $headers .= 'Content-Disposition: attachment; filename="'.$dir[$i].'"; size='.$size.';'. $newLine.$newLine; //inline; $headers .= $attachment.$newLine.$newLine; } } if (mail($to,$subject,"",$headers)) { ?> <script type="text/javascript"> <!- alert ("de html-mail is verstuurd \r\n<?php echo $_POST[email];?>" ) --> </script> <?php } else { echo 'fout bij versturen mail'; } } ?> Hieronder wordt het formulier weergegeven om een mailtje met prioriteit te verzenden en attachemts toe te voegen. © 2011 36 PHP & MySQL gevorderd <!-- /////to = opmerking... ////// --> <form name="form1" method="post" action="index.php"> <div align="center"> <h1>html-mail versturen met attachements</h1> met upload naar folder<br /> <table> <tr> <td colspan="2"><input type="submit" name="zend" value="verstuur mail"> </td> </tr> <tr> <td>to<input name="email" type="text" size="42" value="<?php echo $_POST[email];? >"></td> <td><INPUT TYPE="checkbox" NAME="prioriteit" VALUE="1">prio</td> </tr> <tr> <td colspan ="2"width="200px" height="70px"> html-bericht<TEXTAREA name="mail_content" ROWS="4" COLS="50" wrap="hard" value="<?php echo $_POST[mail_content];?>" /> </TEXTAREA> </td> </tr> </form> <form enctype="multipart/form-data" action="index.php" method="POST"> <tr> <td><input name="uploaded" type="file" /></td> <td><input type="submit" name="upload" value="Upload" /></td> </tr> </form> <?php $dir = opendir("attachments"); //Lijst bestanden in aangegeven directory while ($file = readdir($dir)) { if ($file != '.' && $file != '..') { echo "<tr><td>filename: </td><td>" . $file . "</td></td>"; } } //closedir($dir); echo '<hr>'; ?> </table> </div> </body> </html> © 2011 37 PHP & MySQL gevorderd PDFʼs maken met PHP Soms wil je gegevens omzetten in een pdf-bestand. Hiervoor kan je naar FPDF (http://www.fpdf.org/) , daar staat php-code in een class (object georienteerd stukje php-code). Dit is aan te passen naar je eigen wensen. Er zitten drie stijlen van tabellen in de class, namelijk een eenvoudig-, nettere- en uitgebreidere-versie. Het aantal kolommen, breedtes en de kleuren zijn aan te passen. Uiteraard zijn er meerdere stukken php-code op het Internet te vinden die het zelfde kunnen bieden. Cookies Een cookie wordt vaak gebruikt om een gebruiker te identificeren. Een cookie is een klein bestandje dat de server op de computer van de gebruiker plaatst. Wanneer een browser om een webpagina vraagt, dan de server ook een cookie verzenden. Met PHP, kunnen cookie- waarden worden verstuurd en opgehaald. Als een gebruiker eenmaal is ingelogd, dan kunnen de login gegevens in een cookie op het cliëntsysteem worden opgeslagen. Bij een volgend bezoek kunnen de standaard waarden automatisch worden ingevuld met de waarden uit het cookie... Let o, cookies kunne privé gegevens bevatten en bij gebruik van onder andere publiekelijke PC’s is dit niet wenselijk. Een Cookie maken De setcookie () functie wordt gebruikt om een cookie te plaatsen. Tip: De setcookie () functie moet VOOR de <html>markering worden geplaatst. Syntaxis setcookie (naam, waarde, verloopt, pad, domein); © 2011 38 PHP & MySQL gevorderd Voorbeeld 1: In het voorbeeld hieronder wordt een cookie met de naam “gebruiker” aangemaakt met de waarde “Jan van Berg”. Na één uur moet verlopen (+3600 seconden): <? setcookie (“gebruiker”, “Jan van Berg”, tijd () +3600); ?> <html> ..... Tip: De waarde van het cookie is automatisch URLencoded, een cookie verzenden is gecodeerd en automatisch gedecodeerd bij ontvangst (om geen URLencoding te gebruiken moet setrawcookie () worden gebruikt) Voorbeeld 2: U kunt de aflooptijd van het cookie op een andere manier ook plaatsen. Het kan gemakkelijker zijn dan gebruikend seconden. <? $verloopt=time () +60*60*24*30; setcookie (“gebruiker”, “Jan van der Berg”, $verloopt); ?> <html> ..... In het voorbeeld hierboven is de verlooptijd een maand (60 seconden * 60 min * 24 uren * 30 dagen). De waarde van een cookie opvragen De PHP $_COOKIE variabele wordt gebruikt om een cookies waarde op te vragen. Hieronder worden alle ‘gebruiker- waarde’ van het cookie genoemd getoond het op een pagina: <? // Print een cookie echo $_COOKIE [“gebruiker”]; // Een manier om alle cookies te bekijken print_r ($_COOKIE); ?> In het volgende voorbeeld is de isset() functie gebruikt om te controleren of het cookie is geplaatst: <html> <body> <? if (isset ($_COOKIE [“gebruiker”])) echo ‘Welkom ‘. $_COOKIE [“gebruiker”]. ‘ ! <br/> ‘; else echo “U bent gast op onze site <br/>“; ?> </body> </html> © 2011 39 PHP & MySQL gevorderd Een Cookie verwijderen Wanneer een cookie verwijdert moet worden, dan moet de vervaldatum in het verleden liggen. Dit kan terug gezet worden... Voorbeeld om een cookie te verwijderen: <? // stelt de vervaldatum aan, en wordt één uur geleden setcookie (“gebruiker”, "", tijd () - 3600); ?> Wat als Browser Geen Cookies steunt? Als de gebruikte browser geen cookies ondersteund, dan zijn er andere methodes om gebruikinformatie van één pagina tot een andere in uw toepassing over te gaan. Één methode is de gegevens door formulieren (een formulier vraagt om gebruikersinput en is eerder behandeld). Het formulier vraagt de gebruiker om informatie en stuurt dit naar “groet.php” , wanneer de gebruiker op de “submit” knop klikt: <html> <body> <form name=”form” method= " post” action= " welkom.php " " > Naam: <input type= "text" name= " naam "/> Leeftijd: <input type= "text" name= " leeftijd "/> <input type=”submit” name= “verstuur” value =”verstuur”> </form> </body> </html> Win de waarden in het file “groet.php” als dit terug: <html> <body> Welkom <? echo $_POST [“naam”]; ?>.<br/> U bent <? echo $_POST [“leeftijd”]; ?> oude jaren. </body> </html> © 2011 40 PHP & MySQL gevorderd Toepassingen Toepassing1: SQL – database koppeling Het koppelen met een database wordt gedaan bij het laden van een website. Het opbouwen moet zo veilig mogelijk op de server staan. Als de toegang tot de database beschikbaar komt voor derden, dan liggen alle gegevens ‘op straat’. Zet dit bij voorkeur in de private_html map van je webserver en include deze code in de site. $host = 'localhost'; $username = "user_db"; $password = "wachtwoord_db"; $database = "db_naam"; $con = mysql_connect($host, $username, $password); if (!$con) { die('Geen connectie gemaakt met DB: ' . mysql_error()); } else { //connectie met database maken mysql_select_db($database, $con); } ?> Toepassing2: SQL – toevoegen van een tupel in een database Na connectie met de database wordt er na het klikken van de knop ‘invoegen’ worden de acoountgegevens uit het formulier toegevoegd in de tabel. include("../private_html/site/db_connect.php"); $q_invoegen_account = “INSERT INTO tabel_account VALUES (email, voornaam, tussenv, achternaam, adres, hnr, plaats)”; if (isset($_POST[invoegen]) && $invoerfouten == 0) { // uitvoeren na klik invoegen mysql_query($q_invoegen_account); } … meer code, waarin een formulier zit met knop om de velden als nieuwe gebruiker toe te voegen © 2011 41 PHP & MySQL gevorderd Toepassing3: SQL – opvragen en beheren database gegevens Een query die alle account gegevens uit een database haalt en in een tabel weergeeft. Alle gegevens worden in een formulier weergegeven, zodat de gebruiker dit kan aanpassen en updaten. Met een formulier daaronder kan het record worden verwijdert. Elke regel met de gegevens van een account heeft een eigen achtergrondkleur. Dit kan met CSS worden gedaan (er is geen css-uitwerking meegeleverd). Ook bevat elke regel een bewerk- en verwijder-knop. Na 2 includes,staat er acties die uitgevoerd worden mist die knop is geklikt (viewaccounts.php): include("../private_html/site/db_connect.php"); include(“../private_html/site/queries.php”); if (isset($_POST[Ja])) { // uitvoeren na klik op ja-knop mysql_query("START TRANSACTION;"); // transactie mysql_query($delete_aankopen_account); mysql_query($delete_gegevens_account); mysql_query($delete_account); mysql_query("COMMIT;"); } if (isset($_POST[update])) { // uitvoeren na klik op update-knop mysql_query($update_account); } if (isset($_POST[verwijder]) ) { // Delete Ja/Nee -keuze; alleen weergeven wanneer er is geklikt op delete echo'<table class ="JaNee"><tr> <td> <form name= "ZekerJa" action="viewaccounts.php" method="POST"> <input name="Ja" type="submit" value="Ja"> </form> </td> <td> <form name= "ZekerNee" action="viewaccounts.php" method="POST"> <input name="Nee" type="submit" value="Nee"> </form> </td> <td class ="JaNee"></tr></table>'; } Query om accounts op te vragen wordt uitgevoerd en een tabel wordt opgezet. $accountszoeken = mysql_query($zoekaccount_q); $lijn = 0; // variabele achtergrondkleuren per regel echo '<table border = "0" cellpadding = "0" cellspacing = "0">'; De regels met accounts wordt weergegeven door een while-loop: while ($gevondenaccounts = mysql_fetch_array($accountszoeken)) { $accID = $gevondenaccounts['u_id']; $lijn ++; echo '<tr CLASS= '; if ($lijn & 1) {echo ' "odd" ';} else {echo ' "even" ';} echo '>'; // CSS-class ‘even’ en ‘odd’ elk met een eigen achtergrond-kleur echo '<FORM NAME="view_update_account" ACTION="viewaccounts.php" method="POST">'; // het email-account maakt een gebruiker uniek en is de sleutel in de database echo '<td> <INPUT TYPE="text" name="email" value ="'.$gevondenaccounts['email'].'" SIZE="20" MAXLENGTH="25"> '; © 2011 42 PHP & MySQL gevorderd Het email-adres is een sleutel die nodig is om de juiste regel te overschrijven in de database. Wanneer deze wordt gewijzigd in een formulier, moet het originele email-adres nog wel beschikbaar zijn (onzichtbaar). Controleer ook of het nieuwe adres al niet bekend is in de database. Anders zijn er twee gebruikers met het zelfde email-adres en zijn de gebruikers niet meer uniek. echo '<INPUT TYPE="hidden" name="ORGmail" value ="'.$gevondenaccounts['email'].'" SIZE="20" MAXLENGTH="25"> </td>'; echo '<td> <SELECT NAME="aanhef"> <OPTION value="dhr" '; if ($gevondenaccounts['aanhef'] == dhr ) {echo " SELECTED ";} echo' >dhr </OPTION> <OPTION value="mevr" '; if ($gevondenaccounts['aanhef'] == mevr ) {echo " SELECTED ";} echo' >mevr </OPTION> </SELECT> </td>'; echo '<td> <INPUT TYPE="text" name="voornaam" value ="'.$gevondenaccounts['v_naam'].'" SIZE="12" MAXLENGTH="25"> </td> '; echo '<td><INPUT TYPE="text" name="tussenv" value ="'.$gevondenaccounts['tussenv'].'" SIZE="4" MAXLENGTH="7"> </td>'; echo '<td> <INPUT TYPE="text" name="adres" value ="'.$gevondenaccounts['adres'].'" SIZE="21" MAXLENGTH="25"> </td>'; echo '<td> <INPUT TYPE="text" name="hnummer" value ="'.$gevondenaccounts['hnr'].'" SIZE="3" MAXLENGTH="4"> </td>'; echo '<INPUT TYPE="text" name="plaats" value ="'.$gevondenaccounts['plaats'].'" SIZE="15" MAXLENGTH="15"> </td>'; echo’<td align ="right"> <INPUT TYPE="submit" NAME="update" value="update"> </FORM> </td>’; echo’<td> <FORM NAME="deleteaccount" ACTION="viewaccounts.php" method="POST"> <INPUT TYPE="hidden" name="delete_account" value = "'.$gevondenaccounts['email'].'" SIZE="25" MAXLENGTH="25"> <INPUT TYPE="submit" NAME="verwijder" value="verwijder"> </FORM></td>’; echo '<td> <INPUT TYPE="text" name="achternaam" value ="'.$gevondenaccounts['a_naam'].'" SIZE="20" MAXLENGTH="30">'; © 2011 43 PHP & MySQL gevorderd Door de queries in een appart bestand te zetten, hier: queries.php, wordt de PHP-code overzichtelijker. Het beheer over de queries is hiermee ook vereenvoudigd, doordat de queries niet meer verspreid staan in en over verschillende php-documenten. <?php … meerdere queries …. $update_account= "UPDATE `tabel_account ` SET aanhef = '".$aanhef."', v_naam = '".$_POST[voornaam]."', tussenv = '".$_POST[tussenv]."', a_naam = '".$_POST[achternaam]."', adres = '".$_POST[adres]."', hnr = '".$_POST[hnr]."', plaats = '".$_POST[plaats]."', email = '".$_POST[email]."', WHERE `email` = '".$ORGmail."' "; $delete_account = "DELETE FROM `tabel_account` WHERE email = '".$_POST[delete_account]."' "; ?> Toepassing4: update tabelvelden vanuit een VIEW Hieronder is een methode weergegeven hoe een view gemaakt wordt en hoe er daarna een update op de view wordt gedaan. Het is namelijk niet mogelijk een update uit te voeren over meerdere tabellen in één keer. Het maken van een view: CREATE VIEW blabla AS SELECT r.* FROM `tabel1` r, `tabel2` a WHERE a.idaccount = r.idaccount AND r.veldX= 'waarde1' AND a.veldY='waarde2' Daarna de update (die hier bestaat uit één veld): UPDATE blabla SET [veldX]= 'nieuwe waarde' © 2011 44