Archive for the ‘PHP’ tag
PHP-Programmierung gehört zu den Hauptskills auf den Projektplattformen
Gastartikel von Wojciech Dziedzic
Wojciech Dziedzic hat an der Humboldt Universität zu Berlin Germanistische Linguistik, Anglistik und Polonistik im Magisterstudiengang abgeschlossen. Jetzt arbeitet er im Online Marketing bei twago – einer Projektvermittlungsplattform für Freelancer und KMU’s.
Die Projektvermittlungsplattformen oder Online-Marktplätze wachsen jeden Monat, weil immer mehr Spezialisten und Auftraggeber von solcher Art der Zusammenarbeit überzeugt sind. Zielgruppe dieser Anbieter sind vor allem Freelancer und KMU’s. Programmierer, Webdesigner, Übersetzer, SEO- und IT-Experten, Grafikdesigner und viele mehr gehören zu tausenden registrierten Dienstleistern bei den Projektplattformen. Einer der Hauptskills, sprich die Anzahl der registrierten Nutzer mit dieser Fähigkeit, ist die PHP-Programmierung. Das spiegelt sich auch in der Anzahl der ausgeschriebenen Projekte, für die dieser Skill benötigt wird. Plattform, Projekt, Skills – das sind nur Begriffe, aber wie das ganze Verfahren funktioniert, das wird im Folgenden kurz beschrieben.
PHP 5.3.1 und Zend Framework Bug Hunt Day
Kurze Info: PHP 5.3.1 ist gerade released worden. Über 100 Bugs wurden gefixt. Auf php.net/downloads und windows.php.net/download steht alles zum Download bereit.
Außerdem läuft gerade der November Bug Hunt Day des Zend Frameworks. Nach einem Tag sind bereits 59 Issues geschlossen worden, ich bin sehr gespannt wo der Counter morgen Abend steht!
Achja, noch eine Kleinigkeit: Falls ihr memcached 1.4.3 verwendet und mittels PHP darauf zugreift, euch sei gesagt dass die delete()-Funktion des Memcache-PECL-Moduls mit der Version nicht funktioniert. Mit 1.4.2 funktioniert alles wunderbar. Also downgraden (bzw. nicht upgraden) und auf ein Update von PECL warten. Nur so nebenbei.
PHP und die lose Typisierung
Heute mal eine sehr praktische Erfahrung:
Der Kollege nebenan fragte, ob ich mal kurz rübergucken kann, er verstehe die Ausgabe einer Funktion nicht. Vereinfacht sah der Code so aus (über Sinn und Unsinn soll hier nicht diskutiert werden, es ist nur vereinfacht dargestellt):
function show(array $headerArray) { foreach ($headerArray as $headerKey => $headerValue) { $outputString = $headerKey . ':'; foreach ($headerValue as $valueKey => $value) { if ($valueKey != 'append') { $outputString .= $value; } } return $outputString; } }
Die Funktion erwartet ein Array mit Header-Informationen. Diese sollen durchlaufen werden, und die Inhalte sollen als Wertepaare-String zurückgegeben werden, wenn der innere Key nicht „append“ ist.
Soweit ist der Code OK. Jetzt kommt der Aufruf:
$headerArray = array("From" => array( 0 => 'john.doe@some.city', 'append'=> true )); echo show($headerArray);
Wie lautet die Ausgabe? Korrekt, nämlich so:
From:
Wenn ich den Aufruf leicht ändere:
$headerArray = array("From" => array( '0' => 'john.doe@some.city', 'append'=> true )); echo show($headerArray);
Wir nutzen also als Key nun den String ‚0‘. Jetzt sollte das richtige rauskommen. Aber man liegt immernoch falsch:
From:
Da wurde ich stutzig. Man sollte denken, jetzt wird der String ‚0‘ mit dem String ‚append‘ verglichen. Da es ungleich ist, sollte die Email-Adresse ausgegeben werden. Falsch gedacht.
PHP scheint den Key eines Arrays als Integer zu casten wenn möglich. Egal ob wir 0 oder ‚0‘ als Key verwenden, beim Auslesen des Arrays erhalten wir immer einen Integerwert. Das sollte man sich auf der Zunge zergehen lassen.
Als Folge vergleicht er also immer den Integer 0 mit dem String ‚append‘. Damit ein Vergleich möglich ist, castet PHP den String korrekterweise als Integer, und das ergibt ja bekannterweise 0.
Das ursprüngliche Problem lag natürlich beim != . Man hätte das ganze vermeiden können, indem man !== verwendet, dann wäre das Problem nicht aufgetreten, und ich hätte einen Artikel weniger.
Verteiltes Rechnen mit Javascript und Google Gears
Wie ich ja bereits des öfteren anmerkte, habe ich früher ein Browsergame programmiert. Begonnen habe ich 2003, als es erst recht wenige Browsergames gab, und diese auch alle von Privatleuten als Hobby betrieben wurden. Da man natürlich Alleinstellungsmerkmale braucht gegen „die Konkurrenz“, baut man viele Ideen ein, die andere nicht haben. Unter anderem war in meinem Browsergame (es handelte sich um ein Aufbauspiel a la OGame, Stoneage etc.) das erste Mal auch ein Turniermodus (1on1) möglich, so dass man abseits der lang laufenden Welten auch in einem KO-Modus gegen andere antreten konnte. Dazu wurden Speed-Server für die ausgelosten Paare gestartet, wo dann 2 Spieler gegeneinander antreten mussten und gewisse Siegbedingungen erreichen mussten. ICQ-Benachrichtigungen bei bestimmten Ereignissen hatte ich auch recht früh eingebaut.
In der folgende Version (die leider nie das Licht der Welt erblickt hat) kamen noch viele weitere interessante Features hinzu. Der Quellcode wurde komplett neu geschrieben in PHP5, war nun voll objektorientiert (in PHP4 war das ja nur sehr beschränkt möglich), und auch neue „Web2.0“ Funktionalitäten waren mit drin.
So gab es zum Beispiel eine Möglichkeit, dass Spieler sich selbst Weltkarten zusammenbauen konnten mit einem einfachen Editor. Der Spieler hat dazu mehrere Feldtypen (Gras, Fels, Wasser, Berg, Moor) und kann daraus eine Karte basteln, auf der er dann gegen andere antreten kann (und wenn sie gut bewertet wird, kann es auch eine Karte für einen „großen“ Server werden, wo tausende Spieler drauf spielen). Eines der Probleme, die es dabei gab, war die Berechnung der Wege. Man muss, um seine Armee zu bewegen, nur das Zieldorf anwählen und kann dort angreifen. Der Dijkstra-Algorithmus bestimmt dann die Zeit, die die Armee unterwegs ist. Dazu muss man den genauen Weg kennen, denn es gibt auch unpassierbares Gelände (in diesem Fall Berge) oder Flächen, auf denen die Armee langsamer ist (Moor). Da die Karten mitunter sehr groß sind (zB 1000*1000), dauert diese Berechnung recht lang. Diese Berechnung bei jeder Armeebewegung zu machen macht die Webseite ziemlich lahm. Also habe ich für die „Standardkarten“ diese Berechnungen bereits erledigt und die 500.000 Ergebnisse (von jedem Feld zu jedem anderen) in einer Datenbank gespeichert.
Wenn nun aber viele Spieler neue Karten basteln, schafft das der Server nicht mehr, er muss ja auch nebenbei noch für die eigentlichen Webseiten und Datenbanken herhalten. Eine Berechnung für eine Karte dauert mitunter 20 Stunden (Dijkstra Algorithmus in PHP).
Was also tun? Richtig, wir verteilen die Arbeit auf die Client-Rechner. Die 500 Spieler, die auf der Webseite rumsurfen und das Spiel spielen, können nebenbei auch bei der Berechnung helfen. Doch wie macht man das? Aufwendige Dinge wie ein eigenes Client-Programm schreiben, oder Plugins für BOINC etc. sind zu aufwändig und übertrieben. Wie so häufig gibt es eine einfache Lösung: Gears von Google.
Mit Gears kann man asynchron Javascripte ausführen, die die Webseite nicht beeinträchtigen, indem man sogenannte WorkerPools mit Arbeit versorgt.
Hier habe ich mal ein einfaches Beispiel:
main.html
<script type="text/javascript" src="gears_init.js"></script> <script type="text/javascript"> var workerPool = google.gears.factory.create('beta.workerpool'); workerPool.onmessage = function(a, b, message) { alert('result from worker ' + message.sender + ': \n' + message.body); }; var childWorkerId = workerPool.createWorkerFromUrl('worker2.js'); workerPool.sendMessage([5, 1, 8], childWorkerId); </script>
worker2.js:
var wp = google.gears.workerPool; wp.onmessage = function(a, b, message) { // do calculation here var reply = message.body[0] + message.body[1] + message.body[2]; wp.sendMessage(reply, message.sender); }
Wenn man die entsprechende Webseite aufruft, wird man gefragt, ob der Zugriff auf Gears erlaubt werden soll. Wenn man Gears installiert hat, kann man also noch von Fall zu Fall unterscheiden, ob man der Webseite seine Resourcen zur Verfügung stellen möchte oder nicht.
Was passiert nun? Die Webseite startet einen WorkerPool, in diesem Workerpool wird ein Worker gestartet, der das Script worker2.js ausführen soll. Wir senden an den darin befindlichen Worker ein Array mit 3 Zahlen.
Der Worker errechnet dann die Summe dieser Zahlen, und sendet das Ergebnis zurück an den WorkerPool. Diese Nachricht fangen wir mit dem „onMessage“ Eventhandler ab und zeigen das Ergebnis mittels alert() an.
Wie würde nun die Kartenberechnung funktionieren? Wir übergeben statt dem einfachen Array ein komplexes großes Array mit dem Graphen, den Kantengewichten usw. Im Worker findet dann die eigentliche Dijkstra-Berechnung statt. Dort wäre es sinnvoll, nicht die ganze Karte zu berechnen (Dauer 20 Stunden), sondern nur kleine Häppchen, die in wenigen Sekunden bearbeitet sind. Statt das Ergebnis dann via alert() auszugeben, schicken wir es via AJAX zurück an den Webserver, der das Ergebnis in die Datenbank einträgt.
Leider ist es bei diesen ersten Tests geblieben, ich habe die eigentlichen umfangreichen Dijkstra-Berechnungen nie in Javascript mit Gears umgesetzt. Aber möglich ist es.
Eine einzige Hürde gibt es: Auf dem Clientrechner muss Gears installiert sein. Mit einer guten Community und Nutzern, die einem vertrauen, ist aber auch das machbar.
Alternativ kann man natürlich auch ohne Gears die Berechnungen in Javascript durchführen lassen. Dabei muss man jedoch beachten, dass der Browser dadurch nicht unbenutzbar wird. Man muss also die Berechnung künstlich bremsen, außerdem muss man eine Lösung dafür finden, dass der Browser lang laufende Javascripte gern auch mal abbrechen möchte.
Mit Gears passiert sowas nicht.
Anwendungsfälle des Dijkstra-Algorithmus sind beispielsweise das bekannte „Friend of a Friend“ Problem (soziale Netzwerke zeigen an, über wieviele Kontakte man eine andere Person kennt) oder alle anderen Arten, wo man in einem Graphen den kürzesten Pfad ermitteln möchte. Man kann so sicherlich auch noch andere, komplexe Berechnungen auf die Clients auslagern.
Gears kann man natürlich auch noch für viele weitere Dinge nutzen, wie schöne Benachrichtigungen, als lokalen Speicher für Dateien oder Daten (Datenbank), Geolocation (was ja mittlerweile die Browser schon nativ beherrschen) usw.
Habt ihr Erfahrungen mit Gears, oder Ideen welche revolutionären Dinge man damit umsetzen könnte?
PHP-Unconference 2009 am Wochenende
Die PHP-Unconference findet dieses Jahr wieder statt, und zwar vom 12.09. – 13.09.2009 (also nächstes Wochenende!) im Hamburger Geomatikum.
Da ich den Termin letztes Jahr verpasst habe, bin ich umso glücklicher, dieses Jahr dabei sein zu können. Da ich dort privat hinfahre, kommt mir der Preis von 25 Euro natürlich sehr entgegen. Andere (größere) PHP-Konferenzen kosten häufig pro Tag mehr als 500 Euro, und hier gibt es 2 Tage für 25 Euro. Cool!
Organisiert wird es von der PHP-User-Group Hamburg und der Informatik-Abteilung Uni Hamburg.
Falls sich jemand fragt, was eine Unconference ist: Es handelt sich hierbei nicht um eine klassische Konferenz mit fester Agenda und starren Vorträgen, sondern vielmehr um kleine Präsentationen, Diskussionen und Gesprächen rund um alle Themen. Jeder Teilnehmer kann auch selbst auf der Bühne stehen. Es bleibt aufgrund der Größe (ca. 200 Leute werden da sein) im kleineren Rahmen. In der ersten Session wird abgestimmt, welche Themen auf die Bühne kommen. Ich bin gespannt, ist meine erste Unconference!
Ich freue mich auch schon besonders auf mein Wunschthema „PHP im Enterprise. Skalierbarkeit und Sicherheit“, das ziemlich beliebt ist, denn aktuell ist es auf Platz 1 der Vorschlags-Liste. Auch 3 bekannte Persönlichkeiten/Firmen haben schon angeboten, Vorträge dazu zu halten. Hier könnt ihr schauen, welche Themen sonst noch interessant sind.
Ob ich wohl einen meiner Leser dort treffen werde? Ich lasse mich überraschen.
PS: Falls jemand von euch eine günstige Möglichkeit kennt, dort für <30 Euro zu übernachten (nein, Auto zählt nicht), möge er sich schnell melden!