Archive for the ‘PHP’ Category
PHP 7 Feature Freeze
PHP 7 wird großartig, ich freue mich schon sehr darauf! Ich hoffe dass der straffe Zeitplan eingehalten werden kann, und wir im Oktober/November die Version 7.0 in den Händen halten.
Vor 2 Wochen war der Feature-Freeze, und alle Abstimmungen die noch liefen sind beendet, es stehen also nun mehr oder minder alle Features fest die drin sein werden. Im großen und ganzen wissen wir nun was uns in PHP 7 alles erwarten wird.
Hier stelle ich folgende Features von PHP 7 vor:
- Performance
- Skalare Typehints
- jsond
- Coalesce-Operator
- Engine-Exceptions
- Kontext-sensitiver Lexer
- Uniform Variable Syntax
- Abstract Syntax Tree
- Neue einheitliche Zufallsfunktionen
- weiteres
Ein altes Navigationsmenu sortieren
Ich habe eine kleine Programmieraufgabe für euch.
Ich habe ein altes Projekt, in dem ich folgende Navigationsstruktur in der Datenbank habe:
menuid | parentid | title | level | sortid |
---|---|---|---|---|
1 | 3 | Wurm 1.1 | 2 | 10 |
2 | 6 | Vogel 2.1 | 2 | 30 |
3 | 0 | Tiger 1 | 1 | 10 |
4 | 6 | Hund 2.2 | 2 | 40 |
5 | 3 | Katze 1.2 | 2 | 11 |
6 | 0 | Pferd 2 | 1 | 20 |
7 | 1 | Baer 1.1.1 | 3 | 0 |
8 | 3 | Schwein 1.3 | 2 | 12 |
9 | 4 | Esel 2.2.1 | 3 | 0 |
Nun möchte ich diese Menüpunkte sortiert ausgeben, und zwar in der folgenden Reihenfolge:
Tiger 1 Wurm 1.1 Baer 1.1.1 Katze 1.2 Schwein 1.3 Pferd 2 Vogel 2.1 Hund 2.2 Esel 2.2.1
Die Sortierreihenfolge muss anhand der menuid, parentid, level und sortid berechnet werden. Eine parentid verweist auf den Elternknoten, sprich er ist darunter einzusortieren. Zwei Einträge mit der selben parentid sind nach der Spalte sortid zu sortieren.
Der Wurm ist ein Kindknoten vom Tiger, der Bär ist ein Kindknoten vom Wurm. Die Katze ist auch ein Kindknoten vom Tiger, hat aber die höhere sortid, muss also nach dem Wurm einsortiert werden.
Es ist ein altes Projekt mit dieser Struktur, und die Frage ist wie man das am einfachsten und schnellsten sortiert?
Geht das ganze mit einem SQL-Query? Das wäre natürlich die beste Lösung, aber mir ist kein solcher Query eingefallen der das Problem lösen könnte.
Also muss es in PHP sortiert werden. Ich habe das ganze in ein PHP-Array gepackt und hier für euch zum Spielen bereitgestellt:
Dort könnt ihr an dem Algorithmus arbeiten, sodass aus dem Ursprungs-Array das Ziel-Array wird. Nachdem ihr „eval()“ gedrückt habt könnt ihr einfach die URL hier in die Kommentare packen, nach jedem Druck auf „eval()“ wird das ganze gespeichert und versioniert.
Ich bin gespannt auf eure Lösungen!
Erstaunlich langsam beim Kopieren einer Datei auf ein NFS-Share
Heute mal etwas skurriles. Eigentlich eine Alltagsaufgabe, die man mit einem 2-Zeiler lösen kann, aber ich bin doch erstaunt über das Problem und die Lösung. Es geht darum, eine Datei auf einem NFS-Share abzulegen, das vorher per PUT zum Webserver hochgeladen wurde. Wahrscheinlich hat man das selbe Problem auch wenn die Datei per POST-Formular hochgeladen wurde.
Folgender Aufruf lädt eine Datei via PUT auf einen Webserver:
curl -T 100mb.test http://localhost/put.php
Mein einfaches Testscript, das die Datei auf das NFS-Share legen soll, sieht so aus:
Eine PLZ-Umkreissuche in PHP
Ich bekam vor ein paar Tagen folgende kleine Programmieraufgabe:
Gegeben ist eine große Datenbank mit > 300.000 Kunden, worin jeder Kunde eine Postleitzahl hinterlegt hat. Firma X möchte nun diese Kunden kontaktieren, aber nur diejenigen die in 35km Umkreis um eine seiner 42 Filialen wohnen.
Tja, wie macht man das?
Aktueller Stand von PHP 7: Deutlich geringerer Arbeitsspeicherverbrauch
Ich möchte mir den aktuellen Stand von PHP 7 anschauen (Stand 20. Januar 2015), und habe dazu im letzten Blogartikel gezeigt wie man PHP 7 direkt aus dem Git-Repository selbst kompiliert. Ich habe nun also PHP 7 zur Verfügung:
$ sapi/cli/php -v PHP 7.0.0-dev (cli) (built: Jan 20 2015 23:13:58) Copyright (c) 1997-2015 The PHP Group Zend Engine v3.0.0-dev, Copyright (c) 1998-2015 Zend Technologies
Vergleichen werde ich mit der aktuell unter Ubuntu 14.04 LTS verfügbaren Version PHP 5.5.9:
$ php -v PHP 5.5.9-1ubuntu4.5 (cli) (built: Oct 29 2014 11:59:10) Copyright (c) 1997-2014 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
Da die eine Version selbst kompiliert ist und die andere von Ubuntu stammt sind sie in diesem Fall nicht ideal für einen Vergleich nutzbar, aber auf ein paar Bytes oder Prozente soll es mir nicht ankommen.
PHP 7 hat in diesem Fall keinen OPcache aktiviert, aber den benötige ich für meine Tests auf der Kommandozeile (CLI) nicht. Möchte man PHP via Webserver (PHP-FPM usw.) nutzen sollte man darauf achten den OPcache per php.ini zu aktivieren, um vergleichbare Ergebnisse zu bekommen.
Folgendes kleines Testscript werde ich mit beiden Versionen laufen lassen:
<?php $a = array(); for ($i=1; $i<2000000; $i++) { $a[] = rand(100000000, 999999999); } echo "not real: ".(memory_get_peak_usage(false)/1024/1024)." MiB\n"; echo "real: ".(memory_get_peak_usage(true)/1024/1024)." MiB\n";
Und hier sind die jeweiligen Ergebnisse:
$ time php arraytest.php not real: 275.61262512207 MiB real: 276 MiB real 0m1.119s user 0m0.763s sys 0m0.190s
$ $ time sapi/cli/php arraytest.php not real: 96.334381103516 MiB real: 98 MiB real 0m0.414s user 0m0.290s sys 0m0.068s
Ui ui ui! Mit PHP 7 reduziert sich der Arbeitsspeicherverbrauch bei diesem Testarray (2.000.000 Zahlen als Values) um satte 65%!
Weniger Arbeitsspeicherverbrauch heißt nicht nur dass „mehr PHP“ auf einem Server laufen kann, weniger Arbeitsspeicher heißt auch dass weniger Daten im Arbeitsspeicher abgelegt werden müssen, und weniger daraus gelesen werden muss, es impliziert also automatisch auch einen Performance-Boost. Wie man an den Laufzeiten erkennen kann ist PHP 7 auch ungefähr 3 Mal so schnell!
In richtigen Applikationen wie WordPress oder Typo3 usw. ist der Unterschied nicht ganz so groß, da spricht man von ungefähr 50% bis 110% mehr Laufzeit-Performance. Denn bei größeren Applikationen wird auch viel Zeit beim Warten auf die Datenbank verbraucht, und Warten ist genauso langsam in PHP 5.5 wie in PHP 7 😉
All diese Verbesserungen sind darauf zurückzuführen wie PHP intern Variablen und Arrays organisiert, den sogenannten ZVALs und Hashtables. Die detaillierten Informationen über die Änderungen an der Hashtable-Implementation von PHP 7 sollte man sich mal zu Gemüte führen.
Edit: Auf Wunsch habe ich auch noch PHP 5.6 getestet, hier die Ergebnisse:
wget http://de2.php.net/get/php-5.6.5.tar.gz/from/this/mirror mv mirror php-5.6.5.tar.gz tar -xzvf php-5.6.5.tar.gz cd php-5.6.5/ ./configure --prefix=/usr/local/php-5.6.5 --with-zlib --with-config-file-path=/usr/local/php-5.6.5/etc --enable-mbstring --with-mysql --with-mysqli --with-pdo-mysql --enable-zip --with-imap --with-kerberos --with-imap-ssl --with-openssl --with-jpeg-dir --with-gd --with-gettext --with-freetype-dir --enable-ftp --with-pspell --with-curl make
$ sapi/cli/php -v PHP 5.6.5 (cli) (built: Jan 23 2015 00:46:40) Copyright (c) 1997-2014 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
$ time sapi/cli/php -d memory_limit=512M arraytest.php not real: 275.61260223389 MiB real: 276 MiB real 0m1.023s user 0m0.663s sys 0m0.170s
PHP 5.6 ist also leicht schneller als PHP 5.5, aber zu PHP 7 ist es immer noch ein richtig großer Unterschied.