Arrayy: A Quick Overview of map(), filter(), and reduce()

Arrayy: A PHP array manipulation library. Compatible with PHP 7+

The next examples are using the php array manipulation library “Arrayy” which is using generators internally for many operations.

StringCollection::create(['Array', 'Array'])->unique()->append('y')->implode(); // Arrayy

map: transform all values in the collection

StringCollection::create(['foo', 'Foo'])->map('mb_strtoupper'); 

// StringCollection['FOO', 'FOO']

filter: pass all values to the truth test

$closure = function ($value) {
    return $value % 2 !== 0;
IntCollection::create([1, 2, 3, 4])->filter($closure); 

// IntCollection[0 => 1, 2 => 3]

reduce: transform all values into a new result

IntCollection::create([1, 2, 3, 4])->reduce(
    function ($carry, $item) {
        return $carry * $item;

// IntCollection[24]

Modern PHPDoc Annotations

We will start very simple with PhpStorm and default PHPDoc, then we will increase the complexity step by step until we have auto-completion for array keys directly from the database with generics, immutable and type safety support.

1.0 PhpStorm & auto-generate PHPDoc blocks

„For documentation comments, PhpStorm provides completion that is enabled by default. PhpStorm creates stubs of „PHPDoc blocks“ when you type the /** opening tag and press Enter, or press Alt+Insert and appoint the code construct (a class, a method, a function, and so on) to document. Depending on your choice, PhpStorm will create the required tags or add an empty documentation stub.“


 * @param array $row
 * @return array
abstract function formatRow(array $row): array;

1.1 Return $this|static|self

It‘s quite annoying that php itself currently only have „self“ as return type ( for the current class. Because of „late static binding“ you can use „static“ in your code to refer to the class a method was actually called on, even if the method is inherited. But in PHPDoc you can already use:

  • @return $this: if you really return $this (e.g. for fluent interface)
  • @return static: refer to the class a method was actually called on
  • @return self: refer to the class a method was written in


 * @return static
abstract function getFoo(): self;

1.2 New (and not that new) Array Syntax

PhpStorm and (PHPStan & Psalm) are supporting some new (and some not that new) array syntax for PHPDoc types, but for now PhpStorm will not auto-generate this types. 


  • int[]: an array with only INT values – [1, 4, 6, 8, 9, …]
  • array<int, int>: an array with only INT values – [4 => 1, 8 => 4, 12 => 6, …]
  • string[]: an array with only STRING values – [„foo“, „bar“, …]
  • array<int, string>: an array with only STRING values – [4 => „foo“, 8 => „bar“, …]
  • Order[]: an array with only „Order“-Object values – [Order, Order, …]
  • array<int|string, Order>: an array with INT or STRING as key and „Order“-Object values – [4 => Order, ‘foo‘ => Order, …]
  • array<int|string, mixed>: an array with INT or STRING as key and mixed as values – [1 => 1, 4 => „foo“, 6 => \stdClass, …]
  • array<int, array<int, string>>: an array with INT as key and and an array (with INT as key and string as value) as values – [1 => [1 => „foo“], 4 => [1 => 4], …]
  • array<int, string[]>: an array with INT as key and and an array (with INT as key and string as value) as values – [1 => [„foo“, „lall“], 4 => [„öäü“, „bar“], …]
  • array{output: string, debug: string}: an array with the key “output” and “debug”, the values are STRING values – [‘output’ => ‘foo’, ‘debug’ => ‘bar’]
  • array<int, array{output: string, debug: string}>: an array with the key “output” and “debug”, the values are STRING values – [1 => [‘output’ => ‘foo’, ‘debug’ => ‘bar’], 3 => [‘output’ => ‘foo’, ‘debug’ => ‘bar’], …]

Examples (@psalm-* || @phpstan-*): PHPStan can also use “psalm-*” prefixed annotations and Psalm understands “phpstan-*” annotations.

  • list<array{output: string, debug: string}>: an array with the key “output” and “debug”, the values are STRING values – [0 => [‘output’ => ‘foo’, ‘debug’ => ‘bar’], 1 => [‘output’ => ‘foo’, ‘debug’ => ‘bar’], …]

list: represents continuous, integer-indexed arrays (always start from index zero) like: [“red”, “yellow”, “blue”] 





 * @param array<int|string, mixed> $row
 * @return array<int|string, mixed>
abstract function formatRow(array $row): array;

PhpStorm support?: Sadly PhpStorm did not have good support for these types, so that you often have to add „@psalm-*“ PHPDoc comments. For example PhpStorm will accept “array<int, Order>” but PhpStorm will not understand the PHPDoc, so that you need to add e.g. “@param Order[] $order” and “@psalm-param array<int, Order> $order”. 

Examples for PhoStorm + PHPStan || Psalm: 

* @param Order[] $order
* @psalm-param array<int, Order> $order
* @return void
public function fooOrder($order): void { ... }

// you could also use "..." here

* @param Order ...$order
* @return void
public function fooOrder(Order ...$order): void { ... }
* @param int $foo_id
* @return Foo[]|Generator
* @psalm-return Generator&iterable<Foo>
abstract function fetchYieldByFoo($foo_id): Generator;

1.3 Dynamic Autocompletion (+ data from your database) via deep-assoc-completion

If you have a method e.g. “formatRow($row)” you can use “getFieldArray()[0]” (data from the database – you have to connection the IDE with your database and your queries need to be analyzable by PhpStorm (take a look at the next screenshot) and combine static data from “getHeaderFieldArray()”, so that you have auto-completion from different sources.


 * @param array<int|string, mixed> $row = $this->getFieldArray()[0] + $this->getHeaderFieldArray()
 * @return array<int|string, mixed>
abstract function formatRow(array $row): array;

more information + examples:

1.4 Immutability Check via Static Code Analyses (via psalm)

And there is even more. :) You can add PHPDoc annotation that will check if you really use immutable classes or at least methods. Please read more here:


 * @param array<int|string, mixed> $row = $this->getFieldArray()[0] + $this->getHeaderFieldArray()
 * @return array<int|string, mixed>
 * @psalm-mutation-free
abstract function formatRow(array $row): array;


– Psalm:

1.5 Generics in PHP via Static Code Analyses

We can also use Generics via code annotations. PHPStan & Psalm both support it, but Psalm’s support is more feature complete and both tools can use the „@psalm-“-syntax. Here comes some simple examples.

array_last: Will return the last array element from the $array (type: TLast) or the $fallback (type: TLastFallback). We tell the function that the types comes from the input parameters and that the input is an array of TLast or TLastFallback from the fallback.

 * @param array<mixed> $array
 * @param mixed             $fallback <p>This fallback will be used, if the array is empty.</p>
 * @return mixed|null
 * @template TLast
 * @template TLastFallback
 * @psalm-param TLast[] $array
 * @psalm-param TLastFallback $fallback
 * @psalm-return TLast|TLastFallback
function array_last(array $array, $fallback = null)
    $key_last = \array_key_last($array);
    if ($key_last === null) {
        return $fallback;
return $array[$key_last]; }

array_first: Will return the first array element from the $array (type: TFirst) or the $fallback (type: TFirstFallback). We tell the function that the types comes from the input params and that the input is an array of TFirst or TFirstFallback from the fallback.

 * @param array<mixed> $array
 * @param mixed             $fallback <p>This fallback will be used, if the array is empty.</p>
 * @return mixed|null
 * @template TFirst
 * @template TFirstFallback
 * @psalm-param TFirst[] $array
 * @psalm-param TFirstFallback $fallback
 * @psalm-return TFirst|TFirstFallback
function array_first(array $array, $fallback = null)
    $key_first = array_key_first($array);
    if ($key_first === null) {
        return $fallback;
return $array[$key_first]; }

So we can define „Templates“ and map input arguments on that types, this can be even more complex if you use it in a class context and you map the „Templates“ on class properties. But the logic will be the same.

Here is a more complex example:

PhpStorm support?: Noop, sadly we need to hack this via „PHPSTORM_META“, so here is an example:

  • override(\array_filter(0), type(0)); // suppose first parameter type is MyClass[] then return type of array_filter will be MyClass[]
  • override(\array_reduce(0), elementType(0)); // suppose first parameter type is MyClass[] then return type of array_reduce will be MyClass

Read more here:

2.0 Resume

It‘s not perfect, and type check and auto-completion only with PHPDoc is not really what I expected for the year 2020. But it‘s working and I hope PhpStorm will bring more support for the new types annotations in the future.

More Links:


Ubuntu + Windows + .dotfiles

1. Open “Update & Security” > “For Developers” > activate the “Developer Mode”.

2. Under “Programs” > “Programs and Features”, click “Turn Windows Features On or Off”.

3. Enable the “Windows Subsystem for Linux (Beta)” option in the list and click “OK”.

4. After an “reboot”, you open the command line (cmd) and type “bash” and press [Enter].

5. Enter a “Username” and a “Password. (you need the password for “sudo”-commands)

6. Now you can open “Bash on Ubuntu on Windows”.

7. Install “git” via:

sudo apt-get install git

8. Get the “.dotfiles” via:

cd ~ ; git clone; cd dotfiles

9. Install dependencies via:


10. Install zsh (optional, but recommended).

11. Use the “.dotfiles” via:


12. Download, install and configure “ConEmu” …

… a alternative “Command Line GUI” for Windows. Instead of the default GUI we have UTF-8 support with “ConEmu”, so we can use chars like “✓”.


After you have installed it, we can force “bash” to “zsh” in the configuration.

13. Add some “symlinks” for easier navigation via: e.g.

sudo ln -s /mnt/c /c
sudo ln -s /mnt/d /d

14. Add the current “hostname” into the “/etc/hosts”-file.

sudo su
echo " $(hostname)" >> /etc/hosts

Now you can edit your “.dotfiles”-settings and tweak your configuration.

Here is my example-config:


PHP: Arrays zusammenzuführen

In den folgenden Beispielen werden Standard-Funktionen von PHP gezeigt, um .


$array1 = [1 => 'one', 2 => 'two', 'foo' => 'bar1'];

$array2 = [3 => 'three', 4 => 'four', 6 => 'six', 'foo' => 'bar2'];

Wenn man Arrays mit “+” verbindet, werden die Werte in der Reihenfolge in welcher man diese Verbindet in das neue Array übernommen. Dabei sollte man jedoch beachten, dass gleiche Schlüssel (keys) nicht überschrieben werden.

$array2 + $array1;


    [3] => three    // array2
    [4] => four     // array2
    [6] => six      // array2
    [foo] => bar2   // array2
    [1] => one      // array1
    [2] => two      // array1

Hier ein zweites Beispiel mit ‘+’, nun haben wir die ensprechenden Arrays jedoch umgekehrt, so dass der ‘foo’-Wert vom ersten Array behalten wird.

$array1 + $array2;


    [1] => one      // array1
    [2] => two      // array1
    [foo] => bar1   // array1
    [3] => three    // array2
    [4] => four     // array2
    [6] => six      // array2

Diese kleine “foreach”-Schleife ist ein nachbau der ‘+’-Methode. Auch hier werden neue Werte angefügt, alte Werte jedoch behalten.

$union = $array1;
foreach ($array2 as $key => $value) {
  if (array_key_exists($key, $union) === false) {
    $union[$key] = $value;


    [1] => one      // array1
    [2] => two      // array1
    [foo] => bar1   // array1
    [3] => three    // array2
    [4] => four     // array2
    [6] => six      // array2

Und auch diese “foreach”-Schleife werden die Arrays vertauscht, so dass die Werte von ‘array2’ bestehen bleiben.

$union = $array2;
foreach ($array1 as $key => $value) {
  if (array_key_exists($key, $union) === false) {
    $union[$key] = $value;


    [3] => three    // array2
    [4] => four     // array2
    [6] => six      // array2
    [foo] => bar2   // array2
    [1] => one      // array1
    [2] => two      // array1

Die folgende PHP-Funktion (array_replace()) behält die Reihenfolge von ‘array1’, ersetzt jedoch Schlüssel (keys) welche ebenfalls in ‘array2’ vorkommen mit dessen Werten.

array_replace($array1, $array2);


    [1] => one      // array1
    [2] => two      // array1
    [foo] => bar2   // array2 (position from array1)
    [3] => three    // array2
    [4] => four     // array2
    [6] => six      // array2

Hier wird ebenfalls ‘array_replace()’ verwendent, jedoch sind ‘array1’ und ‘array2’ wieder vertauscht und auch hier werden die Schlüssel (keys) beibehalten und die Position von ‘foo’ wird beibehalten.

array_replace($array2, $array1);


    [3] => three    // array2
    [4] => four     // array2
    [6] => six      // array2
    [foo] => bar1   // array1 (position from array2)
    [1] => one      // array1
    [2] => two      // array1

Die Funktion ‘array_merge()’ vergibt neue Schlüssel (keys) für indizierte Arrays (0,1,2,3…). Somit fängt das neue Array nun mit dem Schlüssel “0” an.

array_merge($array1, $array2);


    [0] => one      // array1 (with a new key)
    [1] => two      // array1 (with a new key)
    [foo] => bar2   // array2 (position from array1)
    [2] => three    // array2 (with a new key)
    [3] => four     // array2 (with a new key)
    [4] => six      // array2 (with a new key)

Auch hier wurden die Arrays wieder vertauscht und auch hier wurden die numerischen Schlüssel durch neue ersetzt.

array_merge($array2, $array1);


    [0] => three    // array2 (with a new key)
    [1] => four     // array2 (with a new key)
    [2] => six      // array2 (with a new key)
    [foo] => bar1   // array1 (position from array2)
    [3] => one      // array1 (with a new key)
    [4] => two      // array1 (with a new key)

Die PHP-Library “Arrayy” ( …



Arrayy {
  array(6) {
    [1]=> one
    [2]=> two
    [foo]=> bar2
    [3]=> three
    [4]=> four
    [6]=> six



Arrayy {
  array(6) {
    [0]=> three
    [1]=> four
    [2]=> six
    [foo]=> bar1
    [3]=> one
    [4]=> two


HTTP/2: Welchen Vorteil bringt der neue Webstandard?

Diesen Artikel habe ich bereits im Firmen Blog von menadwork GmbH veröffentlicht: Düsseldorf, am 04.11.2015 von Lars Moelleken

Der im Mai 2015 veröffentlichte Webstandard HTTP/2 bewirkt, dass Webseiten schneller angezeigt werden. Die Kompatibilität von HTTP/2 ist in fast allen aktuellen Webbrowsern gegeben, wer dies jedoch einsetzen will muss zwangsläufig ein SSL-Zertifikat einsetzen, so dass die Webseite verschlüsselt übertragen wird.

In Kürze vorab:

Haben Browser und Ser73_221_de_ver im vorherigen HTTP/1.x Standard aus dem Jahr 1996 noch sehr viel Zeit mit „Warten“ verbracht, können durch den neuen Webstandard HTTP2 Webseiten schneller angezeigt werden.

Die Kompatibilität von HTTP/2 ist in fast allen aktuellen Webbrowsern gegeben – ein guter Grund, auf das neue Protokoll zu setzen. Serverseitig unterstützt der Apache Webserver (v2.4.17) den entsprechenden Webstandard.


Wer HTTP/2 einsetzen will muss zwangsläufig ein SSL-Zertifikat einsetzen, so dass die Webseite verschlüsselt (via https://) übertragen wird.

Und nun zu den Details …

Grundsätzliches: So funktioniert das Internet


Um zu erklären, was HTTP/2 ist, sollte man zuerst verstehen wie das Internet grundsätzlich funktioniert. Alle Daten im Computer und auch im Internet sind digital, das bedeutet so viel wie „die Daten werden intern binär verarbeitet“ (z.B. a => 01100001, b => 01100010, c => 01100011).

Um diese Daten nun an einen anderen Computer zu übertragen, benötigt jeder Computer, jedes Smartphone usw. eine eindeutige Adresse, die sogenannte IP-Adresse.

Die Daten werden bei der Übertragung im Internet bzw. im Netzwerk zu sogenannten Paketen zusammengefasst. Jedes Paket wird zusätzlich mit der Information bestückt von welcher IP-Adresse diese gesendet und an welche IP-Adresse diese gesendet werden sollten, solche Informationen nennt man Header-Informationen.

Um nun eine Verbindung von einem zum anderen Computer herzustellen, nutzt man sogenannte Netzwerkprotokolle: Diese definieren einen Standard, so dass unterschiedliche Systeme miteinander kommunizieren können. Im Internet werden UDP (User Datagram Protocol) bzw. TCP (Transmission Control Protocol) verwendet.Das Netzwerkprotokoll UDP ist im Gegensatz zu TCP verbindungslos, d. h. es wird keine eindeutige Verbindung aufgebaut. UDP wird z. B. verwendet um eine Domain ( in die entsprechende IP-Adresse aufzulösen.

Diese Netzwerkprotokolle nutzen unterschiedliche Ports, welche man sich wie Türen vorstellen kann: Jeder Computer hat – ähnlich einem Haus – eine eindeutige Adresse (IP-Adresse) und bietet Platz für unterschiedliche Dinge. diese Dinge können z. B. Webseiten (Port:80), E-Mails (Port:143) oder Dateien (Port:21) sein. Dies ist der Grund, warum man beispielsweise eine Webseite auch wie folgt aufrufen kann: ““.

Auch diese Ports sind zumindest von 0 bis 1023 mit fest definierten Anwendungsprotokollen (z. B. HTTP: 80, IMAP: 143, FTP: 21) belegt, so dass man verschiedene Anwendungen über TCP bzw. UDP ansteuern kann.

Die Einführung von HTTP/1.0 und HTTP/1.1

HTTP (Hypertext Transfer Protocol) wurde zusammen mit den Konzepten für die URL und HTML geschaffen und 1996 als HTTP/1.0 publiziert. Für jede verknüpfte Datei in einem HTML-Dokument – wie z. B. Bilder – wurde eine neue TCP-Verbindung aufgebaut.

Im Jahr 1999 wurde dann HTTP/1.1 publiziert, welches unter anderem Pipelining ermöglicht: Dabei werden mehrere HTTP-Anfragen über eine TCP/IP-Verbindung geschickt, so dass man den Overhead beim Verbindungsauf- und -abbau nicht bei jeder HTTP-Anfrage (Bilder, JavaScript-Dateien oder CSS-Dateien) hat. Jedoch ist dieses Feature bei fast allen Browsern standardmäßig deaktiviert und kann somit meistens nicht genutzt werden. Zudem kollidiert hier mal wieder Theorie und Praxis, da zwar theoretisch mehrere Anfragen direkt nacheinander abgearbeitet werden können, aber das sogenannte “head-of-line blocking”-Problem tritt auf: Denn die Anfragen werden noch immer nach dem FIFO-Prinzip (First In – First Out) verarbeitet und die erste Anfrage muss vor der zweiten Anfrage vom Server verarbeitet werden. Man kann sich dies wie die Kasse beim Supermarkt vorstellen: Nur, weil man mehrere Kunden an einer Kasse bedient heißt dies nicht, dass diese schneller bedient werden, solange man auch hier nach dem FIFO-Prinzip arbeitet.

Der neue Webstandard HTTP/2

HTTP/2 wurde im Mai 2015 veröffentlicht und unterstützt unter anderem das Zusammenfassen von mehrere HTTP-Anfragen über ein Multiplexverfahren. Beim Multiplexen werden Daten gebündelt und gemeinsam übertragen. Außerdem werden die Daten und Header nun komprimiert übermittelt und Daten werden binär kodiert übermittelt.

Webseite via HTTP/1.1 laden Webseite via HTTP/2 laden
1. Erstellt sechs bis acht HTTP-Verbindungen zum Server 1. Erstellt eine Verbindung zum Server
2. Anfrage der HTML-Seite 2. Anfrage der HTML-Seite
3. Empfang der HTML-Seite 3. Empfang der HTML-Seite
4. Decode der HTML-Seite 4. Decode der HTML-Seite
5. Erstellt sechs bis acht Verbindungen zu Dateien in der HTML-Seite, ohne Prioritäten

(unkomprimierten, plain-text Header)

5. Empfang von allen Dateien in der HTML-Seite, mit Prooritäten

(komprimierte, binary Header)

6. Die Verbindung wartet, bis die angeforderte Datei ankommen ist (Dateien werden über den gemultiplexten

Stream gesendet)

7. Fordert die nächste Datei, auf der jetzt offenen Verbindung an
8. Wiederhole Punkt 6-7 bis alle Dateien angekommen sind
9. Schließe sechs bis acht HTTP-Verbindungen 8. Schließe die eine Verbindung



Statement von Google: “Google observed an ~88% reduction in the size of request headers and an ~85% reduction in the size of response headers after enabling compression. This amounted to a saving of between 45 and 1142 ms in the overall page load time.” Quelle:

Diese binären Daten werden als Streams bezeichnet und können mit unterschiedlichen Priorisierungen angefordert werden, zum Beispiel 1. HTML, 2. JavaScript, 3. CSS, 4. Fonts, 5. Bilder. Zudem kann man theoretisch mit der Funktion “Server-Push” auch Dateien zum Client senden, welche dieser gar nicht angefragt hat, so könnte man HTML, CSS und Font senden, wenn nur das HTML angefragt wurde, jedoch ist dieses Funktion z. B. in der aktuellen Version von Apache (v2.4.17) noch nicht implementiert.

Im offiziellen Standard ist HTTP/2 zwar auch ohne SSL (https://) geplant, aber die Browser-Hersteller bieten HTTP/2 nicht ohne Verschlüsselung an. Da SSL-Zertifikate jedoch momentan nicht kostenlos sind, haben Mozilla, die Electronic Frontier Foundation (EFF), Cisco, Akamai und IdenTrust eine neue SSL-Zertifizierungsstelle (CA) mit dem Namen “Let’s Encrypt” gegründet, welche in Zukunft kostenlose Zertifikate ausstellt.


UPDATE: (04.11.2015)

Let’s Encrypt hat heute sein Beta-Programm gestartet, sodass man über wenige Zeilen auf der Kommandozeile bereits ein gültiges SSL-Zertifikat nutzen kann.

  git clone
  cd letsencrypt
  ./letsencrypt-auto --agree-dev-preview --server \ certonly
 Wer noch einen weiteren Grund benötigt, seine Webseite über eine verschlüsselte Verbindung (SSL) auszuliefern, der sollte sich das neue Feature von Firefox 44 anschauen, welches eine Warnung anzeigt, wenn Login-Daten über eine nicht verschlüsselte Verbindung übermittelt werden.

Was ändert sich für Webentwickler?

Jede Technik, welche HTTP-Anfragen reduziert, ist mittels HTTP/2 obsolet, da einzelne kleine HTTP-Anfragen nun schneller abgearbeitet werden als eine große Anfrage. Zu diesen Techniken zählen z. B. das Zusammenfassen (concat) von JavaScript- und CSS-Dateien oder auch das Sprite-Image, welches mehrere kleine Bilder zu einem Bild darstellt. Aber auch das aufteilen von HTTP-Request auf verschiedene Subdomains ist nicht länger sinnvoll, da ansonsten wieder neue TCP-Verbindungen aufgebaut werden müssen. Zudem ist das „Inlinen“ von z. B. Bildern via Data-URIs (data:image:png;base64,…) nicht mehr zweckmäßig.

Mit der „Server-Push-Funktion“ können bereits einige Webserver umgehen, so dass man serverseitig bestimmen kann, dass bestimmte Dateien zusätzlich ausgeliefert werden sollen, wenn z. B. eine HTML-Datei angefragt wird. Dafür müssen in den meisten Fällen bestimmte Header-Daten definiert werden (z. B. X-Associated-Content: “/foo.css”:1,”/bar.js”:1,”/baz.js”:1).

Alle diese Änderungen spielen Frameworks wie Polymer in die Hände, da der Quelltext hier in einzelne Pakete bzw. Komponenten geordnet ist und somit schneller übertragen werden kann.

Was ändert sich für Administratoren?

Administratoren müssen zunächst Server aktualisieren, da z. B. nur die aktuelle Version von Apache (v2.4.17) HTTP/2 unterstützt. Darüber hinaus müssen Pakete für die verschiedenen Linux-Distributionen müssen gebaut werden.

Indem via HTTP/2 die HTTP-Anfragen über eine TCP-Verbindung laufen, werden weniger Verbindungen pro User zum Server aufgebaut, der Web-Server benötigt weniger Speicher und die CPU-Last wird verringert.

Max. pages/s 16.3 @ 120 users 15.9 @ 120 users 98 @ 777 users
Response @ 100 users 1.1s 1.3s 1.1s
Response @ 120 users 1.4 s 1.5s 1.1s
Response @ 200 users 7.1s 7.8s 1.1s
Response @ 777 users 70.2s 72s 2.7s
First error 405 Users 225 Users 884 Users


Server-Anfrage Speicherverbrauch (für die selbe Beispiel-Anfrage)


Vergleich der Ladezeiten


Außerdem sollte man sich ein wenig mehr mit dem Thema SSL auseinandersetzen, so kann man z. B. über den “Strict Transport Security“-Header die Ladezeit von HTTP/2 Seiten weiter reduzieren. Dies geschieht, indem die Nutzung von HTTPS sozusagen gecacht wird und Anfragen via HTTP direkt via HTTPS verarbeitet werden.


Apache & HTTP/2:
“Can I use” HTTP/2:
Info zu HTTP/2:
FAQ zu HTTP/2:
Spec zu HTTP/2:
Präsentation zu HTTP/2 (von @derSchepp):
Präsentation zu HTTP/2 (von @mnot):
W3C – preload:
nghttp2 – Server-Push:
heise: HTTP/2:
Free SSL:
heise: Free SSL:


HTTP/2 ist angekommen | Apache 2.4.17

Was ist HTTP/2? Diese Frage haben andere bereits ausführlich geklärt. :) daher wollen wir dies heute in Kombination mit dem Apache Webserver ausprobieren.

Im Februar 2015 hat Google den Support für SPDY bereits zugunsten von HTTP/2 eingestellt. Und die Kompatibilität von HTTP/2 ist in fast allen aktuellen Webbrowsern gegeben, so das es bereits seit einiger Zeit keinen Grund gibt, nicht auf das neue Protokoll zu setzen. Seit dieser Woche unterstützt auch der Apache Webserver (2.4.17) das Protokoll, “Stefan Eissing” hat das Module “mod_http2” gesponsert, welches wir im folgenden testen werden.

Installation unter Ubuntu 14.04 via Fremdquellen (PPA)

Warnung: “Zusätzliche Fremdquellen können das System gefährden.”

Zu beginn stellen wir sicher, dass SPDY nicht mehr verwendet wird.

a2dismod spdy

Und deinstallieren dies am besten direkt, falls dies über den Paket-Manager installiert wurde.

apt-get purge mod-spdy-beta

service apache2 restart

Um die Quellen (/etc/apt/sources.list.d/) nicht manuell zu ändern, installieren wir kurzerhand das Programm “add-apt-repository” via:

aptitude install software-properties-common

# Web:
# Issues:
add-apt-repository ppa:ondrej/apache2

Falls es beim Hinzufügen des Keys zu Problem kommt, kann man dies auch manuell durchführen:

apt-key adv –keyserver –recv-keys 4F4EA0AAE5267A6C

Anschließend installieren wir das Update via “aptitude“, sodass wir mehr Kontrolle über den Update-Prozess haben.

apt-get update; aptitude


Nach der Installation können wir das “http2”-Module wie folgt aktivieren.

cd /etc/apache2/mods-available/

vim http2.load

# Depends: setenvif mime socache_shmcb
LoadModule http2_module /usr/lib/apache2/modules/

vim http2.conf

<IfModule http2_module>
ProtocolsHonorOrder On
Protocols h2 h2c http/1.1

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Und anschließend muss das Module nur noch aktiviert werden:

a2enmod http2

service apache2 restart

Um zu testen, ob HTTP/2 via https genutzt wird, können wir z.B. direkt im Chrome nachschauen. Dafür öffnen wir einfach die Seite chrome://net-internals und nutzen oben links im DropDown-Menü den Punkt “HTTP/2”.




Mr. Robot | Staffel 1, Folge 1 in a nutshell

Die Fernsehserie folgt einem jungen Programmierer (Elliot), der von dem mysteriösen Mr. Robot für eine Hackergruppe rekrutiert wird und wer die Serie bisher noch nicht geschaut hat, sollte dies nachholen.

In Folge 1 muss Elliot einen Rootkit ausfindig machen, viel mehr werde ich an dieser Stelle nicht vorwegnehmen. Viele der folgenden Befehle sind nicht ohne weiteres auf jedem Linux System auszuführen oder es gibt diese gar nicht. Jedoch versteht bzw. sieht man was diese bewirken sollen.

1. Status

mr robot | status

Um das Problem vom Büro aus zu analysieren, werden zunächst Netzwerk und Dienste geprüft.

status -scanports -s WBUSl12345678WB1 -p[80-7655]

Hier hat Elliot sich anscheinend eine Shell-Funktion geschrieben, welche einen Portscan auf der Server “WBUSl12345678WB1” mit der Port-Range 80 bis 7655 durchführt.

Der folgender Befehl würde wirklich funktionieren.

nmap WBUSl12345678WB1 -p80-7655

Als nächstes wird anscheinend geprüft welche Prozesse momentan auf dem Remote-Server ausgeführt werden.

status -services -s WBUSl12345678WB1

Dies könnte auch eine selbst programmiere Shell-Funktion sein, welche sich auf dem Remote-Server einloggt und die Prozesse z.B. via “ps aux” auflistet.

ssh user@WBUSl12345678WB1 ‘ps aux’

Resultat: Die Services sind nicht mehr erreichbar und anscheinend läuft auf dem Server ein Xorg. ;) Da der Fehler nicht einzugrenzen ist, wird Elliot (mit dem Jet) zum Rechenzentrum geflogen, um den infizierten Server zu lokalisieren und zu isolieren. *freu*

2. Ping

mr robot | multi-ping

Der Befehl selbst ist in der Sequenz nicht zu sehen aber dies könnte so ähnlich aussehen.

fping -g

Resultat: Ein Server ist noch aktiv, dies muss der Übeltäter sein …

3. Locate WBKUW300PS345672

mr robot |locate-server

Der gehackte Server soll in der nächsten Szene manuell durch den Backup-Server ersetzt werden. Es wird der Befehl “Locate” ausgeführt, um sich zunächst an dem gehacktem Server anzumelden.

Der “locate” Befehl ist eigentlich zum suchen von Dateien gedacht, aber diese wird ja auch klein geschrieben.

4. astsu

Hier wird außerdem der fiktive Befehl “astsu” ausgeführt, um Informationen vom Netzwerk-Informationen vom Server zu erhalten.

Folgende Befehle funktionieren tatsächlich…


cat /etc/resolv.conf





mr robot | astsu-what

In der nächsten Szene sehen wir sowohl die vorherigen aus auch die nächsten Befehle welche auf der Konsole eingegeben wurden.

astsu -close port: * -persistent

Und wie wir sehen übernimmt der Befehl “astsu” auch noch die Funktionalität von “iptables“. ;)

Locate BKUW300PS345672

Hier kommt nocheinmal der “Locate” Befehl zum Einsatz, um sich auf den Backup-Server einzuloggen.

mr robot | server_backup

set waneth0* : * [;;]

Im Output kann man ein “false” sehen, aber Elliot verwendet “-force” um dieses Problem zu lösen. Natürlich ist auch diese Befehl ausgedacht, aber viele andere Linux Kommandos akzepieren ebenfalls einen “–force” Parameter, daher ist dies gar nicht so abwegig.

set -force -ovr02 waneth04 : [;;

Um die IP-Adresse wirklich zu konfigurieren kann man z.B. “ifconfig & route” oder “ip” verwenden.

ip addr add dev eth0

ip addr add dev eth0

ip addr add dev eth0

ip route add default via

Resultat: Der gehacket Server ist offline und der Backup-Server hat dessen Funktion übernommen.

5. ps aux | grep root

mr robot | ps-aux

ps aux | grep root

Nachdem die Gefahr gebannt ist, schau Elliot sich den gehackten Server noch einmal genauer an und findet einen Prozess (pid: 24) welcher mit höchster Priorität (-20) läuft.

astu trace -pid 244 -cmd

Hier tauch eine abgewandelte Version vom fiktiven Befehl “astsu” auf, warum die pid 244 und nicht die 24 weiter untersucht wird, bleibt ungeklärt.

Um einen Prozess tatsächlich näher zu untersuch, würde ich zunächst folgende Befehle nutzen.

strace -p 24

lsof -p 24


Beispiel für “strace” & “lsof”

6. ps aux | grep root | cpuset

mr robot | astu-what

ps aux| grep root | cpuset

“cpuset” würde hier nicht funktionieren und ich bin mir nicht ganz sicher was “cpuset” überhaupt macht?!

astu -ls ./root/fsociety/ -a

Nun wird der Inhalt vom Verzeichnis “/root/fsociety/” angezeigt, folgender Befehl würde funktionieren.

ls -la /root/fsociety/

mr robot | more

Elliot schau sich nun die README Datei der Hacker an und möchte den Rootkit zunächst im folgenden löschen.

more readme.txt

astu -rm -norecycle /root/ fsociety/

Um das Verzeichnis wirklich zu löschen, müsste der folgende Befehl ausgeführt werden.

rm -rf /root/fsociety/

mr robot | chmod

Aber er entscheidet sich dagegen und ändert stattdessen die Berechtigungen der Datei, so dass nur noch er selber Zugriff darauf hat.

chmod -R ER280652 600

Auch dieser Befehl wird so nicht funktionieren, da man “chmod” und “chown” unterscheidet. Folgende Befehle würden funktionieren.

chmod -R 600 /root/fsociety/

chown -R ER280652 /root/fsociety/

Resultat: Der ursprüngliche Server ist offline, der Backup-Server ist online und der Rootkit ist noch immer im System.

Fazit: echo “Ich mag diese Serie.” | sed ‘s/Serie/Nerd-Serie/’

jQuery Performance


Die folgenden Tipps erklären wie man die Performance von jQuery verbessern kann, einfach indem man das Framework korrekt einsetzt und bei kritischem Code auf JavaScript zurückgreift.

– verwende “gute” Selektoren
– verwende Variablen als Cache
– verwende “chaining” -> .function1().function2()…
– vermeide Dom Interaktionen

jQuery-Selektor Performance

Sehr Schnell: $(“#id”) || $(#id).find(“.class”)
Schnell: $(“tag.class”)
Normal: $(“.class”) || $(“.class”).children()
Langsam: $(“tag”)
Langsamer: $(“tag1 tag2”) || $(“.class tag:type”)
Extrem Langsam: $(“.class > *”) || $(“.class :type”)

Daraus ergibt sich z.B. das eine Kombination aus “.class #id” langsamer ist, als ein einfacher “#id”-Selektor. Deshalb ist es bei jQuery auch schneller einen bestimmten Bereich im Dom via “#id”-Selektor zu laden und anschließend in der entsprechenden Variable nach weitern HTML-Fragmenten zu suchen. -> .find()

Zudem sollte man bei Selektoren bedenken, dass rechts immer der spezifischste Ausdruck stehen sollte. Gegebenenfalls benötigt man jedoch gar keine lange Selektoren, wenn man Zugriff auf das entsprechende HTML hat, um dieses zu ändern.

// Unoptimiert:
$(“tag1.class1 .class2”)

// Optimiert:
$(“.class1 td2.class2”)

Demo (#id vs .class):

Demo (jQuery – find):

Demo (jQuery – find vs jQuery Plugin):

Demo (jQuery – simple vs jQuery Plugin):

Demo (Zepto.js vs jQuery):

Demo (Zepto.js vs jQuery vs Sprint.js vs JavaScript):

Demo (Sprint.js vs jQuery):

Demo (JavaScript vs jQuery):

IMMER Variablen als Cache verwenden

Um auf bestimmte HTML-Fragmente im Dom zuzugreifen ist es aus Performance-Sicht hilfreich, wenn man sich einen Teil vom Dom in einer Variable speichert und anschließend nur noch innerhalb von JavaScript arbeitet. z.B.:

// Sehr langsam (& Sinnfrei):
$('.myElement span').each(function(i) {
  $('.myElement span').eq(i).css('color', 'green');

// Langsam:
$('.myElement span').each(function() {
  $(this).css('color', 'green');

// Langsam:
$('.myElement span').css('color', 'green');

// Schneller:
$('#myElement').find('span').css('color', 'green');

// Noch schneller: (jQuery + JavaScript)
myElement = $('#myElement').find('span');
for (var i = 0, len = myElement.length; i < len; i++) {
  myElement[i].style.color = 'green';

// Sehr schnell: (kein jQuery)
myElement = document.querySelector('.myElement');
myElement = myElement.querySelectorAll('span');
for (var i = 0, len = myElement.length; i < len; i++) {
  myElement[i].style.color = 'green';

// Sehr sehr schnell: (kein jQuery)
myElement = document.getElementById('myElement');
myElement = myElement.getElementsByTagName('span');
for (var i = 0, len = myElement.length; i < len; i++) {
  myElement[i].style.color = 'green';

Demo (mit / ohne Cache-Variable):


jQuery ist im Vergleich mit JavaScript oder anderen Frameworks langsamer, aber wenn man z.B. noch den IE8 unterstützen muss, sollte man auf ein umfassendes Framework wie jQuery nicht verzichten, da ansonsten die entgütige Entwicklungszeit (z.B. Bugfixes für IE) die bessere Performance nicht rechtfertigt. Ein weitere Pluspunkt für jQuery sind die viele bereits fertigen jQuery-Plugins. Außerdem kann man die Performance von jQuery verbessern, wenn man beim programmieren von jQuery-Plugins darauf achtet so wenig Dom-Selektoren “$()” bzw. Dom-Interaktionen wie möglich zu nutzen.

Um dies zu bewerkstelligen kann man z.B. auf das jQuery Boilerplate zurückgreifen, so dass man bereits eine erste Programmier-Struktur vorgegeben hat. Dies hat zusätzlich den Vorteil, dass die eigenen Plugins, die jQuery typische Verkettung von Befehlen unterstützen. Außerdem gewöhnt man sich somit daran in Modulen / Plugins zu denken, welche man zudem durch dessen Konfiguration auch wiederverwenden kann.

Zepto.js war bei meinen Tests keine Alternative zu jQuery, da z.B. ein each() kein zepto-object zurückgibt, so dass man innerhalb der Schleife wieder einen Selektor benötigt. Das Framework nutz die Syntax und Namen wie jQuery, verhält sich jedoch leider etwas anders.

Sprint.js war in den Tests bei weitem schneller als jQuery, jedoch unterstützt dieses Framework nur IE 10+, außerdem ist dieses Framework nicht mal ein Jahr alt, die Dokumentation ist noch nicht vorhanden (bzw. verweist auf die jQuery Dokumentation) und es wurde noch nicht von so vielen Entwicklern getestet wie z.B. jQuery.


– Erklärung zu jQuery- bzw. CSS-Selektoren:
– Effektive CSS-Selektoren:
– jQuery Performance (Tizen):
– jQuery Performance (jQuery):
– jQuery Performance (Blog-Post):

Admin meets Frontend

… oder was „JavaScript“ und „Shell-Script“ gemeinsam haben.

Zu beginn muss ich zugeben, dass ich bei meinen ersten Skripten auch nicht auf den Sichtbarkeitsbereich von Variablen (Scope) geachtet habe. Wenn man sich jedoch etwas mit Softwareentwicklung auseinandersetze stellt man schnell fest, dass globale Variablen direkt aus der Hölle kommen und nichts im Quelltext zu suchen haben.


Variablen sind zumindest in der Shell und in JavaScript zunächst global, selbst innerhalb von Funktionen und werden erst durch den Zusatz „var“ bzw. „local“ zur lokalen Variable. In vielen anderen Programmiersprachen erkennt man den Scope einer Variable direkt im Zusammenhang, ist z.B. eine Variable innerhalb einer Methode deklariert, so ist diese nur innerhalb dieser Methode verfügbar. Wird die Variable jedoch innerhalb der Klasse deklariert, so ist diese für die ganze Klasse und somit für alle Ihre Methoden verfügbar.

Es folgen ein paar Beispiele, wo der Inhalt (Title der Beiträge) des RSS-Feeds von “” ausgegeben werden soll.

JS-Beispiel: mit globalen Variablen


Um dies selber zu testen, öffne die Verlinkte Datei im Browser (leere Webseite) und öffne die Entwicklertools (F12), schalte die Ansicht auf “Konsole” und lade die Seite neu. Im Quelltext sind ausschließlich globale Variablen verwendet, jedoch funktioniert dieses Script “leider” wie gewünscht. Das Problem mit globalen Variablen ist, dass man den Quelltext dadurch ggf. schwerer lesen kann und diesen nicht wiederverwenden kann. Wenn man z.B. verschiedene Funkionen als unterschiedlichen Skripten zusammenfügt oder zusammen nutzen möchte, welche jedoch ebenfalls globale Variablen nutzen, dann können da sehr eigenartige Ergebnisse bei herauskommen.

JS-Beispiel: mit lokalen Variablen




In den DevTools von Chrome kann man jetzt den entsprechenden Variablen-Scope sehen. Jedoch ist der Quellcode noch nicht wirklich wiederverwendbar, da wir das zu lösende Problem (also das laden und parsen einer JSON-Datei) nicht auf eine eigene Abstraktionsschicht gebracht haben.

JS-Beispiel: mit lokalen Variablen und Klassen


In diesem Beispiel wurde nun die Klasse “PlanetUbuntuuserJsonData” erstellt welche wiederum von der Klasse “JsonData” dessen Eigenschaften (Variablen & Methoden) erbt. Leider ist der Quelltext hierbei von zirka 50 auf zirka 80 Zeilen erhört worden und funktioniert dabei z.B. nicht im IE < 10. (siehe Kommentare im Quelltext)

JS-Beispiel: ohne Variablen + jQuery


Dieses Beispiel benötigt zwar die “jQuery”-Bibliothek, welche jedoch bereits entsprechende Funktionalitäten kapselt. Vergleich man diesen Quellcode mit der Vorherigem Version, kann man schnell erkennen, das entschieden weniger Quellcode deutlich besser zu lesen ist. ;-)

Shell-Beispiel: mit globalen Variablen (


In diesem Beispiel sind wieder sehr viele globale Variablen verwendet und wieder funktioniert das entsprechende Skript “leider” trotzdem. Die Funktion “parse_json()” gibt nicht einmal einen Rückgabewert zurück, dafür teilen sich die beiden Funktionen die Variablen. Und im Grunde könnte man den ganzen Quelltext auch einfach ohne Funktionen untereinander schreiben, dies hätte den selben Effekt.

Shell-Beispiel: mit lokalen Variablen (

Die entsprechende Ausgabe ist bereits im Vorherigen Bild zu sehen. Bei Shell-Skripten kommt es seltener vor, dass man dessen Funktionalität wirklich wiederverwenden möchte, jedoch ist der Quelltext deutlich besser zu lesen, wenn man entsprechende Rückgabewerte und Übergabeparameter verwendet.

Quellen / Links:
– Shell: Advanced Bash-Scripting Guide
– Shell: Coding-Style-Guide von “Oh My Zsh”
– JS: Sichtbarkeitsbereich (Scope) von Variablen
– JS: Objektattribut


Blackfire PHP-Profiler: Fire up the Performance

Am Wochenende habe ich mal wieder ein neues Tool ausprobiert: “Blackfire” ist ebenso wie “Insight” von SensioLabs entwickelt und kann die Performance einer PHP-Anwendung “on the fly” analysieren und visualisieren.

Die Installation besteht aus folgenden Komponenten:

  • Probe: dies ist die PHP-Extension welche wir auf dem Server installieren
  • Agent: Dies ist ein Programm, welches ebenfalls auf dem Server installiert wird und die Performance-Daten zu weiterleitet, wo diese dann visualisiert werden
  • Client (optional): ein CLI-Tool um PHP-Profiling auf der Kommandozeile auszuführen
  • Companion: dies ist eine Chrome-Extension, welche auf Knopfdruck das PHP-Profiling ausführt
  • Website: die Webseite zur Darstellung der Ergebnisse

Die Installationsanleitung ist innerhalb von zirka 5 Minuten abgearbeitet und schon kann man schnell und bequem die Leistung / Performance von Änderungen testen und die entsprechenden Ergebnisse miteinander vergleichen. Beispiel-Profile von “


PS: wer noch mehr Information benötigt sollte sich Xdebug lokal installieren bzw. aktivieren und die Profile-Daten anschließend via WinCacheGrind (Windows) oder direkt via KCachegrind (Linux) auswerten und visualisieren.