abonnement bol.com Unibet Coolblue
pi_21132106
PHP Dataverwerking

Wat is dit?
Deze FAQ is gemaakt om mensen op weg te helpen met een veel voorkomend probleem in PHP: externe variabelen. Als je script op internet wel werkt maar thuis niet, als een overgenomen scriptje gewoonweg niet wil werken of als je beveiligingsproblemen hebt met betrekking tot externe variabelen, dan zit je hier goed.

Het probleem zit 'm in register_globals. Dit is een instelling in PHP die ervoor zorgt dat externe variabelen automatisch worden omgezet naar globale variabelen. Een voorbeeldje dat zal werken met register_globals op 'on':
quote:
<?

echo $tekst;

?>
Als deze pagina aangeroepen wordt met 'pagina.php?tekst=hallo', dan zal de output ook 'hallo' zijn. Dit is erg handig en gebruiksvriendelijk van PHP, maar helaas niet erg professioneel. Sterker nog, het wordt ten zeerste afgeraden om zo te werk te gaan. Dit is de reden waarom sinds PHP 4.2.0 de waarde van register_globals standaard op 'off' staat. Veel webservers hebben deze waarde nog op 'on' staan, als je achter de waarde wilt komen kun je ini_get() of phpinfo() gebruiken.

Wat kan er fout gaan dan?
Over het algemeen gaan er twee dingen fout. Ten eerste, de compatibiliteit met verschillende servers. Zodra jouw scriptje op een andere server moet gaan draaien zou het goed kunnen zijn dat register_globals uit is gezet, en je scriptje niet meer werkt.

Ten tweede is er een mogelijk beveiligingsprobleem. Zie het volgende scriptje:
quote:
<?

if (user_heeft_toegang()) {
$toegang = 'okay';
}

(...)

if ($toegang == 'okay') {
//voer gevaarlijke code uit
}

?>
Stel dat je deze pagina oproept met 'pagina.php?toegang=okay', dan wordt de variabele $toegang al gedefinieerd met de waarde 'okay' voordat het scriptje start. Zo kan iemand dus in staat zijn gevaarlijke code uit te voeren door simpelweg variabelen te 'injecten' als register_globals aanstaat.

Nou en? Er zal toch niemand zijn die kwaad wil doen via mijn scriptje!
Zelfs al is je scriptje totaal voor eigen gebruik, driemaal geëncodeerd en achter zeven firewalls geplaatst, dan is het nog verstandig de aanbevolen methodes te gebruiken. Sowieso krijg je beter inzicht in het verloop van de dataverwerking in PHP, maar is je code later ook beter uitwisselbaar en beter te begrijpen voor andere scripters. Als je later ooit geforceerd op een server moet werken waar register_globals op 'off' staat, zoals het hoort, zul je blij zijn dat je 't kunt.

Hoe moet ik POST-formulieren gebruiken?
Een van de meest gebruikte methodes om een gebruiker data te laten versturen is door middel van POST-formulieren, die er als volgt uit zien:
quote:
<form action="pagina.php" method="post">
<input type="text" name="waarde" />
<input type="submit" value="Verstuur" />
</form>
Dit simpele formuliertje bestaat uit een tekstvak en een submit-knop. Zodra je op 'Verstuur' drukt verstuurt je browser de POST-gegevens door naar de webserver en komen de gegevens bij je scriptje terecht. Om die gegevens in te lezen maak je gebruik van de globale variabele $_POST:
quote:
<?

//dit is wat register_globals in feite doet,
//maar op deze manier werkt het altijd (en veilig)
$waarde = $_POST['waarde'];

echo $waarde;

?>
Om erachter te komen of bepaalde data uit een POST-formulier is verzonden kun je simpelweg gebruik maken van isset():
quote:
<?

if (isset($_POST['waarde'])) {
...
}

?>
In het voorbeeld wordt gebruik gemaakt van 'method="post"', je kunt hier ook 'method="get"' van maken om de data via de URL te versturen; zie beneden voor meer informatie.

En het versturen van bestanden?
Als je bestanden wilt versturen gaat dat op bijna dezelfde manier als bij een POST-formulier:
quote:
<form action="pagina.php" method="post" enctype="multipart/form-data">
<input type="file" name="bestand" /><br />
<input type="text" name="waarde" /><br />
<input type="submit" value="Verstuur" />
</form>
Je moet dus een 'enctype'-parameter definiëren om het te laten werken. Hierdoor stel je de browser in staat om de bestanden goed door te sturen naar de webserver, die ze vervolgens doorgeeft aan je scriptje. Bestanden kunnen worden benaderd door de globale variabele $_FILES:
quote:
<?

$waarde = $_POST['waarde'];

if (isset($_FILES['bestand'])) {
$bestand = $_FILES['bestand'];
echo $bestand['name'];
}

?>
Hierbij zijn is_uploaded_file en move_uploaded_file handige functies.

