đ„ Profilierung eines Symfony-Flows mit Blackfire
vom 5. Juli 2026
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:
- Der Symfony-Worker â eine manuelle
while-Schleife, die jede Nachricht umschlieĂt. - Der Flow-Treiber â eine interne AusfĂŒhrungsschleife innerhalb von
await(), die Pakete (Ip) verarbeitet, bis keine mehr vorhanden sind. 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 dieIps abruft,AsyncEvent-Ereignisse auslöst und pausierte Fibers fortsetzt.AmpDriver- rekursive Schleife ĂŒberEventLoop::defer($loop), bis keine Pakete mehr vorhanden sindReactDriver,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:
- Der Befehl lÀuft in einer Schleife und verarbeitet jeweils eine Nachricht.
handleSignal()gibt beiSIGUSR2den WertfalsezurĂŒck: Der Worker wird wĂ€hrend der Profilerstellung fortgesetzt.- Die Sonde wird in einer
static-Variablen zwischen zweiSIGUSR2gespeichert. - 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:
- extract â instanziiert eine php-etl-Pipeline, verzweigt eine
ExtractorInterface, die pro Zeile einenAcceptanceResultBucketliefert. - transform -
TransformerInterface+FlushableInterface, Generator mit mehrerenyields:array_map+strtoupper+str_rot13in jedem Durchlauf - load -
LoaderInterface+FlushableInterface, gleiches Generatormuster mit zusĂ€tzlichen Transformationen - walk â
$pipeline->walk()durchlÀuft die Ergebnisse, schreibt invar/output/products-*.jsonund 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
yieldderTransformerInterface/LoaderInterfaceerzeugt separate Frames array_mapundstr_rot13im Transformationsschritt: identifizierbarer CPU-Hotspotfile_put_contentsin 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 vonZeilenaus 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-OperationenBuildPromptJob: Zeichenkettenassemblierung,json_encodeFakeExecuteJob:preg_match_allauf Includes und Routen, Schleifehash('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
yieldoder einJobInterface - 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
Demo-Repositories
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