Quick PHP tip: hoe develop je een site lokaal en online met een andere DB?

Zelf develop ik mijn PHP het liefst lokaal (via XAMPP), soms willen teamgenoten / klanten / baas af en toe mee kijken waar je ongeveer bent. Je kan je lokale site wel online gooien maar als je online database een andere login en password heeft dan de offline versie kan er van alles mis gaan.

Je kan natuurlijk elke keer voordat je hem online gooit de instellingen aanpassen, maar zit je erop te wachten omdat elke keer te doen?

Als je deze code in je index.php zet (of bijvoorbeeld een config bestand die je require’d of include via je index.php) kan je verschillende instellingen meegeven en worden de juiste toegepast afhankelijk van je situatie.

//BASE is the root of our app
//substr strips off 'index.php'
define('BASE', substr($SERVER['PHPSELF'],0,-9));

‘local’ en ‘local/publish’ slaan op mappen op de root van mijn lokale machine (bij XAMPP in htdocs) vanaf waar mijn app gedraaid zou kunnen worden (deze moet je dus zeer waarschijnlijk aanpassen). Wordt de app niet vanaf een van die mappen gedraaid? Dan zijn we live met de echte instellingen!

Posted at December 06, 2011, under PHP.

Hoe maak je een dynamisch menu in PHP?

Ik heb al een aantal keer de vraag gekregen hoe je makkelijk met PHP een menu kan maken met waarbij een item de klasse ‘current’ oid. heeft.

Je kan dit oplossen door ifjes in elkaar te nesten, dit wordt echter een te groot drama als je ook met subnavigatie gaat werken. Daarnaast wil je code (voor bijv. hoe een link eruit ziet) eigenlijk maar op 1 plek hebben.

Hier zijn twee functies uit mijn visitekaartjes generator die dit iets slimmer voor elkaar krijgen. (het voorbeeld hieronder is iets simpeler omdat je in het kader van het probleem geen Classes nodig hebt, dat maakt alles alleen maar ingewikkelder).

function createMenu($menu, $current) {
    //if current is empty (homepage), set it to home
    $current = (empty($current)) ? 'home' : $current;
    //start UL
    $html = "<ul>n";
    //for each item in menu create a link
    foreach ($menu as $value) {
        if ($value['name'] == $current) {
            $html .= '<li>' . $value['name'] . "</li>n";
        } else {
            $html .= '<li><a href="' . $value['url'] . '">' . $value['name'] . "</a></li>n";
        }
    }
    //end UL
    $html .= "</ul>n";
    //return the menu
    return $html;
}

De getMenu functie bevat nu het hele menu in de code (aka hardcoded), Het zou beter zijn om ze uit een database te halen en ze in een array aan de createMenu functie te voeren(die niks weet over het menu zelf, behalve dat home de homepagina is).

Belangrijk is wel dat alle urls niet relatief zijn (of relatief aan de root), oftewel hij moet beginnen met http://website of /. Als je dit niet doet kunnen je links anders zijn op basis van waar je je in je app bevindt (dat wil je niet).

Op deze manier kan je de functie gebruiken:

//deze set je normaal dynamisch, afhankelijk van op welke pagina de gebruiker zit.
$current = ";
$menu = getMenu();
echo createMenu($menu,$current);

De output is afhankelijk van de pagina waar de gebruiker op dat moment is, iets in deze trand:


Posted at December 01, 2011, under PHP.

De basis van .htaccess

Als je met websites werkt ben je het .htaccess bestand misschien al wel eens tegengekomen, maar wat doet dit bestand nou eigenlijk? .htaccess is iets wat alleen werkt op Apache webservers (overgrote deel van alle webservers op het internet).

Als je naar een restaurant gaat kom je voor het eten, terwijl je wacht komt de ober aangerend om alles te serveren, jij bent er niet voor de ober maar voor het eten wat hij serveert.

In dit voorbeeld ben jij de websitebezoeker, het eten de pagina(s / website) die je bezoekt en de webserver is de ober die zorgt dat iedereen netjes zijn eten krijgt. Een ‘stressed’ webserver is dan ook een ober die teveel werk heeft in te weinig tijd, het gevolg is dat iedereen lang op zijn eten moet wachten en misschien zelfs weg gaat.

.htaccess is een bestand die je in mappen op je webserver kan zetten. Dit bestand bevat regels over hoe de inhoud van die map getoond moet worden aan de browser. Regels over hoe de ober jouw eten moet serveren.

Voorbeelden van dingen die je kan doen met .htaccess:

clean URLS

Grote CMS’en zoals WordPress of Frameworks zoals CodeIgniter of CakePHP werken op basis van virtuele directories: Als jij een pagina aanmaakt met de naam ‘contact’ kan iedereen die pagina bereiken onder jouwwebsite.nl/contact. Die /contact slaat normaal gesproken op de map contact op je webserver. Echter is dit niet handig voor dynamische systemen die on the fly pagina’s kunnen aanmaken. Anders zou elke post op je blog een unieke pagina moeten zijn.