Hoe kan ik variabelen doorgeven via de URL?
Variabelen die doorgegeven worden via de URL heten zogenaamde GET-variabelen. Ze kunnen zowel via een formulier worden geconstrueerd (method="get") of door een hyperlink te maken in de vorm van:
quote:
pagina.php?waarde=100
Deze kun je achterhalen d.m.v. de globale variabele $_GET:
quote:
<?

$waarde = $_GET['waarde'];
echo $waarde;

?>
Hoe zit dat met cookies?
Cookies zijn een geval apart. Omdat ze op de computer van de gebruiker worden opgeslagen heb je er niet de volledige controle over; cookies zouden dan ook nooit mogen worden gebruikt om geheime gegevens in op te slaan. Verder is het mogelijk om een levensduur in te stellen, waarna de cookies door de browser mogen worden verwijderd. Om een cookie te maken:
quote:
<?

//zet de waarde '1' in de cookie 'visited'.
//na een dag (86400 seconden) wordt hij verwijderd
setcookie("visited", "1", time() + 86400);

?>
Let op: je gebruikt setcookie() voor enige output van PHP; dus voordat je iets echo()'ed of HTML output. Dit komt doordat cookies in de header van de webserver naar de browser worden gestopt, en deze wordt ook voor de daadwerkelijke pagina verstuurd. Om cookies te achterhalen maak je gebruik van de globale variabele $_COOKIE:
quote:
<?

if ($_COOKIE['visited'] == "1")
echo "Je bent hier vandaag al eens eerder geweest ";

//en om een cookie te verwijderen
unset($_COOKIE['visited']);

?>
Hoe gebruik ik sessies op de juiste manier?
Zoals gewoonlijk roep je session_start() aan voordat je iets output naar de browser. Om een variabele in te stellen en uit te lezen maak je gebruik van de globale variabele $_SESSION:
quote:
<?

session_start();

$_SESSION['waarde1'] = "blaat";

$test = $_SESSION['test'];

unset($_SESSION['verwijderdezemaar']);

?>
Sessies lopen gewoonlijk door totdat je de browser sluit; een vaak gebruikte methode om sessies langer aan te laten houden is de session id in een cookie op te slaan en deze later weer op te roepen. Het kan zijn dat PHP een zgn. URL rewriter gebruikt om alle links in je pagina's te voorzien van een '?PHPSESSID='; dit is een methode om de session id bij te houden.

Hoe roep ik servervariabelen aan?
Een hoop scripts maken gebruik van servervariabelen om bijvoorbeeld achter het IP-adres of het type webbrowser van de gebruiker te komen. Dit soort variabelen moeten worden achterhaald door middel van de globale variabele $_SERVER:
quote:
<?

//zoals...
$ip = $_SERVER['REMOTE_ADDR'];
$script = $_SERVER['PHP_SELF'];
$vandaan = $_SERVER['HTTP_REFERER'];
$browser = $_SERVER['HTTP_USER_AGENT'];

//en niet te vergeten, voor HTTP-authenticatie:
$user = $_SERVER['PHP_AUTH_USER'];
$wachtwoord = $_SERVER['PHP_AUTH_PW'];

?>
Hoe zet ik een al bestaand scriptje om?
Allereerst moet je goed in de gaten hebben hoe het scriptje werkt en waar alle data vandaan komt. Zet op de goede plaatsen in je script de bijbehorende variabelen:
quote:
<?

//deze komt van 'n formulier
$naam = $_POST['naam'];

//deze halen we uit een cookie
$tijd = $_COOKIE['tijd'];

//deze was gewoon fout
if ($PHP_SELF == 'blaat.php') {
if ($_SERVER['PHP_SELF'] == 'blaat.php') {

?>
Mocht het spaghetticode zijn en weet je absoluut niet meer hoe het in elkaar zat, dan is het misschien het beste om dat scriptje opnieuw te maken terwijl je de punten uit deze FAQ aanhoudt. Goed in de gaten hebben hoe je scriptje werkt en waar alle data vandaan komt is natuurlijk erg belangrijk als je een goede scripter wilt worden.

Hoe voorkom ik die variable injections?
Je kunt ze voorkomen door er zeker van te zijn dat de betreffende variabelen geïnitialiseerd zijn. Dit kan door ze een waarde te geven of door ze te unset()ten:
quote:
<?

$toegestaan = false;

if (user_heeft_toegang()) {
$toegestaan = true;
}

if ($toegestaan) {
//gevaarlijke code
}

//we willen niet dat iemand na dit punt de
//variabele $count heeft gedefiniëerd
unset($count);

?>
Variable injections kom je vooral tegen in de vorm van hacks in SQL-queries, waar in het ergste geval een gebruiker complete controle over je database krijgt. Opgepast dus.

Nou, weer wat geleerd. Bedankt!
Graag gedaan

[ Bericht 0% gewijzigd door Sander op 04-12-2005 18:54:03 ]
Stuur een PM naar me met als onderwerp stats help voor je userstatistieken!
Boom Gaspar - Matt Cameron - Jeff Ament - Stone Gossard - Mike McCready - Eddie Vedder.
abonnement bol.com Unibet Coolblue
Forum Opties
Forumhop:
Hop naar:
(afkorting, bv 'KLB')