PHP 5.3: GC, NOWDOC, ?: operator en GOTO
De afgelopen tijd heb ik de grote nieuwe en meest populaire nieuwe features van PHP 5.3 bekeken. Met deze posting komen we even aan het einde van de PHP 5.3 serie. In deze posting bekijk ik de verschillende kleinere toevoegingen en wijzigingen die doorgevoerd zijn voor PHP 5.3.
- Garbage Collector
- De ternary operator shortcut: ?:
- FileInfo extensie
- Nieuwe classes in SPL
- Statische methodes dynamisch aanroepen
- Nieuwe magic method: __callStatic
- HEREDOC / NOWDOC
- GOTO ondersteuning
- De __DIR__ constante
Garbage Collector
Voor mensen die wat langer levende PHP scripts maken is de nieuw toegevoegde garbage collector interessant. Standaard heeft PHP geen oplossing voor het probleem dat een object een niet verwijderbare referentie behoudt tot een ander object:
-
<?php
-
-
class A {
-
public function __construct() {
-
}
-
}
-
-
-
$a = new A();
-
-
$a->a = $a;
-
$a->a->mydata = $a->data . 'test';
-
-
-
-
-
?>
Het concept reference counting werkt in dit geval tegen PHP. In het bovenstaande script ontstaan er twee referenties naar $a. Een bij de instantiatie van class A, en verderop wijs ik $a nog een keer toe aan een eigenschap van $a. Dat veroorzaakt een cyclische referentie.
Op dat moment zijn er dus twee referenties naar het object in $a. Unset() ik dan $a, dan wordt er dus 1 referentie weg gehaald, maar dan is er nog 1 referentie over, namelijk in $a->a.
Deze wordt niet vanzelf opgeruimd door PHP omdat er op het moment van opruimen nog een referentie naar het object bestaat. Het probleem is dat je daar nu nooit meer bij kan om zelf op te ruimen, en dus blijft het geheugen in gebruik zoals blijkt uit de output van het bovenstaande script:
-
MEM 1 aan het begin: 0.31 Mb
-
MEM 2 na instantiatie A: 1.31 Mb
-
MEM 3 na zelf referentie: 2.31 Mb
-
MEM 4 na unset($a): 2.31 Mb
Met de Garbage Collector die in PHP 5.3 is gebouwd, welke overigens een product van de Google Summer of Code 2007 is, wordt het mogelijk om dit soort geheugen problemen op te lossen. De Garbage Collector is namelijk in staat om dit soort cycles te detecteren én op te lossen:
-
<?php
-
-
gc_enable();
-
-
class A {
-
public function __construct() {
-
}
-
}
-
-
$a = new A();
-
-
$a->a = $a;
-
$a->a->mydata = $a->data . 'test';
-
-
-
gc_collect_cycles();
-
-
?>
De output van dit script is veel bemoedigender:
-
MEM 1 aan het begin: 0.31 Mb
-
MEM 2 na eerste instantie: 1.29 Mb
-
MEM 3 na zelf-referentie: 2.26 Mb
-
MEM 4 na unset($a): 0.31 Mb
Na het unsetten van $a is het geheugen gebruik nu terug naar het originele geheugen gebruik van voor we begonnen met het gebruik van klasse A. Het gebruik van de garbage collector vereist wel enkele stappen aan de kant van de ontwikkelaar.
Om de Garbage Collector te gebruiken zul je deze eerst moeten inschakelen. Hiervoor gebruik je de functie gc_enable(). Vanaf dit moment zal PHP extra informatie bijhouden. Zoals de naam gc_enable doet vermoeden kun je de Garbage Collector ook weer uitschakelen en dit doe je eventueel met gc_disable(). Om 'de rotzooi op te ruimen' gebruik je de functie gc_collect_cycles(), welke de extra bijgehouden informatie gebruikt om bijvoorbeeld in het bovenstaande script de cyclische referentie te detecteren en te doorbreken zodat het geheugen vrijgegeven kan worden.
De ternary operator shortcut: ?:
De ternary operator is een geliefde operator, maar vaak wil je testen of een variabele een waarde heeft en zo niet daar alsnog een default waarde aan toekennen:
Allemaal niet zo probleem, hooguit wat langdradig. Voor deze situatie is de ternary operator shortcut eh... operator, toegevoegd. Om het bovenstaande voorbeeld na te maken, zou je eventueel de volgende code kunnen schrijven:
-
$var = '';
-
$var = $var ?: 'Var is Leeg'
-
echo $var;
-
-
//Output: Var is Leeg
Oftewel, op het moment dat de variabele $var een waarde heeft die tot FALSE evalueert, zal $var de nieuwe waarde 'Var is Leeg' krijgen.
Veel mensen denken, of hopen :), dat de volgende code ook werkt met deze nieuwe operator:
Echter, dat is niet het geval. In dit geval zal de waarde van $var TRUE of 1 zijn op het moment dat $var al bestaat. De expressie wordt namelijk intern omgeschreven naar:
en dus niet naar:
.. zoals mensen hopen. Er is wel een technische reden voor te bedenken waarom dit niet zo werkt (je kunt niet veilig bepalen dat de waarde $var moet worden gebruikt), maar toch jammer.
Voor de isset() variant hebben de PHP developers dan ook ooit ifsetor() bedacht maar konden het jammer genoeg niet eens worden over een (complexe) exacte werking met meerdere argumenten etc, en adviseren nu om een IMHO hacky userland functie voor zoiets te gebruiken:
De eventuele notice melding 'undefined variable' voor $var wordt onderdrukt door het feit dat een referentie wordt aangelegd.
De FileInfo extensie
Soms wil je graag detecteren wat voor type bestand een bepaald bestand is. Tot dusver waren we voornamelijk aangewezen op de file commandline utility, maar vanaf PHP 5.3 mag je er vanuit gaan dat de extensie FileInfo, welke al enige tijd in PECL leefde, beschikbaar is.
Met de FileInfo extensie kun je gemakkelijk allerlei informatie detecteren over een bestand, zoals wat voor mime type gebruikt zou moeten worden voor dat bestand:
Nieuwe classes in SPL
De SPL extensie is in PHP 5.3 niet meer uit te schakelen bij het compileren van PHP, dit houdt in dat je er als ontwikkelaar altijd vanuit mag gaan dat deze extensie beschikbaar is. De SPL extensie zelf is ook uitgebreid met enkele nieuwe interessante klassen:
SplMaxHeap & SplMinHeap
De SplMaxHeap klasse is een van de twee standaard child-klasses van SplHeap. De SplMaxHeap klasse levert een automatisch aflopend gesorteerde lijst van waarden:
-
$spl = new SplMaxHeap();
-
$spl->insert(1);
-
$spl->insert(3);
-
$spl->insert(2);
-
-
foreach ($spl as $value)
-
echo $value;
-
-
/* Output: 321 */
Het broertje van van SplMaxHeap is uiteraard SplMinHeap, welke zoals je verwacht, precies andersom werkt:
-
$spl = new SplMinHeap();
-
$spl->insert(1);
-
$spl->insert(3);
-
$spl->insert(2);
-
-
foreach ($spl as $value)
-
echo $value;
-
-
/* Output: 123 */
SplPriorityQueue
De SplPriorityQueue lijkt erg op de SplMaxHeap klasse, maar verschilt in dat je een key-value combinatie kunt op te slaan in plaats van alleen een waarde. De key wordt gezien als een prioriteits aanduiding, waarbij een hoge waarde belangrijker is.
-
class Mens {
-
public $naam;
-
public function __construct($naam) { $this->naam = $naam; }
-
}
-
-
$spl = new SplPriorityQueue();
-
$spl->insert(new Mens('Henk'),2);
-
$spl->insert(new Mens('Piet'), 1);
-
$spl->insert(new Mens('Sjaak'), 5);
-
$spl->insert(new Mens('Kees'), 3);
-
-
foreach($spl as $key => $value)
-
{
-
}
-
De output van dit script is:
-
Mens #4 = Sjaak
-
Mens #3 = Kees
-
Mens #2 = Henk
-
Mens #1 = Piet
-
Queue bevat 0 items
Een interessante eigenschap van de SplPriorityQueue klasse is dat deze de items die je hebt uitgelezen verwijdert uit de instantie. Het is dus met recht een queue en elke lees actie haalt een node uit de queue.
De SplPriorityQueue is ook uit te lezen zonder foreach() wat in sommige situaties handiger kan zijn:
-
$spl = new SplPriorityQueue();
-
-
$spl->insert(new Mens('Mathieu'),2);
-
$spl->insert(new Mens('Lotje'), 1);
-
$spl->insert(new Mens('Sjaak'), 5);
-
$spl->insert(new Mens('Mike'), 3);
-
-
$spl->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
-
-
while (!$spl->isEmpty())
-
{
-
$value = $spl->extract();
-
}
-
SplFixedArray
In plaats van een dynamische array die automatisch groeit naarmate je er meer in stopt, zoals je gewend bent met PHP, biedt de SplFixedArray een array die juist niet automatisch groeit naarmate je er meer in stopt.
Voor de SplFixedArray geef je op hoeveel items je er maximaal in wilt plaatjes en als je er meer in probeert te stoppen dan zal dat je een exceptie opleveren. Het vastleggen van het maximale aantal elementen biedt de onderliggende code de mogelijkheid om de data toegang te optimaliseren.
-
$a = new SplFixedArray(4);
-
$a[2] = "scriptorama";
-
$a[1] = "localjoost";
-
$a[3] = "flickr";
-
$a[0] = 'twitter';
-
-
foreach($a as $value)
-
echo $value, PHP_EOL
-
-
/* OUTPUT:
-
twitter
-
localjoost
-
scriptorama
-
flickr
-
*/
-
-
$a[4] = 'digg';
-
// Fatal error: Uncaught exception 'RuntimeException' with message 'Index invalid or out of range' in /Users/mathieu/Source/tests/spl/i4.php:14
Een instantie van SplFixedArray is verder te gebruiken als een gewone array, aangezien het de SPL interface ArrayAccess implementeert. Een subtiel verschil met 'gewone' PHP arrays is wel dat het uitlezen van een SplFixedArray met numerieke indices ook op volgorde van de indices gaat (element 0 eerst, dan element 1, etc.), in plaats van de volgorde waarop je ze in de array hebt geplaatst, zoals met gewone PHP arrays (ook geindexeerde arrays) het geval is.
GlobIterator
De GlobIterator is een gemaks toevoeging. Vóór PHP 5.3 moest je je ofwel de glob() functie gebruiken of anders eigen klasse gebaseerd op FilterIterator combineren met een DirectoryIterator maken om alle bestanden uit een directory welke voldoen aan een patroon te krijgen. In PHP 5.3 heb je daarvoor de GlobIterator:
-
<?php
-
$spl = new GlobIterator("../*");
-
-
foreach ($spl as $file)
-
{
-
}
-
-
/*
-
../file1.php [FILE]
-
../tests [DIR]
-
*/
-
?>
Het voordeel van GlobIterator over de glob() functie is dat elk element dat elk element dat de GlobITerator terug geeft een instantie van SplFileInfo is, wat direct meer flexibiliteit biedt.
Statische methodes dynamisch aanroepen
Je wist waarschijnlijk wel dat PHP allerlei mogelijkheden heeft om methodes en functies dynamisch aan te roepen. Daar hebben we op Scriptorama al eens over geschreven: Callbacks in PHP. Er was echter altijd een beperking met statische aanroepen, hiervoor moest je altijd de ietwat onhandige call_user_func() of call_user_func_array() functie voor gebruiken.
In PHP 5.3 kun je dit gewoon op de PHP manier doen:
Nieuwe magic method: __callStatic
Er is in PHP 5.3 ook een nieuwe magic method bij gekomen. In PHP 5 zit al de magic method __call(), waarmee je in een object aanroepen naar niet gedefinieërde methodes kunt afhandelen. Maar dit werkt alleen op objecten en gewone methodes. De functionaliteit is nu compleet gemaakt door __call() ook mogelijk te maken voor static aanroepen middels een nieuwe magic method __callStatic:
HEREDOC en NOWDOC
In de huidige PHP versies hebben we al de zogenaamde HEREDOC functionaliteit. Hiermee kun je een stuk tekst definieëren zonder daar quotes en escaping voor te gebruiken:
-
$text = <<<EOD
-
Dit
-
Is "mijn"
-
Data
-
EOD;
-
-
echo $text;
In PHP 5.3 komt daar nu de NOWDOC functionaliteit bij, en daarbij komt meteen ook een extra nieuwe syntax voor HEREDOC. De NOWDOC functionaliteit vs. de HEREDOC functionaliteit biedt dezelfde verschillende als single quotes vs. double quotes: NOWDOCS leest geen variabelen en escape sequences uit.
-
$variabele = "artikel";
-
-
// Gebruik single quotes om 't label naam om NOWDOCS te gebruiken:
-
$text_now = <<<'EOD'
-
Dit is "data". Ik heb ook een mooi $variabele \n";
-
EOD;
-
// Gebruik single quotes óf geen quotes om HEREDOCS te gebruiken:
-
$text_here = <<<"EOD"
-
Dit is "data". Ik heb ook een mooi $variabele \n";
-
EOD;
-
Beperkte GOTO ondersteuning
Een van de iets meer controversiële toevoegingen aan PHP 5.3 is de ondersteuning voor beperkte GOTO. Je hebt daar vast al iemand over horen klagen, dus dat ga ik niet doen. Ik ga je alleen laten zien waar je het wél voor zou kunnen gebruiken.
De structuur van GOTO is eenvoudig: definieer een label en plaats een statement om naar dat label te springen:
-
if ($conditie) // niet vereist, slechts een voorbeeld
-
goto label_naam;
-
-
label_naam:
-
echo "Nu zitten we onder label_naam";
Belangrijk om te realiseren is dat een label met een block code eronder geen speciale betekenis heeft. Het definieert alleen maar een locatie binnen het PHP script en dit houdt in dat als jouw code om een of andere reden bij het label uitkomt (terwijl dat niet de bedoeling is) deze code ook gewoon uitgevoerd zal worden. Iets om rekening mee te houden:
Een van situaties waar je GOTO voor zou kunnen toepassen is error handling. Stel bijvoorbeeld dat je een functie of methode hebt die veel SQL queries moet doen, op het moment dat er iets niet klopt wil je graag een ROLLBACK doen zodat de wijzigingen ongedaan gemaakt worden. Dat zou er zonder GOTO waarschijnlijk zo uitzien:
-
class GotoExampleClass
-
{
-
/* ... */
-
function UpdateBalance($userID, $amount)
-
{
-
$this->_db->query("BEGIN");
-
-
$userData = $this->_db->fetch_one_row("SELECT * FROM user WHERE UserID = $userID");
-
-
if (!$userData) {
-
$this->_db->query("ROLLBACK");
-
$errorMessage = "User doesn't exist";
-
return $errorMessage;
-
}
-
-
$this->_db->query("UPDATE user SET LastActivity = NOW() WHERE UserID = $userID");
-
-
$balance = $this->_db->fetch_one_column("SELECT SUM(Amount) AS current_balance FROM user_balance WHERE UserID = $userID");
-
-
/* Voor het voorbeeld, laten we nu vast de balance updaten :) */
-
$this->_db->query("INSERT INTO Balance(UserID, LastModified, Amount) VALUES ($userID, NOW(), $amount)");
-
-
$is_withdrawal = ($amount <0);
-
if ($is_withdrawal)
-
{
-
/* Als er een bedrag wordt afgeschreven, check dan of de user wel genoeg geld heeft */
-
if ($balance <abs($amount) && !$userData['has_credit'])
-
{
-
$this->_db->query("ROLLBACK");
-
$errorMessage = "Not enough Scriptorama Dollars and no credit!";
-
return $errorMessage;
-
}
-
-
if ($balance <abs($amount) && $userData['has_credit'])
-
{
-
{
-
$this->_db->query("ROLLBACK");
-
$errorMessage = "Withdrawal would exceed credit limit";
-
return $errorMessage;
-
}
-
}
-
-
}
-
-
$this->_db->query("COMMIT");
-
return TRUE;
-
}
-
}
Op zich niet zo heel veel mis mee, maar je ziet dat we wel 3x vrijwel dezelfde code kloppen om de huidige staat op te ruimen en terug te keren uit de functie.
-
$this->_db->query("ROLLBACK");
-
$errorMessage = "Withdrawal would exceed credit limit";
-
return $errorMessage;
Dat kunnen we korter maken door GOTO te gebruiken:
-
class GotoExampleClass
-
{
-
/* ... */
-
function UpdateBalance($userID, $amount)
-
{
-
$this->_db->query("BEGIN");
-
-
$userData = $this->_db->fetch_one_row("SELECT * FROM user WHERE UserID = $userID");
-
-
$errorMessage = "User doesn't exist";
-
if (!$userData) goto balance_error;
-
-
$this->_db->query("UPDATE user SET LastActivity = NOW() WHERE UserID = $userID");
-
-
$balance = $this->_db->fetch_one_column("SELECT SUM(Amount) AS current_balance FROM user_balance WHERE UserID = $userID");
-
-
/* Voor het voorbeeld, laten we nu vast de balance updaten :) */
-
$this->_db->query("INSERT INTO Balance(UserID, LastModified, Amount) VALUES ($userID, NOW(), $amount)");
-
-
$is_withdrawal = ($amount <0);
-
if ($is_withdrawal)
-
{
-
/* Als er een bedrag wordt afgeschreven, check dan of de user wel genoeg geld heeft */
-
$errorMessage = "Not enough Scriptorama Dollars and no credit either!";
-
-
if ($balance <abs($amount) && !$userData['has_credit']) goto balance_error;
-
-
-
-
if ($balance <abs($amount) && $userData['has_credit'])
-
{
-
$errorMessage = "Withdrawal would exceed Scriptorama Dollar Credit Limit! Aborted.";
-
goto balance_error;
-
}
-
-
}
-
-
$this->_db->query("COMMIT");
-
return TRUE;
-
-
balance_error:
-
$this->_db->query("ROLLBACK");
-
return $errorMessage;
-
}
-
}
Dat maakt het iets korter en uiteindelijk is de opruim code die onder balance_error staat ietsjes makkelijker te wijzigen dan dat je de code verspreid door je functie hebt staan.
Uiteraard zijn de waarschuwingen over het gebruik van GOTO niet geheel uit de lucht gegrepen dus: geniet, maar GOTO met mate!
De __DIR__ constante
Voorheen deed je vaak dirname(__FILE__) om er achter te komen waar het huidige PHP bestand nu precies was. Deze waarde is nu ook direct te benaderen via de nieuwe constante __DIR__
-
echo __DIR__;
-
// Output: /Users/mathieu/Source/tests
Conclusie
PHP 5.3 heeft echt een hele hoop nieuwe features die het ontwikkelen met PHP weer een stukje leuker, makkelijker en beter maakt.
Wat is jouw favoriete nieuwe feature in PHP 5.3?
Volg Scriptorama via RSS!
Reageer ook!
Misschien ook nuttig om een topic te maken met veranderingen die minder gunstig zijn, maar wel belangrijk om te weten.
Een voorbeeld is:
array_key_exists(mixed $key, array $search)Dit werkt niet meer op objecten in 5.3. In 5.3 zal
property_exists(mixed $class, string $property )gebruikt moeten worden.Zoals je ziet zijn de argumenten bij deze functie omgedraaid, maar dat sluit wel beter aan bij:
method_exists(object $object, string $method_name )Op de lokale mirror staat deze info (nog) niet, maar wel op: http://docs.php.net/property_exists
Door Dynom
op 09.05.08 @ 8:45 am | Permalink
En dat goto voorbeeld kan niet gewoon met try catch? :z Of ben ik de 10000e persoon die met dat argument komt? :P
Door Maarten
op 09.05.08 @ 9:33 am | Permalink
Tuurlijk kan dat, er zijn meerdere wegen die naar Rome leiden :). Tenzij je natuurlijk erg strict met excepties omgaat en deze alleen gebruikt als er ook daadwerkelijk een exceptionele situatie plaatsvindt ipv het als een control-flow te gebruiken.
Maar goed, dit is bedoeld als een voorbeeld, niet hét voorbeeld.
Door Mathieu Kooiman
op 09.05.08 @ 9:46 am | Permalink
Het lijkt me handiger om in plaats van
ifsetor()een algemenerecoalesce()te gebruiken (à la SQL COALESCE).function coalesce()
{
foreach (func_get_args() as $arg) {
if (isset($arg)) return $arg;
}
return null;
}
Door Maarten Sander
op 09.05.08 @ 11:35 am | Permalink
Tja, maar exception moet je ook niet voor elke poep en scheet gooien. En uiteraard is dit niet het voorbeeld, maar ik ben benieuwd naar het voorbeeld welke ook nog een beetje als good practice eruit ziet. Lees: voorlopig vind ik goto nog altijd stom en saai.
Door Maarten
op 09.05.08 @ 11:51 am | Permalink
@Maarten Sander:
Dat is dus waar de PHP developers het kennelijk niet eens over konden worden en dus rest ons enkel de userland implementatie voor ifsetor() die door een eigenaardigheid in PHP (references zorgen ervoor dat een Notice melding wordt onderdrukt) bruikbaar blijft in alle gevallen.
Een coalesce implementatie is eigenlijk niet te doen omdat je met func_get_arg() niet kunt aangeven dat het argument als reference gebruikt wordt worden en je dus niet de eigenaardigheid in PHP kunt triggeren :)
Door Mathieu Kooiman
op 09.05.08 @ 2:38 pm | Permalink
Goed artikel!
Nu nog iets als block-statements (ala Ruby) en ik ben helemaal gelukkig :-)
Door wup
op 09.06.08 @ 5:53 pm | Permalink
Zowel positief als negatief over deze zaken; __DIR__ en de GarbageCollector kan ik alleen maar toejuichen, maar ik vind het zelf een beetje raar dat je de GC zelf moet laten opruimen. Dat komt er wellicht op neer dat je code doorspekt gaat worden van gc_collect_cycles() aanroepen.
De goto-optie ben ik niet zo'n fan van, maar dat is persoonlijk. Ook de __callStatic ben ik niet echt kapot van. Naar mijn idee zou de situatie die je hiermee wilt oplossen niet voor mogen komen. Je krijgt nu een uitkomst die je wellicht ook niet wilt. Dan maar executie afkappen. Dat geldt ook in mindere mate voor de "statische methode dynamisch aanroepen". Bij mij rijst dan de vraag of dit een feature is die mindere programmeergoden moet helpen of extra functionaliteit moet bieden.
Vind trouwens de werking van FileInfo nogal apart. In de constructor wordt volgens jouw voorbeeld een eigenschap gegeven en vervolgens toegepast op een bestand, terwijl ik het logischer zou vinden als je een volgende werking zou hebben:
$fileinfo = new FileInfo ( 'foobar.png' );
echo ( $fileinfo->mimetype() ); // image/png
Verder even complimenten voor de artikelen.
Door Timo
op 09.06.08 @ 11:43 pm | Permalink
@Timo:
Het dynamisch aanroepen van statische methoden is iets wat volgens mij meer voorkomt dan je denkt. Het was ook allang mogelijk:
Het is nu alleen maar makkelijker gemaakt door het op de PHP manier aan te bieden.
Wat betreft FileInfo, tja, het is maar hoe je er naar kijkt. Het opvragen van bestandsinformatie is iets waarvan het goed mogelijk is dat je dit meerdere keren op verschillende bestanden in 1 request doet. FileInfo opent intern een bestand om deze te doorzoeken. Om dat nou voor ieder bestand opnieuw te doen is ook weer zoiets. Deze oplossing werkt daar omheen.
Door Mathieu Kooiman
op 09.07.08 @ 7:05 am | Permalink
@Mathieu:
Iets geheel anders, zijn er ook plannen om bij PHP6 (of zelfs 5.3) eens de bezem te halen door de inconsistentie op het gebied van functienamen? Kijk bijvoorbeeld maar eens naar de string functies str_replace en strlen. Misschien case sensitivy toevoegen.
Door Timo
op 09.07.08 @ 12:07 pm | Permalink
@Timo
Nou, nee. Iedereen weet dat het irritant is, maar het veranderen zou zo enorm veel van alle bestaande PHP scripts breken en daarmee zou men nooit upgraden naar die nieuwe versie. Kijk maar naar hoe lang de migratie van PHP 4 naar PHP 5 heeft geduurd.
Door Mathieu Kooiman
op 09.07.08 @ 12:13 pm | Permalink
Is er iemand die mij 1 praktisch nut van de ?: kan geven? Met bovenstaande beperking heeft het voor mij elke magie verloren en zie ik er totaal geen nut in.
Het is ook niet echt een nette contstructie daardoor: er komt altijd OF het resultaat van de expressie uit (true), OF wat je meegeeft.
Is wat je meegeeft 'false', dan had je net zo goed ?: weg kunnen laten. Is het iets anders, dan eindig je met een variabele waar iets fuzzies in zit: true of een waarde.
Ik loof een biertje uit voor degene die me een daadwerkelijk nuttig voorbeeld kan geven.
Door Ivo
op 09.07.08 @ 1:25 pm | Permalink
De :? operator lijkt me in deze opzet niet bijzonder zinnig, omdat je het zoals iedereen zegt, het het liefst voor isset( ) zou gebruiken. Een halfbakken oplossing met passing by reference zie ik ook niet zitten, ik zie ook niet in waarom mensen niet gewoon de goede oude ternary operator zouden gebruiken, dan maar iets meer typen.
Goto is janken, ik zie niet in waarom iemand dat in vredesnaam zou gaan gebruiken. Nowdoc is wel grappig, al gebruik ik heredoc ook nooit. De SPL toevoegingen wordt ik erg blij van, net zoals DateTime zal dit met zekere regelmaat mijn leven makkelijker maken.
Betreft het "dynamisch aanroepen" van statische methoden: ik denk dat Timo wellicht een beetje in de war is: het is niet zozeer het "dynamisch" aanroepen, maar een variabele methode-naam aanroepen, ook statisch. Het is dus niet zo dat je een statische methode met -> aan kan roepen, zoals in 4 het geval.
__DIR__.. tja, het scheelt me iets meer typen. GC is handig, voor langlopende scripts.
Door berry__
op 09.09.08 @ 9:10 am | Permalink
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>