Softwareontwikkeling FAQ: PHPMet dank aan drm.Inhoudsopgave
Links
Boeken
FAQMijn POST en GET forms werken niet (meer)Hoogstwaarschijnlijk ben je onlangs gemigreerd van een oude PHP versie naar een nieuwe, of je bent begonnen aan een PHP tutorial die verouderd is.In de manual van PHP vind je onder het stukje Predefined variables een en ander over de zogenaamde "superglobals", die in versie 4.1.2 hun intrede deden. Daarnaast werd in versie 4.2.0 de configuration directive 'register_globals' standaard op Off gezet. Dit had als gevolg dat variabelen die van buitenaf komen niet meer automagisch globaal aangemaakt werden. PHP:
Dit stukje php werkte voorheen altijd gewoon zonder problemen, als je het aanriep met index.php?user=drm. Tegenwoordig zijn de variabelen terug te vinden in hun respectievelijke superglobals. PHP:
Zie verder de manual voor het gebruik van deze superglobals. Ik kan de fout echt niet vinden!Heb je error_reporting op E_ALL staan? Nee? Meteen doen! Deze directive / functie op E_ALL zetten zorgt er namelijk voor dat je veel meer bruikbare debug-informatie krijgt. PHP is namelijk van zichzelf heel erg tolerant met bepaalde constructies, terwijl ze eigenlijk niet helemaal netjes zijn of al min of meer verboden zijn maar nog toegelaten worden wegens backward compatibility.Als je zogenaamde notices ook toelaat in je error_reporting krijg je o.a. informatie over:
Schrik dus niet als je je error_reporting ook op E_ALL hebt staan. Hoe zet ik bepaalde configuratie directives aan/uit?Vaak komt het voor dat je zelf maar een klein stukje webspace hebt, maar niet alle opgelegde configuraties van de serverbeheerder zo wilt zoals hij ze heeft ingesteld.Zoek in de manual op welke directive je aan wilt passen, en ga na op welke manieren je ze kunt zetten. Je vindt ook een tabel terug waarin staat wat de PHP_INI_* waarden betekenen:
Zie voor meer informatie dit stuk uit de manual. "... is not a valid MySQL resource index"Hoogstwaarschijnlijk heb je een fout staan in je MySQL query. Gebruik de functie mysql_error() om erachter te komen wat de fout precies is.Een goede gewoonte is het om bij MySQL queries altijd even te kijken of er een fout is opgetreden, en zo ja, wat de fout en de query dan was: PHP:
Zie voor meer informatie over het effectief gebruik van trigger_error() dit stukje. Meer informatie over MySQL functies vind je hier. Mijn sessie-variabelen worden niet opgeslagenGebruik session_register() en $_SESSION constructies niet door elkaar.session_register() PHP:
$_SESSION PHP:
Gebruik of de één, of de ander. Als je beide constructies door elkaar gebruikt, werkt het niet. As simple as that. Sterker nog: sinds register_globals default uit staat, is het gebruik van session_register deprecated:
Mijn sessie-variabelen verdwijnen na sluiten van het browservensterUit http://www.php.net/manual/en/ref.session.php:Uit http://www.php.net/manual...on-set-cookie-params.php: Een stukje code bovenaan elk script zou je sessie dus 30 dagen actief moeten houden: PHP:
Let daarbij er dus op, dat een lifetime van 0 betekent dat het cookie getrashed wordt bij sluiten van het browservenster. Mijn file-upload form werkt niet
Ik heb een multiple select of meerdere checkboxes, maar krijg maar 1 variabele binnen in PHP?Je kunt door achter de naam van je input-veld [] te zetten aan PHP vertellen dat je graag wilt dat alle variabelen die met die naam binnen komen als array behandeld moeten worden:Voorbeeld: HTML:
Het gevolg van een dergelijk formulier is dat in dit geval de $_GET array binnen PHP op zijn beurt weer arrays bevat waarin aangegeven staat welke opties 'aangevinkt' zijn: Uitvoer: PHP:
code:
Eveneens kun je de indices van de array op zichzelf ook namen/nummering geven. Als je dat doet kun je eenvoudig de 'value' van checkboxes achterwege laten: HTML:
Uitvoer: PHP:
code:
Met een beetje creatief gebruik van in_array () en/of foreach constructies is het op die manier heel eenvoudig te achterhalen welke opties aangevinkt zijn. Van mijn <input type="image" ... > kan ik de coordinaten niet terugvinden?Zoals je in de PHP.net FAQ kunt lezen, worden de namen foo.x en foo.y variabelen in PHP omgezet naar resp. foo_x en foo_y.Bij een javascript-submit of drukken op enter wordt mijn form niet herkend als 'submitted'?Als je in je form een <input type="submit"> een name en een value geeft, worden deze in Internet Explorer niet meegegeven als form-waarde.Je kunt dan beter 1 van de 2 volgende constructies gebruiken om te controleren of je form gesubmit is: In het geval van een POST formulier: PHP:
In het geval van een GET formulier: (Uiteraard kun je deze wijze ook toepassen bij een POST. Het is maar net wat jouw voorkeur geniet.) HTML:
PHP:
Spaties van een <input ... value=...> worden niet herkend door de browserJe moet attributen van een html element om deze reden altijd quoten en de waarde ervan escapen. Zie de volgende voorbeelden:Waarom quoten? PHP:
Het resultaat is dan: HTML:
De browser zal enkel het stukje This als waarde van het veld interpreteren. De rest zal de browser proberen als attributen te behandelen. Als dat niet lukt wordt de informatie gewoon genegeerd. Als je echter quotes om de waarde heenzet, heb je daar geen last van. Waarom escapen? PHP:
Het resultaat is dan: HTML:
Je zal begrijpen dat de browser dit niet anders kan interpreteren dan dat het gedeelte This is value with a de waarde van het attribuut value is. Gebruik dus htmlspecialchars() of htmlentities() om de values te escapen. 'Escapen' van quotes in queries?Controleer altijd of get_magic_quotes_gpc() en get_magic_quotes_runtime() aan staan. Als 1 van deze twee aan staat, worden variabelen binnen PHP die enkele (') of dubbele (") quotes of backslashes (\) bevatten automagisch escaped. Dat wil zeggen dat een string die in PHP binnen komt via GET, POST of een cookie (gpc) die een ', " of \ bevat automagisch een \ voor die character krijgt. Bekijk het volgende voorbeeld:PHP:
Uitvoer met get_magic_quotes_gpc aan, na submit: code:
Daarbij is het dus overbodig om nog een addslashes of een andere escape-functie los te laten op die variabelen. Houd zelf de controle op het escapen. Het is het overwegen waard om zelf de controle te houden op het escapen van variabelen, om te voorkomen dat je bijvoorbeeld in <input ...> velden een ongewenste backslash krijgt. Mijn voorkeur heeft het dan ook om in de code te checken of er al ge-escaped is, en zo ja: die escape characters weer te verwijderen: Uiteraard is het ook een optie om je configuratie helemaal naar je hand te zetten, maar je kunt een reden om dat niet globaal te doen en de magic quotes directives kun je niet altijd per script aan of uit zetten, behalve magic_quotes_runtime (zie set_magic_quotes_runtime(). Daarnaast is het het overwegen waard om je scripts zo portable mogelijk te maken (onafhankelijk van configuraties). PHP:
Vervolgens kun je met je eigen escape functies de juiste escapes doen: PHP:
Overigens is het ook te overwegen de ANSI-SQL wijze van escapen te hanteren, door een enkele quote te escapen met een extra enkele quote: PHP:
De testcase voor werking van je escapes: Om goed te testen of je escaping wel goed werkt, probeer het volgende in te voeren in je database door middel van een formuliertje: code:
Wanneer je bij inserten van deze string geen foutmelding krijgt en je krijgt exact dezelfde string terug bij het uitlezen van die string uit je database, werkt je escaping perfect: PHP:
Maar waarom gebruik je nou in vredesnaam die add- en stripslashes functies niet? Het probleem met die functies is dat er soms dingen escaped worden die niet ge-escaped hoeven te worden naast dingen die wel escaped moeten worden. Als er dus data ingevoerd die opzichzelf een escape-sequence is, wordt die data in eerste instantie escaped voor bijv. MySQL, maar bevat hij bij uitlezen weer diezelfde escape-sequence die ingevoerd is. Als je daar vervolgens een stripslashes () overheenhaalt, ben je een escape sequence kwijt. Vandaar dat de bovengenoemde testcase de beste is om na te gaan of er niet teveel of te weinig escapes uitgevoerd worden. Ik wil index.php?piet=1&sjaak=3 vervangen door index/1/3. Hoe doe ik dat?Eigenlijk is dit niet echt een PHP vraag, maar een Apache vraag. Maar op de een of andere manier komt het altijd in een PHP context weer terug, vandaar hier maar een stukje uitleg.MultiViews Verreweg de meest eenvoudige manier is om in je Apache configuratie (hetzij in httpd.conf, hetzij in een .htaccess, hetzij nog ergens anders) voor de directory waar je je php'tje hebt staan de MultiViews option aan te zetten: code: code:
De Apache 1.3 documentatie zegt er het volgende over: In PHP kun je vervolgens de binnengekomen request afhandelen met de $_SERVER['REQUEST_URI'] variabele. mod_rewrite Een veel ingewikkelder maar veel flexibeler oplossing is het gebruik maken van mod_rewrite. Deze module geeft je de beschikking over diverse configuratie directives die vertellen hoe een inkomende request "vertaald" (rewritten) moet worden naar een door jou te bepalen URI. Een eenvoudig voorbeeld is om bijvoorbeeld de url /rewrite-test/index/1/2 te rewriten naar /rewrite-test/index.php?piet=1&sjaak=2 code:
Je kunt dit natuurlijk zo gek maken als je zelf wilt. Een goed opgezette set rewriterules kan ook zorgen voor goede 'default'-afhandeling en shortcuts naar bepaalde pagina's. Zo zou je bijvoorbeeld een rewriterule kunnen maken die doorverwijst naar een search-engine als een url niet bestaat, of /user/piet doorverwijzen naar een profile.php?user=piet, etcetera. Alles bij elkaar genomen is het zeer zeker de moeite waard mod_rewrite te verkiezen boven MultiViews. Voor meer informatie over het gebruik van mod_rewrite kun je het beste de URL Rewriting Guide en de mod_rewrite reference van Apache doornemen. Voor meer informatie over het gebruik van regular expressions kun je hier terecht. Het bewerken van afbeeldingen in PHP, hoe werkt dat?Dit is een korte vraag met een uitgebreid antwoord, dat in deze FAQ uitgewerkt is. |
[ Voor 23% gewijzigd door NMe op 21-12-2019 18:15 ]
'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.