Deze systemen halen een trucje uit om dit voor elkaar te krijgen. Ipv naar /contact te gaan ga je eigenlijk naar bijvoorbeeld: index.php?page=contact (en vanaf hier kan index.php kijken welke pagina er opgevraagd wordt).

Je bent het al snel met me eens dat /contact er mooier en cleaner uitziet en makkelijk te typen is in een browser. Met .htaccess kan je al het verkeer wat naar /contact gaat achter de schermen sturen naar index.php?page=contact. Hoe doe je dit?

Maak een bestand .htacces en zet deze in de betreffende map en zet deze code erin:

# rewrite all requests ( /a/b/c/d/ ) to index.php?page=a/b/c/d/
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]

Eerst zetten we de rewrite engine aan (het onderdeel van Apache wat dit mogelijk maakt) en vervolgens zeggen we dat alle bestand (!-f) en folder (!-d) requests die binnenkomen moeten worden herschreven naar index.php?page=[request].

ETags

In het kader van optimalisatie willen we zoveel mogelijk rommel wat niet gebruikt wordt verwijderen. Een goed voorbeeld hiervan zijn de ETags, deze uitvinding van Microsoft was bedoeld bij te houden wanneer bestanden gewijzigd zijn ivm. caching. Dit wordt echter nooit gebruikt maar wordt wel standaard meegestuurd vanaf Apache. Uitzetten is heel simpel:

FileETag None

Default charset

Een charset heeft te maken met de encoding van je te webpagina’s (en alle andere bestanden die je serveert), normaal moet je die ook in je HTML vastleggen, echter kan je dit wel eens vergeten. In dat geval is de default charset handig.

AddDefaultCharset utf-8

Dit zijn wat voorbeelden van een tal van mogelijkheden. Wil je meer weten? De .htaccess van HTML5Boilerplate bevat 541 regels aan Apache optimalisatie!

Posted at December 01, 2011, under general.

Front end tips: snelle websites

Als je je veel bezig houdt met het maken van websites, is het belangrijk te snappen dat je je websites snel moet houden. Hierin behandel ik standaard technieken die worden gebruikt om dit zoveel mogelijk te garanderen. Waarom zou je je website willen optimaliseren op snelheid?

picture from h5bp.com

(afbeelding van de html5boilerplate website).

Hier zie je het verschil in laadtijd van een geoptimaliseerde pagina en een niet geoptimaliseerde. Hoe groter je websites worden, hoe groter het verschil zal zijn.

HTML5boilerplate
In deze post zal ik een hoop technieken behandelen die je kan uitvoeren om je pagina’s te optimaliseren. Je kan ook nieuwe websites maken op basis van de HTML5boilerplate, hierin zitten alle optimalisaties ingebakken die ik behandel (plus nog veel meer). Er zit een tool bij die heel snel alles voor je kan optimaliseren.

Expire Headers
Met Expire Headers kan je instellen hoelang een document gecached moet worden. Als je bijvoorbeeld je CSS bestanden voorziet van versie nummers (geautomatiseerd natuurlijk, bijvoorbeeld via HTML5boilerplate) zoals style.1.css weet je zeker dat het bestand style.1.css nooit zal veranderen, als jij iets in je code veranderd wordt het bestand style.2.css genoemd. Dit wetend kan je in je webserver (waarschijnlijk Apache) instellen dat het bestand style.1.css heel lang gecached mag worden. Je webserver geeft dit dan mee aan de client en met een beetje geluk hoeft de client maar eenmalig je CSS file binnen te trekken. Hier kan je voorbeeld code voorin je .htaccess (configuratie bestand van Apache) vinden.

Zet je JavaScript onderaan de pagina

(niet van mij, bron: onbekend)

Op een moment dat een browser een pagina laadt en hij komt JavaScript code tegen (inline, of externe scripts) wordt alles op pauze gezet totdat alle JavaScript gedownload en verwerkt is. als je JavaScript in je head zet gaat je browser aan de slag met je JS en gaat hierna pas beginnen met het renderen van de pagina. Omdat je 9 van de 10 keer alleen JavaScript gebruikt om iets op de pagina te manipuleren, doe je hier toch nog niks mee totdat de complete pagina gerenderd is. Als de browser toch op pauze moet, doe dit dan terwijl de gebruiker alvast naar je pagina kan kijken ipv. een wit scherm.

Als je je JS vlak voor je zet valideert hij netjes en oogt je pagina een stuk sneller.

