<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
  <title>fsck.sh - Deutsch</title>
  <subtitle>A tech blog about system administration, development, and all things UNIX.</subtitle>
  <link href="https://fsck.sh/de/feed.xml" rel="self"/>
  <link href="https://fsck.sh/de/"/>
  <updated>2026-02-27T00:00:00Z</updated>
  <id>https://fsck.sh/de/</id>
  <author>
    <name>Matthias Breddin</name>
  </author>
  <entry>
    <title>Symfony Messenger Worker hängt? 3 stille Production-Bugs</title>
    <link href="https://fsck.sh/de/blog/symfony-messenger-worker-haengt-3-stille-bugs/"/>
    <updated>2026-02-27T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/symfony-messenger-worker-haengt-3-stille-bugs/</id>
    <content xml:lang="de" type="html">&lt;p&gt;Sechzehn Minuten. Drei Bugs. Null Fehlermeldungen.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Oder: Wie Symfony Messenger uns versicherte, dass alles läuft — während absolut nichts passierte&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Wir haben einen Symfony-Messenger-Worker auf Production deployed, den Start beobachtet, das vertraute &lt;code&gt;[OK] Consuming messages from transport &quot;bulk_operations&quot;&lt;/code&gt; in den Logs gesehen — und weitergemacht. Messages stauten sich. Der Worker tat nichts. Keine Exceptions, keine Warnings, keine fehlgeschlagenen Jobs. Nur Stille.&lt;/p&gt; &lt;p&gt;Was folgte, war eine 16-minütige Debugging-Session, die drei voneinander unabhängige Bugs aufdeckte — jeder auf seine Art unsichtbar. Hier ist der Ablauf.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Drei Bugs, drei Silent Failures. (1) &lt;code&gt;auto_setup=0&lt;/code&gt; in der DSN sorgte dafür, dass die &lt;code&gt;messenger_messages&lt;/code&gt;-Tabelle nie erstellt wurde — der Worker loggt trotzdem OK. (2) &lt;code&gt;use_notify: true&lt;/code&gt; funktioniert nur mit PostgreSQL; MySQL ignoriert es und fällt nicht auf Polling zurück. (3) PHP-FPM schrieb &lt;code&gt;Europe/Berlin&lt;/code&gt;-Timestamps, während PHP CLI sie als UTC las — jeder Background-Job verzögerte sich um exakt eine Stunde.&lt;/p&gt; &lt;h2 id=&quot;das-setup&quot; tabindex=&quot;-1&quot;&gt;Das Setup&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/symfony-messenger-worker-haengt-3-stille-bugs/#das-setup&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Das Setup&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Die Umgebung: Symfony 6.2, PHP 8.1, MySQL 8.0 auf einem Bare-Metal-Ubuntu-Server. Alle Erkenntnisse beziehen sich auf diesen Stack — das Verhalten kann sich mit anderen Symfony-Versionen oder Redis/AMQP-Transports unterscheiden. Der Background-Worker läuft als systemd-Service (der Standard-Mechanismus unter Linux für langlaufende Hintergrundprozesse):&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# /etc/systemd/system/messenger.service&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span&gt;ExecStart=/usr/bin/php /var/www/app/bin/console messenger:consume bulk_operations --time-limit=3600 --memory-limit=128M&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span&gt;User=www-data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Der Transport nutzt Doctrine:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt;# config/packages/messenger.yaml&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;framework&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; messenger&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; transports&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; bulk_operations&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; dsn&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;%env(MESSENGER_TRANSPORT_DSN)%&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; options&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; use_notify&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; true&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; check_delayed_interval&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 60000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Und die DSN in &lt;code&gt;.env&lt;/code&gt;:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;MESSENGER_TRANSPORT_DSN&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;doctrine://default?&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;auto_setup&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Drei Config-Entscheidungen. Drei Bugs. Schauen wir sie uns in der Reihenfolge an, in der wir sie gefunden haben.&lt;/p&gt; &lt;h2 id=&quot;warum-schlagt-messenger-ohne-die-&#39;messenger_messages&#39;-tabelle-still-fehl&quot; tabindex=&quot;-1&quot;&gt;Warum schlägt Messenger ohne die ‘messenger_messages’-Tabelle still fehl?&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/symfony-messenger-worker-haengt-3-stille-bugs/#warum-schlagt-messenger-ohne-die-&#39;messenger_messages&#39;-tabelle-still-fehl&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Warum schlägt Messenger ohne die ‘messenger_messages’-Tabelle still fehl?&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Die &lt;code&gt;messenger_messages&lt;/code&gt;-Tabelle existierte nicht.&lt;/p&gt; &lt;p&gt;Die DSN hatte &lt;code&gt;auto_setup=0&lt;/code&gt;, was Symfonys Doctrine-Transport anweist, die Queue-Tabelle nicht automatisch anzulegen. Das ist ein vernünftiges Production-Setting — du willst nicht, dass deine App Datenbanktabellen on the fly erstellt. Aber es setzt voraus, dass du die Tabelle selbst angelegt hast. Hatten wir nicht.&lt;/p&gt; &lt;p&gt;Das Problem: &lt;code&gt;messenger_messages&lt;/code&gt; ist keine Doctrine-Entity. Es gibt keine Migration dafür, keine Entity-Klasse, nichts in &lt;code&gt;src/Entity/&lt;/code&gt;. Es ist eine interne Transport-Tabelle, die Symfony außerhalb deines ORM-Layers verwaltet. Wenn du den Transport sie nicht erstellen lässt und es auch nicht manuell machst, existiert sie schlicht nicht.&lt;/p&gt; &lt;p&gt;Die Reaktion des Workers auf eine fehlende Tabelle? &lt;code&gt;[OK] Consuming messages from transport &quot;bulk_operations&quot;&lt;/code&gt;. Kein Error. Kein Warning. Nur ein grünes Häkchen und unendliche…&lt;/p&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/symfony-messenger-worker-haengt-3-stille-bugs/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Jagd auf einen 0,18%-Bug: Redis Lock Expiration in Crunz</title>
    <link href="https://fsck.sh/de/blog/redis-lock-expiration-crunz-bug/"/>
    <updated>2026-02-10T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/redis-lock-expiration-crunz-bug/</id>
    <content xml:lang="de" type="html">&lt;p&gt;&lt;em&gt;Wenn „sporadisch&quot; eigentlich „mathematisch unvermeidlich&quot; heißt&lt;/em&gt;&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;In RedisStore.php line 185:&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Symfony&#92;Component&#92;Lock&#92;Exception&#92;LockConflictedException]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Eine Zeile. Kein Stack Trace. Kein Kontext. Nur eine &lt;code&gt;LockConflictedException&lt;/code&gt; in den Logs unseres &lt;a href=&quot;https://github.com/crunzphp/crunz&quot;&gt;crunz&lt;/a&gt;-Schedulers — jeden einzelnen Tag. Mal einmal, mal ein Dutzend Mal. Kein erkennbares Muster, kein offensichtlicher Auslöser. Ein nicht-deterministischer Bug wie aus dem Lehrbuch.&lt;/p&gt; &lt;p&gt;Ich hab’s eine Weile ignoriert. Dann hab ich gerechnet.&lt;/p&gt; &lt;p&gt;Es war gar nicht zufällig. Es war eine probabilistische Gewissheit, eingebaut in den Lock-Refresh-Mechanismus von Crunz — ein Bug, der ungefähr 1 von 550 Lock-Operationen trifft. Bei 42 Redis-gesicherten Cronjobs über den Tag verteilt war die Frage nie &lt;em&gt;ob&lt;/em&gt; es passiert, sondern &lt;em&gt;wie oft&lt;/em&gt;.&lt;/p&gt; &lt;h2 id=&quot;was-ist-ein-lock-und-warum-lauft-er-ab&quot; tabindex=&quot;-1&quot;&gt;Was ist ein Lock, und warum läuft er ab?&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/redis-lock-expiration-crunz-bug/#was-ist-ein-lock-und-warum-lauft-er-ab&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Was ist ein Lock, und warum läuft er ab?&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Wer sich mit Distributed Locking und Mutual Exclusion bereits auskennt: einfach weiterspringen. Für alle anderen — ein kurzes Gedankenmodell.&lt;/p&gt; &lt;p&gt;Stell dir einen Lock vor wie eine Parkuhr. Du wirfst Münzen rein (eine TTL — Time to Live), und solange die Uhr läuft, gehört der Parkplatz dir. Niemand sonst kann ihn nehmen. Aber sobald die Zeit abläuft, ist der Platz wieder frei — auch wenn du noch im Laden einkaufst.&lt;/p&gt; &lt;p&gt;Redis Locks funktionieren genauso. Crunz — ein PHP-Cronjob-Scheduler — nutzt die Symfony Lock-Komponente mit einem &lt;code&gt;RedisStore&lt;/code&gt;, um überlappende Task-Ausführung zu verhindern. Wenn ein Task startet, holt er sich einen Lock mit Zeitlimit via &lt;code&gt;ZADD&lt;/code&gt; (Redis’ „Sorted Set Add&quot;-Befehl — speichert einen einzigartigen Token mit einem Score, der den Expiry-Timestamp darstellt). Solange der Task den Lock vor Ablauf erneuert, ist alles sicher. Aber kommt die Erneuerung zu spät — auch nur um den Bruchteil einer Sekunde — betrachtet Redis den Lock als weg. Der nächste Refresh-Versuch findet einen leeren Platz und wirft &lt;code&gt;LockConflictedException&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Der Clou: Crunz erneuert den Lock nicht zuverlässig. Es nutzt einen probabilistischen Ansatz. Dazu gleich mehr.&lt;/p&gt; &lt;h2 id=&quot;redis-distributed-locks-in-php&quot; tabindex=&quot;-1&quot;&gt;Redis Distributed Locks in PHP&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/redis-lock-expiration-crunz-bug/#redis-distributed-locks-in-php&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Redis Distributed Locks in PHP&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Ein Distributed Lock mit Redis stellt sicher, dass nur ein Prozess gleichzeitig einen kritischen Abschnitt ausführt — selbst über mehrere Server hinweg. In PHP macht die Symfony Lock-Komponente das unkompliziert. Ein einfaches Redis-Lock-Beispiel:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; Symfony&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Component&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Lock&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;LockFactory&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; Symfony&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Component&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Lock&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Store&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;RedisStore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;redis&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; &#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Predis&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;&#92;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Client&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;host&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;localhost&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 6379&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;]);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;store&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; RedisStore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;($&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;redis…&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/redis-lock-expiration-crunz-bug/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>PHP: Die Kakerlake unter den Programmiersprachen (Und warum das ein Kompliment ist)</title>
    <link href="https://fsck.sh/de/blog/php-die-kakerlake-der-programmiersprachen/"/>
    <updated>2026-01-29T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/php-die-kakerlake-der-programmiersprachen/</id>
    <content xml:lang="de" type="html">&lt;p&gt;&lt;em&gt;Unsterblich, unmodern, unbestreitbar beschäftigt&lt;/em&gt;&lt;/p&gt; &lt;p&gt;2011 machte ein Artikel mit dem Titel „PHP is Dying“ die Runde. Der Autor prophezeite, dass PHP innerhalb von fünf Jahren nur noch für Legacy-Wartung taugen würde. Das war vor 15 Jahren. PHP betreibt immer noch 73,3% aller Websites mit erkennbarer Server-Technologie (W3Techs, Januar 2026).&lt;/p&gt; &lt;p&gt;Ich schreibe PHP seit 2002. In 15 dieser Jahre war es mein Haupteinkommen als Freiberufler. Mit Symfony arbeite ich seit Version 2. Und alle paar Jahre erzählt mir jemand selbstsicher, dass meine Berufswahl am Sterben ist.&lt;/p&gt; &lt;p&gt;Sie liegen immer noch falsch. Aber ganz ohne Punkte sind sie nicht.&lt;/p&gt; &lt;h2 id=&quot;die-kritiker-haben-teilweise-recht&quot; tabindex=&quot;-1&quot;&gt;Die Kritiker haben teilweise recht&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/php-die-kakerlake-der-programmiersprachen/#die-kritiker-haben-teilweise-recht&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Die Kritiker haben teilweise recht&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Seien wir ehrlich: PHP hat echte Probleme. Sie anzuerkennen macht uns zu besseren Entwicklern, nicht zu illoyalen.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Die Standardbibliothek ist Chaos.&lt;/strong&gt; Die Parameterreihenfolge ist inkonsistent (&lt;code&gt;strpos($haystack, $needle)&lt;/code&gt; vs &lt;code&gt;array_search($needle, $haystack)&lt;/code&gt;). Namenskonventionen sind überall anders (&lt;code&gt;str_replace&lt;/code&gt; vs &lt;code&gt;substr&lt;/code&gt; vs &lt;code&gt;string_starts_with&lt;/code&gt;). Das ist nicht zu verteidigen. Es ist historischer Ballast aus dem rasanten, Community-getriebenen Wachstum der frühen Jahre.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Unicode-Handling ist angeflanscht.&lt;/strong&gt; Du brauchst &lt;code&gt;mb_*&lt;/code&gt;-Funktionen für ordentliche Multibyte-Unterstützung, und wenn du sie vergisst, entstehen subtile Bugs. 2026 ist das immer noch nicht erstklassig gelöst.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Legacy-Code gibt PHP einen schlechten Ruf.&lt;/strong&gt; Viel PHP da draußen ist wirklich furchtbar. Ungepflegte WordPress-Plugins, Spaghetti-Code von 2008, überall rohes SQL. Wenn Kritiker sagen „PHP-Code ist schlecht“, schauen sie oft auf Code, der in jeder Sprache schlecht wäre. Aber PHPs niedrige Einstiegshürde bedeutet, dass mehr davon sichtbar ist.&lt;/p&gt; &lt;p&gt;Das sind legitime Kritikpunkte. Wer sich darauf konzentriert, ist fair.&lt;/p&gt; &lt;h2 id=&quot;warum-der-mythos-sich-halt&quot; tabindex=&quot;-1&quot;&gt;Warum der Mythos sich hält&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/php-die-kakerlake-der-programmiersprachen/#warum-der-mythos-sich-halt&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Warum der Mythos sich hält&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Wenn PHP also echte Probleme hat, warum nenne ich „PHP stirbt“ einen Mythos? Weil die Vorhersagen nicht zur Realität passen. Die „PHP stirbt“-Erzählung läuft durchgehend seit mindestens 2004 (Slashdot-Diskussionen) über 2007 (frühe Blogposts) bis 2011 (Mainstream-Tech-Presse) bis heute.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Survivorship-Bias funktioniert in beide Richtungen.&lt;/strong&gt; Kritiker erinnern sich an den furchtbaren PHP-4-Code, den sie gesehen haben. Sie sehen nicht die modernen Symfony-Anwendungen mit strikter Typisierung, 100% Testabdeckung und sauberer Architektur. Diese Anwendungen laufen einfach still in Produktion.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Der Hype-Zyklus bevorzugt Neues.&lt;/strong&gt; Node.js sollte PHP 2012 „killen“. Go 2015. Rust 2018. Jede neue Sprache bekommt atemlose Berichterstattung. PHP liefert weiter Features und baut sein Ökosystem aus. Ohne den gleichen Rummel.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Engagement-Farming.&lt;/strong&gt; „PHP ist tot“ generiert Klicks und hitzige Diskussionen. „PHP 8.4 bringt Property Hooks“ trendet nicht auf X (das Twitter ersetzt hat).&lt;/p&gt; &lt;h2 id=&quot;die-mythen-die-nicht-sterben-wollen&quot; tabindex=&quot;-1&quot;&gt;Die Mythen, die nicht…&lt;/h2&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/php-die-kakerlake-der-programmiersprachen/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Doppar: Laravels schlanker, schneller Cousin</title>
    <link href="https://fsck.sh/de/blog/doppar-php-framework-speed-demon/"/>
    <updated>2026-01-28T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/doppar-php-framework-speed-demon/</id>
    <content xml:lang="de" type="html">&lt;p&gt;&lt;em&gt;Oder: Was passiert, wenn “schnell genug” nicht reicht&lt;/em&gt;&lt;/p&gt; &lt;p&gt;318 Requests pro Sekunde. 1.000 gleichzeitige Nutzer. Null verlorene Verbindungen.&lt;/p&gt; &lt;p&gt;Das sind Stresstestergebnisse von &lt;a href=&quot;https://doppar.com/&quot;&gt;Doppar&lt;/a&gt;, einem PHP-Framework, von dem du wahrscheinlich noch nie gehört hast. Laravel optimiert für Developer Experience. Symfony optimiert für Enterprise-Stabilität. Doppar optimiert für pure Geschwindigkeit — und überlässt dir den Rest.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Für wen das hier ist:&lt;/strong&gt; Du hast deine PHP-Anwendung profiliert, Queries optimiert, Caching eingebaut, und brauchst trotzdem mehr Durchsatz. Du hast kein Problem damit, Integrationen selbst zu schreiben, die woanders ein &lt;code&gt;composer require&lt;/code&gt; wären. Du willst Laravel-Syntax ohne Laravel-Overhead.&lt;/p&gt; &lt;hr /&gt; &lt;h2 id=&quot;was-ist-doppar&quot; tabindex=&quot;-1&quot;&gt;Was ist Doppar?&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/doppar-php-framework-speed-demon/#was-ist-doppar&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Was ist Doppar?&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Doppar ist ein performantes, minimalistisches PHP-Framework, das Ende 2025 Version 3.x veröffentlicht hat. Es basiert auf drei Prinzipien:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Null externe Abhängigkeiten&lt;/strong&gt; für Kernfunktionen&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Intelligentes Memoization&lt;/strong&gt; wiederholter Ausführungen&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Attribute-First-Konfiguration&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;composer&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; create-project&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; doppar/doppar&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; my-app&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; my-app&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;php&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; pool&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; server:start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Deine erste Route:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt;// app/Http/Controllers/HelloController.php&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CAEE&quot;&gt;#[&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Mapper&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;prefix&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;api&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CAEE&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; HelloController&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; Controller&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CAEE&quot;&gt; #[&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Route&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;uri&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;hello/{name}&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; methods&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;GET&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;])&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CAEE&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; public&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; greet&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; Response&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; {&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; response&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;Hallo, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;{$&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;]);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; }&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Voraussetzungen: PHP 8.3+ und Composer.&lt;/p&gt; &lt;hr /&gt; &lt;h2 id=&quot;geschichte-and-philosophie&quot; tabindex=&quot;-1&quot;&gt;Geschichte &amp;amp; Philosophie&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/doppar-php-framework-speed-demon/#geschichte-and-philosophie&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Geschichte &amp;amp; Philosophie&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Doppar wurde von &lt;a href=&quot;https://github.com/techmahedy&quot;&gt;techmahedy&lt;/a&gt; entwickelt — ein Entwickler, der Laravels elegante Syntax ohne den Overhead wollte. Das &lt;a href=&quot;https://github.com/doppar/framework/releases&quot;&gt;3.x-Release Ende 2025&lt;/a&gt; markierte den Übergang vom Experiment zum nutzbaren Framework. Die Parallele zu Laravels eigener Entstehungsgeschichte ist kein Zufall — Symfony existierte und war robust, aber Laravel fand seine Stimme, indem es etwas anderes anbot.&lt;/p&gt; &lt;p&gt;Die Philosophie ist simpel:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;“Brauchst du ein Feature? Installier es und nutz es. Brauchst du es nicht? Halt deine Anwendung so einfach und sauber wie möglich.”&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;Doppar will Laravel oder Symfony nicht ersetzen. Es ist eine Alternative für Entwickler, die alles aus ihrem aktuellen Stack rausgeholt haben und trotzdem mehr brauchen.&lt;/p&gt; &lt;hr /&gt; &lt;h2 id=&quot;warum-ist-es-schnell&quot; tabindex=&quot;-1&quot;&gt;Warum ist es schnell?&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/doppar-php-framework-speed-demon/#warum-ist-es-schnell&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Warum ist es schnell?&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Drei Techniken machen Doppar schneller als typische PHP-Frameworks:&lt;/p&gt; &lt;h3 id=&quot;1.-intelligentes-memoization&quot; tabindex=&quot;-1&quot;&gt;1. Intelligentes Memoization&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/doppar-php-framework-speed-demon/#1.-intelligentes-memoization&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;1. Intelligentes Memoization&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Wiederholte Ausführungen werden automatisch gecacht. Config-Parsing, Service-Auflösung, Route-Matching — alles, was mehr als einmal läuft, wird ohne manuelles Eingreifen memoized.&lt;/p&gt; &lt;h3 id=&quot;2.-abhangigkeitsfreier-core&quot; tabindex=&quot;-1&quot;&gt;2. Abhängigkeitsfreier Core&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/doppar-php-framework-speed-demon/#2.-abhangigkeitsfreier-core&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;2. Abhängigkeitsfreier Core&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;ORM, Validation, WebSocket-Server und Scheduler sind direkt im Core eingebaut. Kein Doctrine. Keine externen Queue-Packages. Keine Third-Party-HTTP-Clients für…&lt;/p&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/doppar-php-framework-speed-demon/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Spukhafte Fernwirkung: Wenn dein Proxy-Fix die Anwendung zerstört</title>
    <link href="https://fsck.sh/de/blog/spukhafte-fernwirkung-proxy-fix-zerstoert-app/"/>
    <updated>2026-01-21T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/spukhafte-fernwirkung-proxy-fix-zerstoert-app/</id>
    <content xml:lang="de" type="html">&lt;p&gt;&lt;em&gt;Oder: Wie ich lernte, dass „funktioniert&quot; und „korrekt&quot; nicht dasselbe sind&lt;/em&gt;&lt;/p&gt; &lt;p&gt;„Spukhafte Fernwirkung&quot; (Spooky action at a distance) — so nannte Einstein 1947 die Quantenverschränkung, das Phänomen, bei dem die Messung eines Teilchens sofort ein anderes beeinflusst, egal wie weit sie voneinander entfernt sind. Er meinte es abwertend; die Idee schien absurd.&lt;/p&gt; &lt;p&gt;Den Begriff in Bezug auf Software hörte ich zum ersten Mal vor fast zehn Jahren, in Marco Pivettas (@ocramius) Vortrag &lt;a href=&quot;https://ocramius.github.io/extremely-defensive-php/&quot;&gt;Extremely Defensive PHP&lt;/a&gt;. Das Konzept blieb im Kopf: Code an einer Stelle beeinflusst Code woanders, ohne sichtbare Verbindung.&lt;/p&gt; &lt;hr /&gt; &lt;p&gt;„Die Ranking-Berechnungen laufen nicht.&quot;&lt;/p&gt; &lt;h2 id=&quot;das-system:-eine-callback-basierte-pipeline&quot; tabindex=&quot;-1&quot;&gt;Das System: Eine Callback-basierte Pipeline&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/spukhafte-fernwirkung-proxy-fix-zerstoert-app/#das-system:-eine-callback-basierte-pipeline&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Das System: Eine Callback-basierte Pipeline&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Unser Ranking-Tool fragt eine Externe-API nach Suchmaschinendaten ab. Die Pipeline ist simpel:&lt;/p&gt; &lt;div class=&quot;mermaid&quot; role=&quot;img&quot; aria-label=&quot;Diagram&quot;&gt;flowchart LR A[Task senden&lt;br /&gt;Command] --&amp;gt; B[Externe&lt;br /&gt;API] B --&amp;gt; C[Verarbeiten&lt;br /&gt;Command] C --&amp;gt; D[Ergebnisse&lt;br /&gt;berechnen]&lt;/div&gt;&lt;p&gt;Jeder Task durchläuft eine State Machine, die durch drei Flags getrackt wird:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; AnalysisTask&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; private&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; bool&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;submitted&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // An externe API gesendet?&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; private&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; bool&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;completed&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // API hat Verarbeitung abgeschlossen?&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; private&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; bool&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;processed&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // Wir haben Ergebnisse abgeholt?&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Die Übergabe passiert über einen &lt;strong&gt;Webhook-Callback&lt;/strong&gt;: Wenn die externe API uns die Daten gesendet hat, wird danach einen HTTP-Request an unseren Callback-Endpoint geschickt, der &lt;code&gt;completed = true&lt;/code&gt; setzt.&lt;/p&gt; &lt;p&gt;Einfach, oder?&lt;/p&gt; &lt;h2 id=&quot;der-bug:-tasks-fur-immer-blockiert&quot; tabindex=&quot;-1&quot;&gt;Der Bug: Tasks für immer blockiert&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/spukhafte-fernwirkung-proxy-fix-zerstoert-app/#der-bug:-tasks-fur-immer-blockiert&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Der Bug: Tasks für immer blockiert&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Tasks wurden erfolgreich erstellt und übermittelt. Die externe API verarbeitete sie (im Anbieter Dashboard verifiziert). Aber unser Process-Command fand nichts zu tun. Mitte November 2025 hörte die Verarbeitung auf.&lt;/p&gt; &lt;p&gt;Ich schaute mir die Pipeline an:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;protected&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; execute&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;InputInterface&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; OutputInterface&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; int&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;{&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;tasksToProcess&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;repository&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;findBy&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;([&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;submitted&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;completed&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // &amp;lt;-- Hmm...&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;processed&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; ]);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; foreach&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; ($&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;tasksToProcess&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;task&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; {&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;processTask&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;($&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;task&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; }&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; Command&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;SUCCESS&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Moment mal. Wir suchen nach Tasks, bei denen &lt;code&gt;completed = false&lt;/code&gt; ist?&lt;/p&gt; &lt;p&gt;Wenn der Callback &lt;code&gt;completed = true&lt;/code&gt; setzt, wenn die API fertig ist… warum suchen wir dann nach Tasks, die &lt;em&gt;nicht&lt;/em&gt; abgeschlossen sind?&lt;/p&gt; &lt;h2 id=&quot;die-annahmen-falle&quot; tabindex=&quot;-1&quot;&gt;Die Annahmen-Falle&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/spukhafte-fernwirkung-proxy-fix-zerstoert-app/#die-annahmen-falle&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Die Annahmen-Falle&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Ich schaute mir den Callback-Controller an:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CAEE&quot;&gt;#[&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;Route&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;/api/callback&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; methods&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;POST&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;])&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CAEE&quot;&gt;]…&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/spukhafte-fernwirkung-proxy-fix-zerstoert-app/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>HP iLO Hardware-Monitoring mit OMD Labs einrichten</title>
    <link href="https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/"/>
    <updated>2026-01-13T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/</id>
    <content xml:lang="de" type="html">&lt;p&gt;Sieben Probleme. So viele Stolpersteine habe ich gezählt, bis das Hardware-Monitoring für drei HP ProLiant Server endlich lief. Dabei klang es in der Dokumentation so einfach: SNMP aktivieren, check_hpasm ausführen, fertig.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Oder: Wie ich lernte, dass “Community-Projekt” manchmal “bring dein eigenes Pflaster mit” bedeutet&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Falls du gerade vor einem ähnlichen Setup stehst – HP ProLiant Server via iLO überwachen, OMD Labs als Monitoring-System – dann wird dir dieser Bericht einiges an Frust ersparen.&lt;/p&gt; &lt;h2 id=&quot;die-ausgangssituation&quot; tabindex=&quot;-1&quot;&gt;Die Ausgangssituation&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/#die-ausgangssituation&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Die Ausgangssituation&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Drei HP ProLiant DL360p Gen8 Server mit VMware ESXi 7.0.3. Jeder Server hat einen iLO4 Management-Controller mit eigenem Netzwerkinterface:&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Server&lt;/th&gt; &lt;th&gt;ESXi IP&lt;/th&gt; &lt;th&gt;iLO IP&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;esxi-01&lt;/td&gt; &lt;td&gt;192.168.20.x&lt;/td&gt; &lt;td&gt;192.168.21.101&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;esxi-02&lt;/td&gt; &lt;td&gt;192.168.20.x&lt;/td&gt; &lt;td&gt;192.168.21.102&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;esxi-03&lt;/td&gt; &lt;td&gt;192.168.20.x&lt;/td&gt; &lt;td&gt;192.168.21.103&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;&lt;strong&gt;Ziel:&lt;/strong&gt; Umfassendes Hardware-Monitoring – Lüfter, Temperaturen, Netzteile, RAM, RAID – über die iLO-Schnittstelle.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Monitoring-System:&lt;/strong&gt; OMD Labs 5.60 (ConSol Edition) mit Naemon als Core und PNP4Nagios für Graphing.&lt;/p&gt; &lt;p&gt;Klingt straightforward? War es nicht.&lt;/p&gt; &lt;h2 id=&quot;problem-1:-&amp;quot;failed-to-create-new-file:-invalid-path&amp;quot;&quot; tabindex=&quot;-1&quot;&gt;Problem 1: “Failed to create new file: invalid path”&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/#problem-1:-%22failed-to-create-new-file:-invalid-path%22&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Problem 1: “Failed to create new file: invalid path”&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Beim allerersten Versuch, einen Host über das Thruk Web-Interface anzulegen, begrüßte mich sofort eine Fehlermeldung:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Failed to create new file: invalid path&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Was ist passiert?&lt;/strong&gt; Das Verzeichnis für Konfigurationsdateien existierte schlicht nicht. OMD Labs ist ein Community-Projekt – manche Grundfunktionen sind nicht perfekt out-of-the-box konfiguriert.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Die Lösung:&lt;/strong&gt;&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;su&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; monitoring&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; # Als OMD-Site-User&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;mkdir&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -p&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; ~/etc/naemon/conf.d/hosts&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;mkdir&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -p&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; ~/etc/naemon/conf.d/services&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;mkdir&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -p&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; ~/etc/naemon/conf.d/commands&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Für produktive Setups empfiehlt es sich, Konfigurationen direkt per CLI zu erstellen. Das Web-Interface ist nett für Quick Wins, aber nicht immer zuverlässig.&lt;/p&gt; &lt;h2 id=&quot;der-umweg-uber-esxi-snmp&quot; tabindex=&quot;-1&quot;&gt;Der Umweg über ESXi SNMP&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/#der-umweg-uber-esxi-snmp&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Der Umweg über ESXi SNMP&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Bevor wir uns dem iLO widmeten, haben wir zunächst ESXi selbst via SNMP überwacht.&lt;/p&gt; &lt;h3 id=&quot;snmp-auf-esxi-aktivieren&quot; tabindex=&quot;-1&quot;&gt;SNMP auf ESXi aktivieren&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/#snmp-auf-esxi-aktivieren&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;SNMP auf ESXi aktivieren&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Per SSH auf den ESXi-Host:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;esxcli&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; system&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; snmp&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; --communities&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; public&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;esxcli&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; system&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; snmp&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; --enable&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; true&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;esxcli&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; network&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; firewall&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; ruleset&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; --ruleset-id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; snmp&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; --enabled&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;h3 id=&quot;problem-2:-snmp-mibs-nicht-geladen&quot; tabindex=&quot;-1&quot;&gt;Problem 2: SNMP MIBs nicht geladen&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/#problem-2:-snmp-mibs-nicht-geladen&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Problem 2: SNMP MIBs nicht geladen&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Beim ersten Test:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;snmpwalk&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -v2c&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -c&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; public&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; esxi-01.example.com&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; sysDescr&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Kam die Meldung:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sysDescr: Unknown Object Identifier (Sub-id not found: (top) -&amp;gt; sysDescr)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Die SNMP MIBs waren auf dem OMD-Server nicht geladen. Kein Drama – numerische OIDs sind ohnehin universeller:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;snmpwalk&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -v2c&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -c&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; public&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; esxi-01.example.com&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; .1.3.6.1.2.1.1.1.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Ergebnis:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;iso.3.6.1.2.1.1.1.0 = STRING: &quot;VMware ESXi 7.0.3 build-24411414 VMware, Inc. x86_64&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Für Nagios/Naemon Checks immer numerische OIDs verwenden – sie sind…&lt;/p&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/hp-ilo-monitoring-omd-labs-einrichten/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>PHPStan Level 9: Der Weg zu fehlerfreiem PHP</title>
    <link href="https://fsck.sh/de/blog/phpstan-level-9-strikte-typisierung/"/>
    <updated>2025-12-26T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/phpstan-level-9-strikte-typisierung/</id>
    <content xml:lang="de" type="html">&lt;p&gt;Drei Tage. So lange habe ich gebraucht, um einen Payment-Reconciliation-Bug zu fixen, den PHPStan in drei Sekunden gefunden hätte.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Oder: Wie ich lernte, das Type System zu lieben&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Der Bug war subtil. Unser API-Wrapper hat &lt;code&gt;null&lt;/code&gt; zurückgegeben, wenn die API in Wartung war – aber nur für bestimmte Transaction-Types. Unsere Tests haben mit Mocks gearbeitet, die nie &lt;code&gt;null&lt;/code&gt; zurückgeben. Das Code-Review hat sich auf die Berechnungs-Logik konzentriert, nicht auf Null-Safety. Production? Production ist um 3 Uhr morgens an einem Sonntag abgestürzt.&lt;/p&gt; &lt;p&gt;PHPStan Level 9 hätte uns angeschrien: “Parameter #2 $bankData of function reconcileTransaction() expects BankData, BankData|null given.”&lt;/p&gt; &lt;p&gt;Dieser 3-Uhr-morgens-Incident hat verändert, wie ich über Type Safety denke. Heute zeige ich dir, wie wir 90% unserer typ-bezogenen Bugs eliminiert haben, ohne einen einzigen zusätzlichen Test zu schreiben. Das Geheimnis? Dein Compiler ist schlauer als deine Tests.&lt;/p&gt; &lt;h2 id=&quot;warum-static-analysis-alles-verandert&quot; tabindex=&quot;-1&quot;&gt;Warum Static Analysis alles verändert&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/phpstan-level-9-strikte-typisierung/#warum-static-analysis-alles-verandert&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Warum Static Analysis alles verändert&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Kennste das noch aus Production?&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;Fatal&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; error&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; Uncaught&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; Call&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; member&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; function&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; on&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; in&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; /var/&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;www&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;PaymentProcessor&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;php&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt;142&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Das passiert, weil PHP dynamisch typisiert ist. Variablen können zur Runtime alles sein. Deine IDE warnt dich vielleicht, deine Tests fangen 80% der Fälle ab, aber die 20% finden ihren Weg in Production – zum ungünstigsten Zeitpunkt.&lt;/p&gt; &lt;p&gt;Static Analysis Tools wie PHPStan analysieren deinen Code &lt;strong&gt;ohne ihn auszuführen&lt;/strong&gt;. Sie bauen einen kompletten Type-Graph deiner Anwendung auf und sagen dir genau, wo Dinge kaputtgehen werden, bevor du deployst.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Traditionelles Testing:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Code schreiben&lt;/li&gt; &lt;li&gt;Tests schreiben&lt;/li&gt; &lt;li&gt;Tests laufen lassen&lt;/li&gt; &lt;li&gt;Deployen&lt;/li&gt; &lt;li&gt;Production-Bugs fixen, die du nicht getestet hast&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Static Analysis:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Code schreiben&lt;/li&gt; &lt;li&gt;PHPStan laufen lassen&lt;/li&gt; &lt;li&gt;Type-Errors fixen&lt;/li&gt; &lt;li&gt;Mit Confidence deployen&lt;/li&gt; &lt;li&gt;Die ganze Nacht durchschlafen&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&quot;die-phpstan-level-journey-(0-9)&quot; tabindex=&quot;-1&quot;&gt;Die PHPStan Level Journey (0-9)&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/phpstan-level-9-strikte-typisierung/#die-phpstan-level-journey-(0-9)&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Die PHPStan Level Journey (0-9)&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;PHPStan bietet 10 Strictness-Level, von “kaum irgendwas checken” bis “dein Code ist mathematisch bewiesen fehlerfrei”. Jedes Level catcht progressiv subtilere Bugs.&lt;/p&gt; &lt;h3 id=&quot;level-0:-basis-existenz-checks&quot; tabindex=&quot;-1&quot;&gt;Level 0: Basis Existenz-Checks&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/phpstan-level-9-strikte-typisierung/#level-0:-basis-existenz-checks&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Level 0: Basis Existenz-Checks&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Der sanfteste Einstieg. PHPStan verifiziert, dass Klassen, Funktionen und Methoden, die du aufrufst, tatsächlich existieren.&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt;// Level 0 catcht das hier&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; UserrModel&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;();&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // Typo im Klassennamen&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;getName&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;();&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // Klasse existiert nicht, Methode existiert nicht&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt;// Level 0 erlaubt das hier (sollte es aber nicht)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; process&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;($&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; {&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // Was wenn $data null ist?&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;&lt;strong&gt;Was es catcht:…&lt;/strong&gt;&lt;/p&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/phpstan-level-9-strikte-typisierung/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Async PHP in Production: Fibers, ReactPHP und Swoole entmystifiziert</title>
    <link href="https://fsck.sh/de/blog/async-php-fibers-reactphp-swoole/"/>
    <updated>2025-12-19T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/async-php-fibers-reactphp-swoole/</id>
    <content xml:lang="de" type="html">&lt;h1 id=&quot;async-php-in-production:-fibers-reactphp-und-swoole-entmystifiziert&quot; tabindex=&quot;-1&quot;&gt;Async PHP in Production: Fibers, ReactPHP und Swoole entmystifiziert&lt;/h1&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/async-php-fibers-reactphp-swoole/#async-php-in-production:-fibers-reactphp-und-swoole-entmystifiziert&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Async PHP in Production: Fibers, ReactPHP und Swoole entmystifiziert&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;&lt;strong&gt;PHP kann 10.000 gleichzeitige Verbindungen handhaben. So geht’s.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;PHPs am wenigsten verstandene Superkraft&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Drei Tage. So lange hab ich damit verbracht, einen API-Aggregation-Service zu optimieren, der 15 externe APIs sequenziell aufgerufen hat. Die Response-Zeit? Schmerzhafte 2,1 Sekunden im Durchschnitt. Dann hab ich Async PHP entdeckt, und derselbe Service antwortet jetzt in 520 Millisekunden. Das ist eine Verbesserung von 304% – ohne die Business-Logik anzufassen.&lt;/p&gt; &lt;p&gt;Falls du immer noch denkst, PHP ist diese langsame, blockierende, synchrone Sprache aus der LAMP-Stack-Ära, dann hast du was verpasst. In 2025 ist &lt;a href=&quot;https://medium.com/@mohamadshahkhajeh/async-php-in-2025-beyond-workers-with-fibers-reactphp-and-amp-e7de384c3ea6&quot;&gt;Async PHP keine Ausnahme mehr&lt;/a&gt;. Mit Fibers im Core seit PHP 8.1, plus ausgereiften Ecosystemen wie ReactPHP, Swoole und Amp, kann PHP Low-Latency-APIs, WebSockets und Streaming-Pipelines fahren – ohne deine Codebase in Callback-Hell zu verwandeln.&lt;/p&gt; &lt;p&gt;Ich zeig dir, wie Async PHP in Production funktioniert, wann du welchen Ansatz nutzt und wie du die Fallstricke vermeidest, die dich um 3 Uhr morgens beißen werden.&lt;/p&gt; &lt;h2 id=&quot;die-php-performance-revolution-uber-die-niemand-spricht&quot; tabindex=&quot;-1&quot;&gt;Die PHP-Performance-Revolution, über die niemand spricht&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/async-php-fibers-reactphp-swoole/#die-php-performance-revolution-uber-die-niemand-spricht&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Die PHP-Performance-Revolution, über die niemand spricht&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Kennste das noch? Concurrent Operations in PHP bedeuteten entweder mehrere Prozesse hochzufahren (Memory-Alptraum) oder Threads zu nutzen (Complexity-Alptraum)? Diese Zeiten sind vorbei.&lt;/p&gt; &lt;p&gt;Was Async PHP heute kann:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;200 RSS-Feeds verarbeiten&lt;/strong&gt; in 2,3 Sekunden statt 111 Sekunden (&lt;a href=&quot;https://www.phparch.com/2025/08/php-fibers-the-game-changer-that-makes-async-programming-feel-like-magic/&quot;&gt;463% Verbesserung&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;500+ Webseiten scrapen&lt;/strong&gt; in der Zeit, die früher für 100 gebraucht wurde&lt;/li&gt; &lt;li&gt;&lt;strong&gt;10x mehr gleichzeitige User&lt;/strong&gt; bei konsistenten Response-Zeiten handhaben&lt;/li&gt; &lt;li&gt;&lt;strong&gt;WebSocket-Server betreiben&lt;/strong&gt;, die tausende Verbindungen gleichzeitig offen halten&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Das Geheimnis? Cooperative Multitasking durch Fibers und Event-Loops. Lass uns aufdröseln, was das eigentlich bedeutet.&lt;/p&gt; &lt;h2 id=&quot;php-fibers-verstehen:-das-fundament&quot; tabindex=&quot;-1&quot;&gt;PHP Fibers verstehen: Das Fundament&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/async-php-fibers-reactphp-swoole/#php-fibers-verstehen:-das-fundament&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;PHP Fibers verstehen: Das Fundament&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;PHP 8.1 hat &lt;a href=&quot;https://php.watch/versions/8.1/fibers&quot;&gt;Fibers&lt;/a&gt; eingeführt – Full-Stack, unterbrechbare Funktionen. Stell sie dir vor wie leichtgewichtige Threads, die du nach Belieben pausieren und wieder aufnehmen kannst, aber ohne die Komplexität von echtem Parallelismus.&lt;/p&gt; &lt;p&gt;Der entscheidende Unterschied: Fibers sind für &lt;strong&gt;Concurrency&lt;/strong&gt;, nicht &lt;strong&gt;Parallelismus&lt;/strong&gt;. Du führst nicht mehrere CPU-intensive Tasks gleichzeitig aus. Du jonglierst effizient mehrere I/O-gebundene Operationen – während eine wartet, läuft eine andere.&lt;/p&gt; &lt;h3 id=&quot;dein-erster-fiber:-der-&amp;quot;aha&amp;quot;-moment&quot; tabindex=&quot;-1&quot;&gt;Dein erster Fiber: Der “Aha”-Moment&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/async-php-fibers-reactphp-swoole/#dein-erster-fiber:-der-%22aha%22-moment&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Dein erster Fiber: Der “Aha”-Moment&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;php&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;fiber&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; Fiber&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; ()&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; {&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; echo&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;Fiber gestartet&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;&#92;n&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; // Ausführung unterbrechen und Kontrolle zurückgeben&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; Fiber&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;suspend&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;pausiert&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; echo&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &quot;…&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/async-php-fibers-reactphp-swoole/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Laravel vs Symfony 2025: Wann du was nutzen solltest</title>
    <link href="https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/"/>
    <updated>2025-12-12T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/</id>
    <content xml:lang="de" type="html">&lt;h1 id=&quot;laravel-vs-symfony-2025:-wann-du-was-nutzen-solltest&quot; tabindex=&quot;-1&quot;&gt;Laravel vs Symfony 2025: Wann du was nutzen solltest&lt;/h1&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/#laravel-vs-symfony-2025:-wann-du-was-nutzen-solltest&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Laravel vs Symfony 2025: Wann du was nutzen solltest&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;&lt;em&gt;Ein pragmatischer Leitfaden für die Wahl des richtigen Tools - denn Glaubenskriege liefern keine Produkte aus&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Der Framework-Krieg ist vorbei. Laravel hat den Popularitätswettbewerb gewonnen. Symfony hat die Enterprise-Schlacht gewonnen. Und hier kommt die Wendung: &lt;strong&gt;Es spielt keine Rolle&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;Was zählt, ist die Wahl des richtigen Tools für dein spezifisches Projekt. Ich habe die letzten sechs Monate damit verbracht, einen Laravel-Monolithen auf Symfony-Komponenten zu migrieren, und weitere drei Monate damit, ein Greenfield-SaaS in Laravel zu bauen. Beide Entscheidungen waren richtig. Beide wären Katastrophen gewesen, wenn vertauscht.&lt;/p&gt; &lt;p&gt;Lass mich dir das Entscheidungsframework zeigen, das ich mir vor zwei Jahren gewünscht hätte.&lt;/p&gt; &lt;h2 id=&quot;der-status-von-php-frameworks-2025&quot; tabindex=&quot;-1&quot;&gt;Der Status von PHP-Frameworks 2025&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/#der-status-von-php-frameworks-2025&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Der Status von PHP-Frameworks 2025&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Bevor wir in Philosophie und Code eintauchen, schauen wir uns die harten Daten aus JetBrains’ State of PHP 2025-Umfrage an:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Laravel&lt;/strong&gt;: 64% Marktanteil (1.720 befragte PHP-Entwickler)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Symfony&lt;/strong&gt;: 23% Marktanteil&lt;/li&gt; &lt;li&gt;&lt;strong&gt;WordPress&lt;/strong&gt;: 25% (ja, höher als Symfony, aber es ist ein CMS, kein Framework)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Andere&lt;/strong&gt;: CodeIgniter, Yii, CakePHP zusammen unter 10%&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Hier ist, was dir niemand erzählt: &lt;strong&gt;Laravel läuft auf Symfony-Komponenten&lt;/strong&gt;. Check mal dein &lt;code&gt;vendor&lt;/code&gt;-Verzeichnis in jedem Laravel-Projekt - du findest &lt;code&gt;symfony/http-foundation&lt;/code&gt;, &lt;code&gt;symfony/routing&lt;/code&gt;, &lt;code&gt;symfony/console&lt;/code&gt; und etwa ein Dutzend mehr.&lt;/p&gt; &lt;p&gt;Laravel ist Symfony mit einem wunderschönen Developer-Experience-Layer obendrauf. Symfony ist eine Sammlung entkoppelter Komponenten, die alles von einem CLI-Tool bis zu Laravel selbst antreiben können.&lt;/p&gt; &lt;h2 id=&quot;der-philosophie-graben&quot; tabindex=&quot;-1&quot;&gt;Der Philosophie-Graben&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/#der-philosophie-graben&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Der Philosophie-Graben&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;h3 id=&quot;laravel:-developer-happiness-zuerst&quot; tabindex=&quot;-1&quot;&gt;Laravel: Developer Happiness zuerst&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/#laravel:-developer-happiness-zuerst&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Laravel: Developer Happiness zuerst&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Laravels Philosophie ist radikale Einfachheit kombiniert mit ästhetischem Vergnügen. Taylor Otwell hat Laravel für Entwickler entworfen, die &lt;strong&gt;schnell shippen wollen und den Prozess genießen möchten&lt;/strong&gt;.&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt;// Laravel Eloquent - das fühlt sich einfach gut an zu schreiben&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;activeUsers&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; User&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;active&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;latest&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; view&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;users.index&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt; compact&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;activeUsers&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&#39;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Alles an Laravel schreit “aus dem Weg gehen”. Convention over Configuration. Vollausgestattet. Meinungsstarke Defaults, die für 80% der Use Cases funktionieren.&lt;/p&gt; &lt;h3 id=&quot;symfony:-flexibilitat-und-kontrolle&quot; tabindex=&quot;-1&quot;&gt;Symfony: Flexibilität und Kontrolle&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/#symfony:-flexibilitat-und-kontrolle&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Symfony: Flexibilität und Kontrolle&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Symfonys Philosophie ist professionelle Flexibilität. Fabien Potencier hat Symfony für Teams gebaut, die &lt;strong&gt;präzise Kontrolle über jede Architektur-Entscheidung&lt;/strong&gt; brauchen.&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt;// Symfony Doctrine - ausführlicher,…&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/laravel-vs-symfony-2025-vergleich/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Symfony AssetMapper: Tschüss Webpack, Hallo Einfachheit</title>
    <link href="https://fsck.sh/de/blog/symfony-assetmapper-ohne-webpack/"/>
    <updated>2025-12-05T00:00:00Z</updated>
    <id>https://fsck.sh/de/blog/symfony-assetmapper-ohne-webpack/</id>
    <content xml:lang="de" type="html">&lt;p&gt;Was wäre, wenn dein Frontend-Build-Prozess einfach… nichts wäre?&lt;/p&gt; &lt;p&gt;&lt;em&gt;Die Rückkehr zur Einfachheit in der Frontend-Entwicklung&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Ich habe die letzten fünf Jahre damit verbracht, Webpack-Konfigurationen zu pflegen. Fünf Jahre, in denen &lt;code&gt;npm install&lt;/code&gt; drei Minuten gedauert hat. Fünf Jahre Debugging, warum mein Build plötzlich nicht mehr funktioniert, nachdem ich ein einziges Package aktualisiert habe. Fünf Jahre, in denen ich Junior-Entwicklern erklären musste, warum sie ein komplett separates Ökosystem lernen müssen, nur um eine JavaScript-Datei zu einem Symfony-Projekt hinzuzufügen.&lt;/p&gt; &lt;p&gt;Dann kam Symfony 6.3 mit AssetMapper, und mir wurde klar: Wir hatten die ganze Zeit das falsche Problem gelöst.&lt;/p&gt; &lt;p&gt;Das Versprechen klingt fast zu gut, um wahr zu sein: &lt;strong&gt;Schreib modernes JavaScript und CSS ohne jegliches Build-System&lt;/strong&gt;. Kein Node.js, kein npm, kein Webpack, keine Konfigurationsdateien, keine Transpilierungs-Pipeline. Nur PHP und die nativen Features, die Browser seit Jahren unterstützen.&lt;/p&gt; &lt;p&gt;Ich war skeptisch. Solltest du auch sein. Aber nachdem ich drei Produktionsanwendungen migriert habe, bin ich überzeugt: Das ist die Zukunft der Symfony-Frontend-Entwicklung.&lt;/p&gt; &lt;h2 id=&quot;das-problem-das-wir-uns-selbst-geschaffen-haben&quot; tabindex=&quot;-1&quot;&gt;Das Problem, das wir uns selbst geschaffen haben&lt;/h2&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/symfony-assetmapper-ohne-webpack/#das-problem-das-wir-uns-selbst-geschaffen-haben&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Das Problem, das wir uns selbst geschaffen haben&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;Kennste das? Du startest ein neues Symfony-Projekt:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;symfony&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; mein-projekt&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; --webapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;In den “alten Zeiten” (also… 2023) hast du sofort als nächstes ausgeführt:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;composer&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; symfony/webpack-encore-bundle&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;npm&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Und dann musstest du:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Node.js installieren (natürlich eine spezifische Version)&lt;/li&gt; &lt;li&gt;Die &lt;code&gt;webpack.config.js&lt;/code&gt; konfigurieren&lt;/li&gt; &lt;li&gt;Deine &lt;code&gt;package.json&lt;/code&gt; einrichten&lt;/li&gt; &lt;li&gt;Mit node_modules kämpfen (hallo, 400MB)&lt;/li&gt; &lt;li&gt;Babel für die Transpilierung konfigurieren&lt;/li&gt; &lt;li&gt;Watching im Development einrichten&lt;/li&gt; &lt;li&gt;Build für Production konfigurieren&lt;/li&gt; &lt;li&gt;Deinem Ops-Team erklären, warum dein Docker-Image jetzt 2GB groß ist&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Wofür? Um &lt;code&gt;import&lt;/code&gt;-Statements in JavaScript zu nutzen. Features, die Browser nativ seit 2017 unterstützen.&lt;/p&gt; &lt;h3 id=&quot;der-webpack-kaninchenbau&quot; tabindex=&quot;-1&quot;&gt;Der Webpack-Kaninchenbau&lt;/h3&gt; &lt;a class=&quot;direct-link&quot; href=&quot;https://fsck.sh/de/blog/symfony-assetmapper-ohne-webpack/#der-webpack-kaninchenbau&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Permalink to &quot;Der Webpack-Kaninchenbau&quot;&lt;/span&gt; &lt;span aria-hidden=&quot;true&quot;&gt;#&lt;/span&gt;&lt;/a&gt;&lt;p&gt;So sah ein typisches Encore-Setup aus:&lt;/p&gt; &lt;pre class=&quot;shiki shiki-themes vitesse-light vitesse-dark&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt;// webpack.config.js&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; Encore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;@symfony/webpack-encore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;Encore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;setOutputPath&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;public/build/&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;setPublicPath&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;/build&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;addEntry&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;./assets/app.js&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;splitEntryChunks&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;enableSingleRuntimeChunk&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;cleanupOutputBeforeBuild&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;enableBuildNotifications&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;enableSourceMaps&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;Encore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;isProduction&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;())&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;enableVersioning&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;Encore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;isProduction&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;())&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;configureBabel&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; {&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; config&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;plugins&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;@babel/plugin-proposal-class-properties&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;);&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; })&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;configureBabelPresetEnv&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; {&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; config&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;useBuiltIns&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;usage&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; config&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;corejs&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; })&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;enableSassLoader&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;enablePostCssLoader&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;()&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;autoProvidejQuery&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;();&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;/span&gt; &lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; Encore&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;getWebpackConfig&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#666666&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Das…&lt;/p&gt;&lt;p style=&quot;margin-top: 2em;&quot;&gt;&lt;a href=&quot;https://fsck.sh/de/blog/symfony-assetmapper-ohne-webpack/&quot;&gt;Weiterlesen auf fsck.sh →&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
</feed>