Blog
  • Login

  • Login
  • Register
  • Blog

  • Articles
  • fr
  • de

✨ Meetup SQLI

on September 17, 2025

On September 16, 2025, the Paris branch of AFUP launched the new season of PHP meetups. For this back-to-school season, the community gathered at the SQLI Digital Experience premises in Levallois-Perret, with a program focused on real-time communication and developer experience.

The AFUP Paris September meetup was held at SQLI Digital Experience, marking the launch of the 2025-2026 season. As with every meetup, the event brought together the PHP community around two technical presentations, as well as discussions, exchanges, and convivial moments.

As a reminder, the AFUP (French Association of PHP Users) organizes monthly meetups in Paris (excluding the summer period). These evenings are an opportunity to discover new topics related to PHP and its ecosystems—whether frameworks, databases, DevOps tools, or even methodologies like agility.

The association lives thanks to its members and partners: - Speakers who come to share their feedback, - Sponsors who host events in their premises, - Volunteers who lead the community and offer formats (mentoring, conferences, forums, etc.).

At the same time, AFUP also offers two major annual conferences: the PHP Forum, which will be held on October 9 and 10, 2025, at the Hotel New York – Disneyland Paris, and the PHP Tour. These events have become essential for anyone interested in the evolution of PHP and its ecosystem.

At SQLI, the evening began with a presentation of the company and its activities in digital, e-commerce, and large-scale PHP architectures, before giving way to technical talks.

1️⃣ Server-Sent Events and ZeroMQ – by Amaury Bouchard

The first presentation highlighted an elegant alternative to websockets: Server-Sent Events (SSE).

Concept: a one-way flow from server to client, based on HTTP, simple to set up and compatible with the majority of browsers.

Practical case: Amaury demonstrated how to integrate SSE with ZeroMQ, a high-performance messaging library. The chosen example was a small real-time chat software, demonstrating the simplicity and robustness of the SSE + ZMQ pair.

Challenges: This combination makes it possible to build reactive applications without falling into the complexity of websockets, while relying on a proven infrastructure.

SSE in two minutes

  • What? A unidirectional channel (server → client) over HTTP/1.1. * Why? Simpler than WebSocket when you don't need permanent upstream (chat, notifications, live metrics, logs, etc.). * How? The server responds in text/event-stream, keeps the connection open, sends formatted events; the client reconnects by itself if the connection breaks. * Bonus: you can multiply the logical flows via the event: field (multiplexing).

Minimal client (browser)

<ul id="log"></ul>
<script>
  const ul = document.getElementById('log');
  const es = new EventSource('/events'); // endpoint SSE

  // Default event es.onmessage = (e) => { const li = document.createElement('li'); li.textContent = e.data; // payload text ul.appendChild(li); };

  // Multiplexing: listen to a named event type es.addEventListener('chat', (e) => { const { user, text } = JSON.parse(e.data); const li = document.createElement('li'); li.textContent = `[${user}] ${text}`; ul.appendChild(li); });</script>

Minimal server (“educational” PHP)

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');

// Emit loop while (true) { $payload = ['ts' => time(), 'msg' => 'tick']; // optional event for multiplexing echo "event: tick\n"; echo "data: " . json_encode($payload) . "\n\n"; @ob_flush(); @flush(); // Keep the frame rate and CPU low sleep(2); }

Format of an SSE event

event:<nom-optionnel> id:<cursor-optionnel> retry:<ms-optionnel> data:<ligne-1> data:<ligne-2><ligne-vide>

Why it works well in PHP

  • No dedicated infrastructure required: it's HTTP. * Easy to deploy behind a reverse proxy. * The client handles the reconnection (EventSource).

Natural limitation: no upstream (client → server). To send a message, we use a classic HTTP request (AJAX/Fetch), and we leave the push to the SSE.

Add ZeroMQ: structuring the flows

