Alexandre Daubois
@alexdaubois.bsky.social
📤 329
📥 63
📝 328
cto
@les-tilleuls.coop
/ @symfony.com+#frankenphp+
#php
core team • creator of ember
reposted by
Alexandre Daubois
Les-Tilleuls.coop
2 days ago
Un autre événement à ne pas manquer cet automne : nous serons les 8 et 9 octobre prochains au
#ForumPHP
en tant que sponsor Argent ! Retrouvez-nous sur notre stand ainsi que sur scène avec les interventions de
@soyuka.me
,
@alexdaubois.bsky.social
et
@dunglas.dev
. Vous y serez ?
0
2
1
Très heureux d'annoncer ma participation au
#ForumPHP
2026 🇫🇷🐘 Je serai présent début octobre a l’évènement de
@afup.org
pour vous montrer ce qui se passe au sein de l'Ecosystem Security Team de
@thephpf.bsky.social
que j'ai eu la chance de rejoindre day one 💜 👉
event.afup.org/forum-php-20...
4 days ago
0
2
2
reposted by
Alexandre Daubois
Antoine Bluchet @soyuka
14 days ago
@dunglas.dev
and I just published a preprint on exposing Hypermedia APIs to LLM agents via a Dynamic Gateway Architecture Thanks
@p20n.w3c.social.ap.brid.gy
for depositing this work
hal.science/hal-05630480
loading . . .
Making sure you're not a bot!
https://hal.science/hal-05630480
1
6
4
OPcache doesn't just cache opcodes. It runs a real compiler optimizer on them. SSA form, dead code elimination, type inference. Yes, in
#PHP
👇
about 1 month ago
1
1
0
ZTS (Zend Thread Safety): the
#PHP
layer most devs never see. In ZTS mode, every global becomes thread-local. Each thread gets its own executor, compiler, module globals. Full isolation. FPM doesn't need it: direct C globals, fastest path. FrankenPHP does: it runs PHP inside Go threads. 🧵
about 1 month ago
2
0
0
Generators vs Fibers in
#PHP
: both suspend execution, totally different mechanism. Generator: saves ONE execute_data frame. Yield pauses it, ->next() resumes. One level deep. Fiber: saves the ENTIRE call stack. Generator, stackless coroutine. Fiber, stackful coroutine.
about 1 month ago
0
2
2
#PHP
has inline caches and almost nobody knows 👀 $obj->name: first access does a hash lookup. But the engine stores the result offset in a "cache slot" embedded in the opcode. Next time, same class? Direct read. No lookup. Works for methods, constants, type checks too.
about 1 month ago
0
2
0
Traits in
#PHP
aren't delegated. They're literally memcpy'd into the class. The engine copies each zend_function entry into the consuming class's function_table. "insteadof" picks the winner. "as" creates an alias to the same oparray. After resolution? The trait is gone. Zero runtime cost.
about 1 month ago
0
1
0
Let's have a look at this
#PHP
RFC: Friends, by Daniel Scherzer. A class could grant select OTHER classes access to its private and protected members, without making anything public. Let's see what's actually on the table. 🧵
about 1 month ago
1
0
0
#PHP
type juggling auth bypass: if ($input == $hash) with a hash starting "0e" + digits: PHP reads it as 0 (scientific notation). MD5("240610708") = "0e462097..." = 0. MD5("QNKCDZO") = "0e830400..." = 0. 0 == 0: auth bypassed. Fix: === or hash_equals(). Never == for security.
about 1 month ago
1
2
1
reposted by
Alexandre Daubois
Les-Tilleuls.coop
about 1 month ago
Moins d'une semaine avant notre API Platform Meetup à Lyon ! Au programme : 🎙️Alexandre Noziere avec "Marier API Platform et un ORM non-Doctrine : le bridge Propel de Thelia 3" 🎙️
@alexdaubois.bsky.social
avec le sujet "FrankenPHP: Le Serveur PHP Sous Stéroïdes"
www.meetup.com/fr-fr/api-pl...
loading . . .
API Platform Meetup @Lyon, jeu. 4 juin 2026, 19:00 | Meetup
Rejoignez-nous pour une soirée exclusive dédiée à **API Platform**. En compagnie de nos experts, venez découvrir les dernières avancées de l'écosystème et la façon dont il
https://www.meetup.com/fr-fr/api-platform/events/314846084/
0
1
1
Timing attacks: === stops at first different byte. Attacker measures response time to guess secrets char by char. hash_equals() compares ALL bytes. Constant time. Go: crypto/subtle.ConstantTimeCompare() Comparing secrets with ===? You leak info through time.
about 1 month ago
0
0
2
reposted by
Alexandre Daubois
Les-Tilleuls.coop
about 1 month ago
Retrouvez-nous ce soir dans nos locaux de Lyon pour l'Apéro Web mensuel ! Au programme : échanges passionnants et des talks par
@alexdaubois.bsky.social
et Alexis Guerre. On a hâte de vous accueillir ! Inscriptions ici :
www.meetup.com/fr-FR/apero-...
loading . . .
Apéro Web Lyon - Mai 2026, jeu. 28 mai 2026, 19:00 | Meetup
📢 Fin **mai,** nous aborderons la cybersécurité sur 2 sujets, chaleureusement accueillis par **Les-Tilleuls.coop** ! L'événement est toujours **gratuit, sur place ou sur
https://www.meetup.com/fr-FR/apero-web-lyon/events/314458784/
0
1
1
PHP compiles your code in 2 passes. And honestly, most devs never look past "it just runs". Here's what really happens between your file and the VM 👇
about 1 month ago
1
1
0
$GLOBALS used to introduce aliasing complexity in the engine. Because it could reference local variables, Zend had to handle indirect entries (IS_INDIRECT) in certain array access paths.
#PHP
8.1 restricted $GLOBALS writes, removing that edge case and simplifying hot paths.
about 2 months ago
0
2
1
#PHP
fibers don't use threads: they use stack swapping. Fiber::suspend() saves the current C stack and VM state, then jumps back to the parent. Fiber::resume() restores everything and continues exactly where you left off. Revolt and Amp are built entirely on this primitive.
about 2 months ago
0
0
0
#Golang's
scheduler has a magic number: 61. Every 61 goroutine schedules, the runtime checks the global queue instead of the local one. Why 61? It's prime, so it never aligns with any other periodic check. If it were 64, you'd get pathological starvation patterns, and 61 breaks every harmonic.
about 2 months ago
0
3
0
One underrated attack vector is your lockfile. 🔐 composer.lock, package-lock.json, go.sum... They all pin versions, but the upstream registry can still ship a malicious 1.2.3 if a maintainer's account gets compromised. 🧵
about 2 months ago
1
1
0
unserialize() in
#PHP
isn't just "unsafe with user input." It's a remote code execution primitive. Here's the full attack chain 👇
about 2 months ago
1
0
2
Here we go for the third talk of the week! This time at home, in Lyon, France 🇫🇷 for the
@afup.org
Day. Jetlag's going to hit hard but it's an event you can't miss. We'll talk about
#JsonPath
in
#PHP
!
about 2 months ago
0
1
2
Thank you so much for having me
#PHPTek
@phparch.com
! First talk in the USA for me, and I'm getting back in September in San Francisco 🇺🇸 Had a blast to talk about
#FrankenPHP
, cybersecurity and meeting people from
@thephpf.bsky.social
and the ecosystem 🐘💜
about 2 months ago
0
2
2
reposted by
Alexandre Daubois
GromNaN
about 2 months ago
A huge thank you to
@fabien.potencier.org
@nicolasgrekas.bsky.social
@alexdaubois.bsky.social
@jderusse.bsky.social
@javiereguiluz.bsky.social
and all the
#Symfony
Core Team involved in triaging the security reports, fixing the bugs, reviewing the PRs and releasing the patched versions.
add a skeleton here at some point
0
7
2
reposted by
Alexandre Daubois
Fabien Potencier
about 2 months ago
During the last few weeks, the
#Symfony
core team has been hard at work fixing a long list of vulnerabilities for both
#Symfony
and
#Twig
. Today, we're publishing that work in the biggest security patch releases ever. Bare with us and wish us luck 🍀
2
28
18
#PHP
attributes look like decorators... end of the resemblance 😄 Attributes are pure metadata, stored in the class definition. They do *nothing* on their own. A framework must call ReflectionClass::getAttributes() and instantiate them to make anything happen. 🧵
about 2 months ago
1
0
0
Named arguments in
#PHP
8.0+ are resolved at compile time. Not runtime. The compiler maps argument names to parameter positions in the function signature. The opcodes use positional slots. $name → position #2 → SEND_VAL to slot #2. One exception... 🧵
about 2 months ago
1
2
1
It's been quite some time since I visited the US! 🇺🇸 Finishing up details for my talks at @phptek (
phptek.io
). Let's talk about
#FrankenPHP
and
#cybersecurity
! See you tomorrow 🥳
about 2 months ago
0
2
0
#PHP
strings aren't C "char*". They're zend_string. A zend_string carries a GC header (8 bytes on 64-bit) + cached hash (8 bytes) + length (8 bytes) + the actual bytes inline at the end of the struct. The hash is computed ONCE on first use and cached forever. Every subsequent hash lookup is free.
about 2 months ago
0
1
0
It's been an incredible experience to be part of the selection committee of the @apiplatform Conference. 🕷️ This year we'll be full of
#PHP
,
#FrankenPHP
and APIPlatform talks. Let's push the boundaries: expect topics rarely shown at conferences! Full lineup 👉
api-platform.com/fr/con/2026/
loading . . .
about 2 months ago
0
0
0
The . (concat) operator in
#PHP
doesn't create a new string every time. If the left operand is a temporary with refcount=1, PHP *REALLOCS* it in place. "a" . "b" . "c" . "d" → in the best case, one allocation + three reallocs. Not four allocations. The engine tries hard to avoid copying.
about 2 months ago
0
1
0
#PHP's
cycle collector doesn't run on every unset(). When a refcount decreases but doesn't hit 0, the zval MAY be a cycle root. It goes into a "root buffer". When the buffer hits 10,000 entries, the collector runs. That's the threshold. 10,000 potential roots. 🧵
about 2 months ago
1
0
0
New
#PHP
RFC dropped: Bound-Erased Generic Types, by Seifeddine Gmati (@azjezz). And everybody's talking about it! Generics in PHP, for real this time? Sort of. Let's look at what it actually proposes, and what it deliberately doesn't. 🧵
about 2 months ago
1
3
0
I'm absolutely thrilled to be back at
@les-tilleuls.coop
's
#APIPlatformCon
this year again! 🕷️ Let's make observability pleasant: "Observe FrankenPHP: DX Serving Performance"! If you follow me for some time, you know what we're going to deep-dive into 😉🔥 👉
api-platform.com/fr/con/2026/
2 months ago
0
2
2
When you write `class Dog extends Animal`,
#PHP
doesn't create dynamic lookups. At compile time, every method from Animal is COPIED into Dog's function_table. Dog doesn't have a pointer to Animal's methods. It HAS the methods. 🧵
2 months ago
1
1
0
OPcache doesn't just cache opcodes, it optimizes them. It builds an SSA (Static Single Assignment) form of your code, like a real compiler! Then it runs optimization passes: constant propagation, dead code elimination, type inference... Your PHP code is kind of rewritten every time!
2 months ago
0
2
1
#PHP
integers are not "just ints": they're zend_long, a platform-dependent C type. 64-bit system, 64-bit signed integer. But what if it overflows? Well, PHP silently converts to float. No exception, no error. So PHP_INT_MAX + 1 is a float: not a crash, not a wrap-around.
2 months ago
0
0
0
#PHP
exceptions don't use C setjmp/longjmp anymore since PHP 7. When an exception is thrown, the engine sets a flag on the execute_data and RETURNS to the VM dispatcher. The dispatcher checks the flag, walks the try/catch table, finds the matching catch block, and jumps to it. 🧵
2 months ago
1
2
1
When you write `use ($x)`,
#PHP
copies the zval into the closure's scope. When you write `use (&$x)`, it wraps $x in a zend_reference and shares it. Closures don't "see" the parent scope: they carry their snapshot. No hidden pointer to the parent frame: it might be gone when the closure runs.
2 months ago
0
2
0
reposted by
Alexandre Daubois
Les-Tilleuls.coop
2 months ago
We're really excited to travel to Chicago mid-May to speak at PHP Tek, one of the biggest PHP conferences in the world. Make sure to attend
@alexdaubois.bsky.social
talks scheduled. Who's coming?
0
4
2
I can't wait to get back to the USA to give 2 talks about
#PHP
! Let's meet in 2 weeks in Chicago for @phptek 🚀
add a skeleton here at some point
2 months ago
0
0
0
In
#PHP
, references are a SEPARATE type: IS_REFERENCE. $a = 1 → zval { type: IS_LONG, value: 1 } $b = &$a → both point to a zend_reference { refcount: 2, value: zval{1} } The reference is a wrapper AROUND the value. Not a flag on the value. This is why PHP 7+ became faster... 🧵
2 months ago
1
1
0
Every local variable in a
#PHP
function is a "Compiled Variable." At compile time, $a, $b, $name... each gets a fixed integer slot in the stack frame. Accessing $a = reading slot #0 from a C array. It's O(1). That's why local variables are the fastest storage in PHP. They're array indexes!
2 months ago
0
2
0
When you call $obj->method() in
#PHP
, here's what the engine does: 1. Read $obj's class entry (zend_class_entry*) 2. Look up "method" in the class's function_table 3. If not found, check parent classes walking the inheritance chain 🧵
2 months ago
1
2
0
Ember isn't just a TUI for Caddy/#PHP apps: • ember status: one-line health check, exit code 0 if OK • ember --json --once: JSON snapshot for CI pipelines • ember --daemon --expose :9191: headless sidecar that serves
#Prometheus
metrics • ember diff before.json after.json: compare across deploys
2 months ago
0
0
0
#PHP's
VM has 3 dispatch modes you can choose. CALL: each handler is a C function. The VM calls them one by one. SWITCH: one giant switch(opcode) in a loop. Classic interpreter. GOTO: computed goto. Each handler jumps directly to the next. Default is HYBRID: goto for hot paths, call for the rest.
2 months ago
0
0
0
The Zend VM of
#PHP
doesn't have one ADD handler. It has DOZENS. ZEND_ADD_LONG_NO_OVERFLOW, ZEND_ADD_DOUBLE... At compile time, the engine picks the most specific handler for your operand types. $a + $b with two known integers is a direct C addition. Thousands of specialized handlers.
2 months ago
0
0
0
#PHP's
foreach doesn't copy your array... Well, not anymore 😄 In PHP 7+, foreach creates an internal iterator (HashPosition) on the array. It walks arData linearly. Copy-on-write protects you: if you modify the array inside the loop, THEN it copies. No modification? No copy, zero overhead.
2 months ago
0
2
0
~15 MB RSS, ~0.3ms per poll cycle. The Docker image is a scratch-based binary + CA certs. No runtime dependencies. Zero config, read-only by design, and officially recommended by
#FrankenPHP
for all
#PHP
apps, also useful for Caddy-based apps. What are you waiting for? 🔥
2 months ago
0
0
0
reposted by
Alexandre Daubois
Les-Tilleuls.coop
2 months ago
Big updates for the FrankenPHP ecosystem: Ember 1.2 & 1.3 are out! The Caddy monitor is now a full-fledged observability platform. Details by
@alexdaubois.bsky.social
⬇️
les-tilleuls.coop/en/blog/embe...
loading . . .
Ember 1.2 / 1.3: Logs, Plugins, and a Platform That Grows With You | Les-Tilleuls.coop
Discover the latest features of Ember 1.2 and 1.3, which will make your observability stack even better!
https://les-tilleuls.coop/en/blog/ember-1-2-1-3-features-highlights
0
1
1
Ember 1.3 is out! 🔥🐘 I wrote a blog post about the new features of 1.2 & 1.3: plugin system, access and runtime logs live visualisation, upstreams health, Docker Hub... a lot to discover! Everything you need to know 👉
les-tilleuls.coop/en/blog/embe...
2 months ago
0
2
1
#PHP
8.4 lazy objects use the SAME engine fallback as __get/__set. When a property is accessed on a lazy object, the engine sees it's "uninitialized." This triggers the property fallback path: the same one used for magic methods! But instead of calling __get(), it calls your initializer once. 🧵
3 months ago
1
4
0
Load more
feeds!
log in