Darkwood Blog Blog
  • Artikel
  • Beobachtung
  • Releases
  • Creators
de
  • en
  • fr
Anmeldung
  • Blog
  • Artikel
  • Beobachtung
  • Releases
  • Creators

đŸ”„ Profilierung eines Symfony-Flows mit Blackfire

vom 5. Juli 2026

Anmelden um auf diesen Beitrag zu reagieren

🚀 1

Blackfire (https://www.blackfire.io) wird hĂ€ufig mit HTTP-Anfragen in Verbindung gebracht: Seitenprofilierung, Flamegraph-Analyse und Optimierung. Ein Großteil der PHP-Verarbeitung lĂ€uft jedoch nicht ĂŒber den Browser. Es handelt sich dabei um langlaufende Prozesse: Messenger-Clients, Synchronisierungs-Worker und Batch-Skripte, die per Cronjob oder Rundeck ausgefĂŒhrt werden.

Und Schleifen sind nicht nur in Symfony zu finden. In darkwood/flow treten sie auf mehreren Ebenen auf:

  1. Der Symfony-Worker – eine manuelle while-Schleife, die jede Nachricht umschließt.
  2. Der Flow-Treiber – eine interne AusfĂŒhrungsschleife innerhalb von await(), die Pakete (Ip) verarbeitet, bis keine mehr vorhanden sind.
  3. YFlow - eine rekursive Komposition, die einen Job so lange erneut ausfĂŒhrt, wie eine Bedingung dies erfordert.

Drei Möglichkeiten, Wiederholung auszudrĂŒcken. Eine einzige Profiling-Frage: Was geschieht wĂ€hrend einer Iteration?

// Worker Symfony classique
while (true) {
    $message = $queue->consume();
    if (!$message) {
        sleep(1);
        continue;
    }
    $this->process($message);  // ← boüte noire
}
// FiberDriver::await() - simplifié
do {
    // pull des Ip, dispatch async, reprise des fibers

} while ($this->countIps($stream['dispatchers']) > 0 or count($this->ticks) > 0);

Blackfire kann diese Prozesse analysieren. Das eigentliche Problem ist nicht die Schleife selbst, sondern das, was sie kapselt. Befindet sich die gesamte GeschÀftslogik innerhalb von process(), ist das Flamegraph zwar technisch korrekt, aber praktisch unbrauchbar.

Das Profiling beginnt nicht in Blackfire. Es beginnt mit der Art und Weise, wie Sie die Verarbeitungslogik strukturieren.

Flow macht die Schleife profilierbar, indem jede Iteration in explizite AusfĂŒhrungsschritte umgewandelt wird.

Ich habe drei Symfony-8-Demos mit darkwood/flow vorbereitet, um dies zu veranschaulichen. Jede Demo verwendet denselben Worker-Befehl und denselben signalbasierten Profiling-Mechanismus, jedoch in einem anderen Verarbeitungsszenario. Es geht nicht darum, Flow zu verkaufen, sondern zu zeigen, wie die Benennung der Schritte innerhalb der Schleife das Profiling nutzbar macht.

Das Problem intransparenter Arbeiter

Ein Symfony-Nutzer ist oft:

  • eine handgeschriebene while-Schleife
  • ein Serviceanruf
  • verstreute BaumstĂ€mme
  • und eine process()-Methode, die alles erledigt

Beim Profiling dieses Workers erkennt Blackfire PHP – keine Architektur. Wir erhalten einen großen Block an CPU-Zeit, einige darin enthaltene E/A-Aufrufe, und die Frage „Wo kann optimiert werden?“ bleibt offen.

Dies ist kein Fehler in Blackfire. Der Profiler protokolliert, was tatsĂ€chlich ausgefĂŒhrt wird. Ist der Code monolithisch, ist auch das Profil monolithisch.

Der pragmatische Ansatz: Strukturieren Sie die Verarbeitung vor dem Profiling, sodass jede Phase zu einer sichtbaren Grenze wird – in den Protokollen und in den Anrufframes.

Die Schleife ist nicht der Feind

Das Problem ist nicht die Endlosschleife an sich. Das Problem ist eine Endlosschleife um eine undurchsichtige process()-Funktion.

Drei Wiederholungsmuster

Model Wo Was er macht
while (true) Symfony-Befehl Verarbeitet Nachrichten bis zum SIGTERM-Signal
Schleife await() Treiberablauf Entleert ausstehende IPs, verteilt Jobs, setzt asynchron fort
YFlow / YJob Kompositionsablauf Einen Job mit neuen Daten erneut aufrufen (kontrollierte Rekursion)

Die Treiber: Die Schleife befindet sich bereits im Flow

Jeder Treiber implementiert DriverInterface::await() mit einer eigenen AusfĂŒhrungsschleife. Die in Flow\Driver\ verfĂŒgbaren Implementierungen sind:

  • FiberDriver – Standardtreiber fĂŒr Demos; do { 
 } while (countIps > 0)-Schleife, die die Ips abruft, AsyncEvent-Ereignisse auslöst und pausierte Fibers fortsetzt.
  • AmpDriver - rekursive Schleife ĂŒber EventLoop::defer($loop), bis keine Pakete mehr vorhanden sind
  • ReactDriver, SpatieDriver, SwooleDriver, ParallelDriver, TrueAsyncDriver – gleiches Prinzip, unterschiedliche asynchrone Laufzeitumgebung

Dies ist wichtig fĂŒr das Profiling: Jeder Aufruf von $flow->await() durchlĂ€uft diese innere Schleife. Wenn unsere Demos einen Batch verarbeiten, iteriert der Treiber die Flow-Schritte, bis alle IPss verarbeitet sind. Blackfire sieht sowohl die Symfony-Worker-Schleife als auch die Treiberschleife – aber vor allem die darin ausgefĂŒhrten Jobs.

YFlow: Wiederholung ohne explizite while-Schleife

YFlow kapselt einen YJob – einen Mechanismus fĂŒr kontrollierte Rekursion, der vom Y-Kombinator inspiriert ist. In der Praxis, ohne auf die Theorie einzugehen:

yield new YFlow(function ($loop) {
    return function ($data) use ($loop) {
        // traiter $data

        return $done ? $result : $loop($nextData);  // ré-invoque le flow
    };
});

Ein Job kann sich selbst mit neuen Daten erneut aufrufen. Dies ist keine lineare Pipeline, sondern eine wiederaufrufbare AusfĂŒhrung. Dies ist nĂŒtzlich fĂŒr iterative Verarbeitung (Paginierung, Wiederholungsversuche, schrittweise Reduzierung), ohne dass while-Schleifen in der GeschĂ€ftslogik implementiert werden mĂŒssen.

FĂŒr das Profiling bleibt der Grundsatz unverĂ€ndert: Blackfire beobachtet, was bei jedem erneuten Aufruf ausgefĂŒhrt wird. Ist der Jobinhalt undurchsichtig, ist auch das Profil undurchsichtig.

Was sich dadurch fĂŒr Blackfire Ă€ndert

Mit SIGUSR2 profilieren wir nicht den Befehlsstart. Wir profilieren eine oder mehrere Iterationen des Workers wÀhrend des geöffneten Fensters:

Demo Eine Iteration =
Kibono Flow Ein Produkt-Batch (ProductBatch) durchlĂ€uft die Schritte extrahieren → transformieren → laden → durchlaufen
PHP Flow Ein Batch-Befehl (OrderBatch), der die Schritte prepare → extract → transform → load durchlĂ€uft
VibePHP-Ablauf Eine simulierte Anfrage (VibeRequest), die die Schritte resolve → read → prompt → execute → metrics durchlĂ€uft

Die Symfony-Schleife verarbeitet die Nachrichten. Der Flow-Treiber steuert die einzelnen Schritte. Blackfire muss wĂ€hrend dieses Prozesses gestartet werden – nicht beim Systemstart.

Profilierung eines langen Prozesses mit POSIX-Signalen

Blackfire bietet das PHP SDK (blackfire/php-sdk) zur programmatischen Erstellung einer Probe an. Auf einem bereits laufenden Worker-Prozess kann keine Browsererweiterung angeklickt werden. Es ist jedoch möglich, UNIX-Signale an den Prozess zu senden.

Seit Symfony 5.2 ermöglicht SignalableCommandInterface das saubere Abfangen dieser Signale:

Signal Rolle in unseren Demos
SIGUSR2 Startet oder stoppt die Blackfire-Sonde (Umschalter)
SIGTERM / SIGINT Aktiviert ein shouldStop-Flag, um zwischen zwei Iterationen zu beenden

Das in den drei Projekten verwendete Muster:

  1. Der Befehl lÀuft in einer Schleife und verarbeitet jeweils eine Nachricht.
  2. handleSignal() gibt bei SIGUSR2 den Wert false zurĂŒck: Der Worker wird wĂ€hrend der Profilerstellung fortgesetzt.
  3. Die Sonde wird in einer static-Variablen zwischen zwei SIGUSR2 gespeichert.
  4. Der sanfte Stopp unterbricht keine laufende Iteration – er wartet, bis die aktuelle Nachricht abgeschlossen ist.

Blackfire profiliert den PHP-Code, der wĂ€hrend des durch die beiden SIGUSR2-Befehle geöffneten Zeitfensters ausgefĂŒhrt wird. In der Praxis: Der Worker wird gestartet, es wird gewartet, bis er mindestens eine Nachricht verarbeitet hat, dann wird das erste Signal gesendet. Das Profil erfasst die laufenden Iterationen – nicht die Initialisierung des Symfony-Containers.

Strukturieren Sie die Verarbeitung vor dem Profiling

darkwood/flow beseitigt keine Schleifen – es macht sie lesbar. Der Symfony-Worker verarbeitet Nachrichten, der Treiber verarbeitet IPs, und YFlow kann rekursiv iterieren. Auf jeder Ebene bietet Flow dieselbe Lösung: benannte Schritte anstelle eines monolithischen process().

Ein Prozess wird als eine Reihe von Schritten beschrieben, die durch Pakete („Ip“) miteinander verbunden sind, wobei jeder Schritt ein Job oder eine Closure ist:

$flow = $flowFactory->create(static function () {
    yield new PrepareEtlExecutionJob($io, $outputDir);
    yield new RunEtlExtractJob($io);
    yield new RunEtlTransformJob($io);
    yield new RunEtlLoadJob($io);
});

$flow(new Ip($batch));
$flow->await();

Flow verbessert die Leistung von Blackfire nicht. Es erzeugt keine zusĂ€tzliche Ebene im Flamegraph. Wenn $flow->await() die FiberDriver-Schleife aufruft, erkennt Blackfire diese Schleife und die von ihr ausgefĂŒhrten Jobs. Wenn jeder Schritt ein separater Job ist, trennen sich die Frames des Flamegraphs automatisch.

In der Praxis wird jede yield-Anweisung oder jede JobInterface-Klasse zu einem benannten Frame im Profil. Konsolenprotokolle folgen derselben Struktur ([extract], [transform] usw.). Sie können die Informationen im Terminal mit denen in Blackfire korrelieren – selbst mitten in einer Worker-Iteration.

FĂŒr ein 20-zeiliges Skript ist der Aufwand unverhĂ€ltnismĂ€ĂŸig. Bei einem mehrstufigen Prozess ist das VerhĂ€ltnis von Aufwand zu Lesbarkeit klar – selbst ohne Profiling. Flow ersetzt weder Messenger noch einen Infrastruktur-Orchestrator; es strukturiert den Code, der innerhalb des Workers ausgefĂŒhrt wird.

Gemeinsame Einrichtung der drei Demos

Die drei Symfony 8-Projekte nutzen dieselbe Infrastruktur:

Element Detail
Befehl app:flow:profile-demo
Standardmodus Verbraucher long (while (!$shouldStop))
Optionen --limit N (nach N Nachrichten beenden), --sleep (anhalten, wenn die Warteschlange leer ist)
Profiling BlackfireSignalHandler + SignalableCommandInterface
SDK blackfire/php-sdk zu require-dev
Anmeldeinformationen BLACKFIRE_CLIENT_ID und BLACKFIRE_CLIENT_TOKEN in .env.local

FĂŒhren Sie einen Schnelltest durch

bin/console app:flow:profile-demo --limit=1 -vv

Erstellung eines Profils eines laufenden Arbeitsprozesses

Terminal 1:

bin/console app:flow:profile-demo -vv

Terminal 2:

ps aux | grep profile-demo
kill -USR2 <pid>   # démarrer le profiling
# laisser tourner quelques itérations

kill -USR2 <pid>   # arrĂȘter → URL du profil dans les logs

Bei jeder Iteration werden außerdem Dauer und Speicherauslastung auf der Konsolenseite protokolliert – nĂŒtzlich zum Abgleich mit dem Flamegraph.

Fallbeispiel 1 – Kibono Flow: Visualisierung einer ETL-Pipeline

Demo: Kibono Flow

Diese Demo basiert auf dem Kiboko/Gyroscops-Ökosystem und php-etl. Die Idee: eine Kiboko\Component\Pipeline\Pipeline in darkwood/flow einzubinden, ohne den bestehenden ETL-Prozess neu zu schreiben.

Technische Struktur

Jede Warteschlangennachricht (data/products-queue.jsonl) ist ein ProductBatch – ein JSON-Array von Zeilen, die zeilenweise erzeugt werden. Der Ablauf verknĂŒpft vier Schritte ĂŒber ProductSyncFlowFactory:

  1. extract – instanziiert eine php-etl-Pipeline, verzweigt eine ExtractorInterface, die pro Zeile einen AcceptanceResultBucket liefert.
  2. transform - TransformerInterface + FlushableInterface, Generator mit mehreren yields: array_map + strtoupper + str_rot13 in jedem Durchlauf
  3. load - LoaderInterface + FlushableInterface, gleiches Generatormuster mit zusÀtzlichen Transformationen
  4. walk – $pipeline->walk() durchlĂ€uft die Ergebnisse, schreibt in var/output/products-*.json und zeigt die Zusammenfassung an.

Die FlowFactory ĂŒbergibt das Pipeline-Objekt von einer Stufe zur nĂ€chsten: Jedes yield in der Factory entspricht einer bestimmten Phase der Verarbeitung.

bin/console app:flow:profile-demo --limit=1 -vv

Was Blackfire sichtbar macht

  • Generatorgrenzen in Transform und Load: Jedes yield der TransformerInterface / LoaderInterface erzeugt separate Frames
  • array_map und str_rot13 im Transformationsschritt: identifizierbarer CPU-Hotspot
  • file_put_contents in walk: E/A-Zeit unterscheidet sich von der Transformationszeit

Das Interesse besteht hier darin, einen "echten" ETL-Prozess (php-etl-Generatoren, Buckets, Flush) zu profilieren – nicht ein kĂŒnstliches sleep() – und zu sehen, wie der Flamegraph der Struktur der Pipeline folgt.

Fall 2 - PHP-Ablauf: zwei Schichten, ETL + Orchestrierung

Demo: PHP Flow
ETL-Referenz: Flow PHP

Diese Demo ist kein generisches ETL-System, das eigens fĂŒr diesen Artikel entwickelt wurde. Sie basiert auf den ETL-Abstraktionen von Flow PHP (https://flow-php.com) – Extraktor, Transformer, Loader, Pipeline – und wurde in einer vereinfachten Version in einem Symfony-8-Worker umgesetzt, der von darkwood/flow orchestriert wird.

Die Idee: die ETL-Abstraktion (wie Daten den Prozess Extrahieren → Transformieren → Laden durchlaufen) von der AusfĂŒhrungs-Orchestrierung (wie ein Symfony-Worker diese Schritte in einer Verbraucherschleife verkettet) zu trennen.

In diesem Beispiel ist Flow nicht nur ein einfacher Pipeline-Runner. Er wird zu einer Orchestrierungsschicht ĂŒber einer ETL-Abstraktion, wodurch Transformations-Hotspots in Blackfire leichter isoliert werden können.

Schicht 1 - ETL-Abstraktion

Inspiriert von Flow PHP, ohne den Code zu kopieren:

PHP-Flow-Konzept Demo-Anpassung
Extractor App\Etl\Extractor - OrderBatchExtractor liefert Rows
Transform App\Etl\Transformer - NormalizeOrderTransformer
Loader App\Etl\Loader - JsonOrderLoader
Pipeline::process() App\Etl\Pipeline - Kette extrahieren → transformieren → laden
Flow + DataFrame App\Etl\OrderEtlFlow - konfiguriert die Pipeline fĂŒr Bestellungen

Die Daten fließen in Form von Row / Rows (ein vereinfachtes Modell der PHP-Flow-Typen). Der FlowContext enthĂ€lt die aktuelle Batch-Datei und das Ausgabeverzeichnis – ein minimales Äquivalent des PHP-Flow-AusfĂŒhrungskontexts.

Pipeline::process() folgt der gleichen Logik: Der Extractor liefert Batches, jeder Batch durchlĂ€uft den Transformer und anschließend den Loader.

Ebene 2 - Darkwood/Flow-Orchestrierung

OrderEtlFlowFactory verwendet Flow\FlowFactory (darkwood), um Jobs zu verketten, die jeden ETL-Schritt separat aufrufen:

Job darkwood/flow Anrufe auf der ETL-Seite
PrepareEtlExecutionJob Instanziiert OrderEtlFlow + FlowContext
RunEtlExtractJob Pipeline::extract()
RunEtlTransformJob Pipeline::transform()
RunEtlLoadJob Pipeline::load()

Jeder Job ist ein separater Frame in Blackfire. Jeder ETL-Aufruf darin (NormalizeOrderTransformer::transform, etc.) ist ein benannter Subframe.

Daten: data/orders.csv - 100 Zeilen, aufgeteilt in 10 Batches Ă  10 durch InMemoryQueue.
Ausgabe: var/output/orders-batch-*.json

bin/console app:flow:profile-demo --limit=1 -vv

Warum diese Abstraktion beim Profiling hilft

Ohne die ETL-Schicht hĂ€tten wir drei Symfony-Jobs, die Arrays manipulieren – sie erstellt Profile, aber sie modelliert keine wiederverwendbare Pipeline.

Ohne darkwood/flow hÀtten wir ein monolithisches OrderEtlFlow::run() - einen einzelnen Frame "run" in Blackfire, selbst wenn das Innere strukturiert ist.

Die beiden Schichten zusammen:

  • Die ETL-Schicht definiert wo die GeschĂ€ftsgrenzen verlaufen (extrahieren / transformieren / laden).
  • darkwood/flow definiert die AusfĂŒhrungsgrenzen (ein Job-Konsument pro Schritt).

Was Blackfire sichtbar macht

  • Ebene 2: RunEtlTransformJob - Orchestrierungsrahmen
  • Ebene 1: NormalizeOrderTransformer::transform - Hotspot-CPU (SHA-256 ×1000 pro Zeile)
  • Ebene 1: OrderBatchExtractor::extract - Extrahieren von Zeilen aus dem Batch
  • Ebene 1: JsonOrderLoader::load - json_encode + file_put_contents

Der Unterschied zu einem monolithischen Symfony-Befehl: Der Flamegraph trennt die Orchestrierung (Darkwood-Jobs) vom ETL-Prozess (Schnittstellen App\Etl). Die Transformation kann optimiert werden, ohne den Worker zu verÀndern, und umgekehrt.

Fallbeispiel 3 – VibePHP-Ablauf: Messung einer Anwendungspipeline

Demo: VibePHP Flow
Referenz: VibePHP

VibePHP ist ein Projekt, bei dem kein PHP-Code ausgefĂŒhrt wird: Eine Laufzeitumgebung liest den Quellcode und erzeugt eine simulierte HTTP-Antwort. Die Profilierung dieses Projekts mit einer echten KI-API wĂ€re nicht deterministisch.

Diese Demo adaptiert Ideen von VibePHP in eine Symfony Flow-Pipeline und konzentriert sich dabei auf die Quelltextinterpretation und die beobachtbaren AusfĂŒhrungsschritte.

Die Demo veranschaulicht die Struktur der Flow-Jobabfragepipeline mit einer reproduzierbaren simulierten Laufzeitumgebung.

Technische Struktur

Jeder Eintrag in data/requests.jsonl ({ "method", "path" }) wird zu einer VibeRequest, der eine IP ĂŒbergeben wird. VibeRequestFlowFactory verknĂŒpft fĂŒnf Jobs:

Job Rolle
ResolveScriptJob Ordnet den Pfad einer Datei in vibe/ zu (Kandidaten: $path, $path.php, $path/index.php, index.php)
ReadSourceJob file_get_contents im aufgelösten Skript
BuildPromptJob Erstellt einen JSON-Kontext (Methode, URI, Skript, Quelle)
FakeExecuteJob RegulĂ€rer Ausdruck fĂŒr require/include, Erkennung von preg_match-Routen, Erstellung von Dummy-HTML oder -JSON, Hash-Schleife ×500
LogMetricsJob Konsolentabelle: Methode, Pfad, Status, Dauer, Speicherspitzenwert, erkannte EintrÀge

Kein Laravel, keine KI-Aufrufe. Die Kosten werden simuliert, sind aber von einer AusfĂŒhrung zur nĂ€chsten konstant.

bin/console app:flow:profile-demo --limit=1 -vv

Was Blackfire sichtbar macht

  • ReadSourceJob: file_get_contents - PHP-Skript zum Lesen von E/A-Operationen
  • BuildPromptJob: Zeichenkettenassemblierung, json_encode
  • FakeExecuteJob: preg_match_all auf Includes und Routen, Schleife hash('sha256') - die CPU-Kosten der simulierten "AusfĂŒhrung"

Ohne Flow wĂ€re alles in einer einzigen handleRequest()-Methode enthalten. Mit Flow hat jede Phase einen Namen, eine protokollierte Dauer und einen Frame im Profil. Dies ist die ĂŒberzeugendste Demonstration fĂŒr den Übergang von einem undurchsichtigen Befehl zu einer transparenten Pipeline.

Was Blackfire zeigt – und was es nicht zeigt

Blackfire eignet sich fĂŒr:

  • CPU-Zeit pro Funktion
  • der zugewiesene Speicher
  • E/A-Aufrufe (Dateien, Netzwerk)
  • die Tiefe der Anziehungskraft und die starken AbhĂ€ngigkeiten

Blackfire sagt nicht:

  • wenn der Transformationsschritt schlecht konzipierte GeschĂ€ftslogik ist
  • wenn ein Cache an einem bestimmten Ort benötigt wird
  • wenn Flow "schneller" ist als ein anderer Ansatz

Es liegt an uns, die Verbindung zwischen Flammenbild und architektonischer Intention herzustellen. Die drei Demos sollen diese Verbindung verdeutlichen:

Demo Frage, zu deren Beantwortung das Profil beitrÀgt
Kibono Flow Wohin vergeht die Zeit in einem Generator-basierten ETL?
PHP Flow Welche ETL-Phase sollte optimiert werden – Orchestrierung oder Transformation?
VibePHP Flow Lesen, Serialisieren oder simulierte AusfĂŒhrung?

Was Flow im Vergleich zu einem klassischen Symfony-Befehl bietet

Ein Symfony-Befehl kann SignalableCommandInterface implementieren und mit SIGUSR2 profiliert werden - Flow ist keine Voraussetzung fĂŒr Blackfire.

Flow fĂŒgt einen Slicing-Vertrag hinzu:

  • jeder Schritt = ein yield oder ein JobInterface
  • die Daten werden ĂŒber eine typisierte IP-Adresse geleitet
  • await() markiert das Ende eines abgeschlossenen Prozesses
Undurchsichtiger Befehl Befehl + Ablauf
Ein großer Block im Flamegraph Frames pro Orchestrierungsphase
Handgefertigte Protokolle Abschnitte [extract], [transform], etc.
Worker-Schleife + undurchsichtige process()-Funktion Worker-Schleife + Treiberschleife + benannte Schritte
ETL- und Worker-Schicht kombiniert ETL-Schicht (App\Etl) + Orchestrierungsschicht (darkwood/flow) getrennt

Flow ersetzt weder Messenger noch Scheduler oder einen Infrastruktur-Orchestrator. Es ist ein Werkzeug zur besseren Lesbarkeit des Codes, der innerhalb des Workers ausgefĂŒhrt wird.

Abschluss

Die Profilierung eines Symfony-Flows besteht nicht darin, Blackfire in eine while-Schleife einzufĂŒgen und auf Erkenntnisse zu hoffen. Schleifen existieren auf verschiedenen Ebenen – im Symfony-Worker, im Flow-Treiber, möglicherweise in YFlow – und das ist an sich kein Problem.

Das Problem ist eine undurchsichtige Iteration. Flow macht die Schleife profilierbar, indem jede Iteration in explizite AusfĂŒhrungsschritte umgewandelt wird – sichtbar in den Protokollen, identifizierbar im Flamegraph.

Die drei Demos – Kibono Flow, PHP Flow, orchestriert von darkwood/flow, und VibePHP Flow – veranschaulichen drei Varianten desselben Prozesses: Lesen, Transformieren, Ausgeben. Blackfire profiliert den PHP-Code, der wĂ€hrend einer oder mehrerer Iterationen ausgefĂŒhrt wird; Flow stellt sicher, dass dieser PHP-Code kein anonymer Block ist.

Das Profiling beginnt nicht in Blackfire. Es beginnt erst, wenn wir entscheiden, dass process() keine Blackbox mehr ist.

Quellen und weiterfĂŒhrende Literatur

Blackfire Inspiration – Profilerstellung eines Konsumenten anhand von Signalen

  • Profilierung eines Verbrauchers mit Blackfire - JoliCode

Demo-Repositories

  • Kibono Flow
  • PHP Flow
  • VibePHP Flow

Verwandte Projekte

  • darkwood/flow - Flow-Komponente (Treiber, YFlow, Orchestrierung)
  • Flow PHP - Referenz-ETL-Architektur fĂŒr die PHP Flow-Demo
  • VibePHP - Referenzprojekt fĂŒr die VibePHP Flow-Demo – php-etl/pipeline – Kiboko-Dokumentation, die in Kibono Flow verwendet wird

Zusammenfassung der Bestellungen

Nach dem Klonen eines Demo-Repositorys:

# Kibono Flow - ETL php-etl dans darkwood/flow
git clone https://github.com/matyo91/kibono-flow.git && cd kibono-flow
bin/console app:flow:profile-demo --limit=1 -vv

# PHP Flow - ETL Flow PHP + orchestration darkwood/flow
git clone https://github.com/matyo91/php-flow.git && cd php-flow
bin/console app:flow:profile-demo --limit=1 -vv

# VibePHP Flow - pipeline de requĂȘte
git clone https://github.com/matyo91/vibephp-flow.git && cd vibephp-flow
bin/console app:flow:profile-demo --limit=1 -vv

Anmelden um auf diesen Beitrag zu reagieren

🚀 1

Site

  • Sitemap
  • Kontakt
  • Impressum

Network

  • Hello
  • Blog
  • Apps
  • Photos

Social

Darkwood 2026, alle Rechte vorbehalten