ZeroMQ (ØMQ) is a high-performance messaging library offering ready-to-use patterns:

  • REQ/REP – request/response (simple RPC) * PUSH/PULL – work queue (pipeline) * PUB/SUB – broadcast (broadcast to subscribers)

Key idea of the talk:

  • Browsers listen via SSE. * The application server subscribes to a PUB/SUB broker (ZeroMQ). * Incoming messages (forms, APIs) are pushed (PUSH) to the broker, which publishes (PUB) to all SSE controllers.

Diagram (text)

[HTTP Client] --POST /message--> [Controller "message"] --PUSH--> [Broker ØMQ] --PUB--> [Controller "events"] --SSE--> [Browser(s)]

Broker-side sketch (PHP + ext-zmq)

$context = new ZMQContext();

// Receiving application messages $pull = new ZMQSocket($context, ZMQ::SOCKET_PULL); $pull->bind('tcp://*:5557');

// Broadcast to SSE consumers $pub = new ZMQSocket($context, ZMQ::SOCKET_PUB); $pub->bind('tcp://*:5556');

while (true) { $msg = $pull->recv(); // wait for a message $pub->send($msg); // broadcast }

“events” controller (consumes PUB, emits SSEs)

header('Content-Type: text/event-stream'); header('Cache-Control: no-cache');

$context = new ZMQContext(); $sub = new ZMQSocket($context, ZMQ::SOCKET_SUB); $sub->connect('tcp://broker:5556'); $sub->setsockopt(ZMQ::SOCKOPT_SUBSCRIBE, ''); // All

while (true) { $msg = $sub->recv(); // JSON {user, text} echo "event: chat\n"; echo "data: $msg\n\n"; @ob_flush(); @flush(); }

“message” controller (receives a POST, pushes to the broker)

$user = trim($_POST['user'] ?? ''); $text = trim($_POST['text'] ?? ''); if ($user !== '' && $text !== '') { $context = new ZMQContext(); $push = new ZMQSocket($context, ZMQ::SOCKET_PUSH); $push->connect('tcp://broker:5557'); $push->send(json_encode(['user' => $user, 'text' => $text])); } http_response_code(204);

Practical notes & pitfalls avoided

  • Proxy-side SSE: Allow long connections and flushing (disable compression on this path, keep X-Accel-Buffering: no under Nginx if necessary). * Back-pressure: Emit at a reasonable rate and flush to avoid accumulating (otherwise memory). * Multiplexing: Use event: to distinguish between streams (chat, metrics, alerts). * Reconnection: EventSource automatically tries; server-side, remain idempotent and allow a retry: if necessary. * Security: Validate/sanitize all messages, never broadcast raw user input.

Summary

  • SSE = server-to-browser push, simple and reliable, perfect for live diffs. * ZeroMQ = application glue for cleanly routing/broadcasting messages. * Together, we get a minimalist, clean, and extensible real-time chat — without building a full WebSocket stack.

2️⃣ Configuration formats and Symfony – by Nicolas Grekas

The second presentation was led by Nicolas Grekas, a key figure in the Symfony framework.

Topic: An overview of the configuration formats available in Symfony — YAML, XML, and PHP.

Key points:

YAML, long favored for its readability, has maintainability limitations.

XML, more verbose, keeps specific use cases.

PHP is gaining popularity because it offers language power, completion, and IDE integration.

DX (Developer Experience) approach: the discussion showed how the choice of format directly impacts team productivity and experience.

The observation

  • Three historical formats coexist: YAML, XML, PHP (fluid config generated from the configuration tree). * This plurality makes discovery more cumbersome (doc, multiple tabs), multiplies the options, and increases the cognitive load for new and old users. * DX: the choice of format impacts onboarding, IDE tooling, navigation/refactor, Flex patches and collaboration (QA teams, non-PHP, etc.).

What each format brings (and costs)

| Format | Strengths | Limitations / Frictions | | ----------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | YAML | Simple, concise, known beyond PHP, easy to read/share | Implicit typing, “ugly” references (const/enum), plugin-dependent tooling, indentation errors | | XML | Very explicit, schematizable, used by ecosystems (e.g. Sylius/Sulu) | Verbose, not appreciated for semantic app configuration | | PHP (fluid configuration) | Typed references, IDE completion, robust refactor | Verbose, less “diffable”, incompatible with Flex recipes (complicated automatic patching) |

Key point: Flex can patch YAML/XML deterministically; not arbitrary PHP code. This is a major obstacle for DX and the ecosystem.

Proposed Direction (work in progress)

  1. Deprecate XML for semantic configs (e.g. framework, messenger, …) and application-side routes, in favor of PHP (already adopted internally on the Symfony side).

    • Keep XML where it remains structural and interop (e.g. service declarations provided by bundles, specific cases of ecosystems).
  2. Keep YAML as the major application-side format: readable, stable, widely understood (multi-language teams, QA, CI/CD tooling).

  3. Don't "kill" PHP: The fluid PHP format remains the most typed and pleasant option in IDE for those who want it — but without breaking Flex.

News / in-depth projects

A. Compilation “Resources” (beyond services)

Introduce the notion of resource (classes carrying useful metadata) known to the container at compilation:

  • Example: entities with validation constraints (attributes), serialization metadata, etc. * Goal: discover and freeze this information at compile time (instead of runtime reflection), for faster startups and more robust DX (less late magic).

B. Compiled attributes (not just runtime)

  • Today, attributes work at runtime via reflection. * Work in progress: collect attributes at compile time, generate mappings (validation, serialization, etc.) and reduce runtime load.

C. Properly extend/override metadata… without enforced XML

  • Real cases (e.g. Sylius/Sulu): we extend validation constraints via YAML/XML. * Objective: to offer a modern alternative (dedicated “support” classes, compiled attributes) to extend models without locking projects into XML.

D. PHP Arrays with Strong Autocompletion

  • Exploration: Describe the config tree so that PHP tables benefit from rich IDE autocompletion (depth-dependent valid keys, inline doc). * Active collaboration with IDE teams (e.g. PhpStorm) to better support comments/doc and nested keys → Table DX greatly improved.

DX points discussed (and arbitrations)

  • YAML vs PHP performance: negligible differences in use (parse at build/cache). * Readability: YAML remains compact for app config; PHP gains in refactoring and typing. * Non-PHP teams: YAML remains universal (QA, ops, docs). * Flex: decisive argument for keeping YAML/XML where recipes must patch projects automatically.

What could “visibly” change

  • Fewer tabs and ambiguities in the docs (reducing recommended formats based on configuration type). * XML pushed back where it doesn't provide a direct benefit (semantic config & app routing). * Compiled attributes + resources: faster builds, more predictable bundles. * Smarter autocompletion for PHP arrays (better discovery of possible keys and values).

Summary

  • No “religious war”: YAML remains comfortable and interop; PHP is strong in IDE; XML is retreating where it is no longer useful. * Efforts are focused on global DX: Flex, doc, tools, compilation of attributes and safer formats. * Course: simplify choices, reduce dispersion, and accelerate the dev loop thanks to compiled metadata and significantly improved autocompletion.

3️⃣ Beyond the talks: the value of the meetup

Beyond technical topics, the event confirmed the importance of meetups for:

Meet the Parisian PHP community and discuss best practices.

Discover concrete approaches through live code, without superfluous slides.

Create links between experts, beginners and the curious, in a friendly atmosphere.

📌 Conclusion

Between simplified real-time thanks to SSE/ZMQ and reflection on DX in Symfony, this first meetup of the season laid solid foundations for future meetings. Many thanks to SQLI for the welcome and to the speakers for their energy and concrete demonstrations.

👉 See you next month for the continuation of the AFUP Paris meetings!

  • Sitemap - Hello - Blog - Apps - Photos - Contact - - - - - Legal mentions - Darkwood 2025, all rights reserved