Minimaliseer het aantal HTTP requests
Het grote protocol achter het web (HTTP) is redelijk oud en niet zo efficient, als je bijvoorbeeld 10 losse bestanden aanvraagt zal dit in de regel langzamer gaan dan 1 bestand dat 2x zo groot is als de losse bestanden verzamelt. Dit komt omdat er bij elke aanvraag opnieuw een connectie moet worden gemaakt. Hierdoor is het belangrijk er altijd voor te zorgen dat je zo min mogelijk links naar scripts, CSS, afbeeldingen ed. staan. Als je werkt met meerdere CSS bestanden is het in de regel altijd verstandiger om ze in 1 bestand te stoppen (ook een @import is een nieuwe HTTP request). Je hoeft je werkwijze niet aan te passen, zolang je er maar voor zorgt dat de productie versie maar een CSS bestand heeft (HTML5boilerplate doet dit automatisch voor je). Ook zijn sprites (meerdere afbeeldingen in een plaatje) beter dan losse afbeeldingen.

Bij JavaScript ligt het iets ingewikkelder omdat je soms op een bepaalde pagina een heel zwaar script nodig hebt en op de rest van je site niet. In dat geval zou ik kijken naar hoe waarschijnlijk het is dat een bezoeker op je site op die pagina komt, als dat niet waarschijnlijk is kan je dat scriptje in een los bestand zetten.

Hou je bestanden zo klein mogelijk
CSS en JS: Het is slim om je CSS voor de productie versie te minify’en (dit haalt alle witregels weg). Browsers interpreteren zulke code net zo snel als gewone CSS alleen is het bestand in een keer een stuk kleiner. Dit gaat ook op voor al je JavaScript (hier worden lange variabele en functie namen ook nog vervangen door a, b, c enz.

HTML: Standaarden VS optimalisatie
Je kan je HTML een stuk kleiner maken door bijv. accolades te laten bij id’s en classes:

Browsers hebben hier geen moeite mee, maar de validator struikelt hier wel over. Dit is een moeilijke discussie aangezien de standaarden wel een kwaliteitsnorm garanderen die je anders negeert.

Test je pagina’s
Yahoo heeft een tooltje gemaakt waarmee je kan testen hoe goed je pagina voldoet aan ‘algemen optmialisatie regels’. Installeer YSlow en test hem op je websites.

Posted at November 30, 2011, under general.

Hou je PHP code overzichtelijk: MVC

Zodra je meer met PHP begint te spelen wordt het handig om je code beter te kunnen ordenen en structureren. PHP kan namelijk een spaghetti taal zijn als je PHP in je HTML zet met ifjes en loopjes. Grote frameworks en CMS systemen hebben al eerder manieren gevonden om alles overzichtelijk te houden.

MVC MVC (Model-View-Controller) is een abstract design pattern die het mogelijk maakt om eenvoudig logica van presentatie te scheiden, met logica bedoel ik hier eigenlijk alles wat niks meer met het design van je website te maken heeft. Omdat MVC een abstract idee is staat het los van de implementatie, zelfs op dat niveau zijn er al veel verschillende ideeën over wat nou de beste manier is.

Even een klein metafoor om het principe duidelijk te maken:

Als je naar de supermarkt gaat heb je alleen te maken met een cassiere, tenminste zo lijkt het. Echter zijn er in de supermarkt nog twee andere belangrijke rollen: namelijk de manager die alles en iedereen bij elkaar houdt en de magazijnmedewerker die ervoor zorgt dat er altijd genoeg spullen in de winkel staan.

Zo werkt het ook bij een website die zich aan het MVC principe houdt: Je denkt dat je alleen met de voorkant (views) te maken hebt, echter is altijd nog de baas die bepaald welke views er nodig zijn en die zorgt dat alles in de winkel aanwezig is, ofwel dat alle gegevens die nodig zijn om de views op te bouwen worden geregeld door een model.

Hoe gaat dit in zijn werk?

Het is belangrijk dat alle rollen worden aangeroepen onder leiding van de controller. Deze zit of rechtstreeks in een index.php (bestand die vaak automagisch geladen wordt) of wordt hierin al eerste aangeroepen. De controller zorgt dat het model de benodigdheden uit de database haalt* en verzamelt deze data en geeft ze mee aan de view.

*het model heeft alle informatie van je applicatie minus de user interface, in het geval van websites zijn dit vaak functies en klasses om een database te query’en.

Dit is een extreem simpel voorbeeld, het wordt al moeilijker als de Controller eerst moet uitzoeken welke pagina er aangevraagd wordt (vaak op basis van GET informatie vermomd via je webserver) en op basis daarvan andere controllers moet raadplegen die meerdere models en views bij elkaar moeten schrapen.

Bij een MVC website is het dus altijd zo dat je op een centraal punt binnenkomt en vanuit daar de betreffende pagina opbouwt.

MVC is niet alleen in de webwereld een belangrijk principe, ook als je bijvoorbeeld apps wilt gaan maken moet je dit begrijpen. Binnenkort zal ik een een tutorial posten die een extreem minimaal voorbeeld in PHP demonstreert.

Posted at November 28, 2011, under PHP.