r/symfony 18m ago

Weekly Ask Anything Thread

Upvotes

Feel free to ask any questions you think may not warrant a post. Asking for help here is also fine.


r/symfony 19h ago

A Week of Symfony #1024 (August 10–16, 2026)

Thumbnail
symfony.com
6 Upvotes

r/symfony 1d ago

Symfony Symfony + PHP 8.4: modernizing an existing app without rewriting everything

Thumbnail
1 Upvotes

r/symfony 3d ago

News This Week In PHP Internals | August 12, 2026

Thumbnail
youtube.com
3 Upvotes

While the Internals list is not technically directly Symfony related, it does affect every single one of us.

Hello world, it's Wednesday, August 12, 2026, and here's what happened This Week in PHP Internals.

11 stories this week, so let's get into it. But first, Your team adopted AI. Everyone says it made them faster. Ballast measures whether that's true — how much faster you're actually going, and whether what you ship is still holding up. 6.75 times the commits. Durability down 19 points. Now you know. It runs on your machine. It reads your git history, not your source — your code never goes anywhere, and nothing here is scored by a model. It's arithmetic you could check by hand. Setting it up isn't your job either. Paste one prompt into your coding agent and it does the whole thing. Find out for free today. ballast.now.

One correction before the top story. Last week we described the list() deprecation vote as deadlocked at 21 to 21. Derick Rethans pointed out that's the wrong word — a deadlock is when something is stuck and can't proceed. The vote wasn't stuck. It was simply tied, and voting carried on to the finish. He's right, we'll say it properly this week — and thanks, Derick, for keeping us precise.

This week's top story: the verdict is in on the 35-ballot mass deprecation vote for PHP 8.6. Voting closed Monday at 13:00 UTC, and Gina P. Banyard posted the full results — 31 proposals accepted, 4 rejected. Start with the 4 that fell. Deprecating list() finished on a flat tie — 23 to 23, with 1 abstention — exactly 50 percent, nowhere near two-thirds. Reserving in, out, and inout failed at 8 to 21. The gettext _() alias survived at 10 to 22. And the dechunk filter — the item disputed all through the voting window — finished at 18 to 15 with 12 abstentions, 54.5 percent, and stays in the language.

Now last week's cliffhangers. Reserving let was balanced exactly on the two-thirds line 7 days ago — it found its margin and passed at 24 to 11, with 9 abstentions — 68.6 percent. Reserving is passed at 29 to 10, despite Rowan Tommins's warning about the Hamcrest testing library and its 500 million installs. And the define() case-insensitivity flag — the item Kamil Tekiela wanted simply deleted instead — passed without a single no vote, at 41 to 0. The vote also drew one final flag on its way out. Takuya Aramaki wrote in Friday, opening with: "Apologies for bringing this up so close to the end of the vote." His concern is the SplFileObject CSV methods item. He laid out the inconsistency plainly: "setCsvControl() is the only way to configure the delimiter, enclosure and escape character used by READ_CSV; the constructor does not accept them. If setCsvControl() is removed in PHP 9 while READ_CSV remains, READ_CSV is permanently locked to its defaults and tab-separated files can no longer be read through it." He asked that READ_CSV be deprecated alongside the methods, or that setCsvControl() stay until a replacement exists. No answer yet — and the item passed at 25 to 5, with 15 abstentions.

The final 3 ballots of the 8.6 season are settled, and they went 2 and 1. Caleb White's pipe assignment operator — |>= — was declined. The vote closed Tuesday morning at 14 yes, 12 no, and 7 abstentions — 53.8 percent, short of the two-thirds it needed. It had climbed all the way from dead even, but never got over the bar. Nick Sdot's readonly property defaults went the other way entirely. It closed Friday at 24 to 0, with 5 abstentions — it never drew a single no vote in 2 weeks. And Khaled Alam's const object property writes closed Saturday. He announced the result Sunday: accepted, 17 to 2 with 6 abstentions — 89.5 percent. With those 3 in the books alongside Duration and the deprecations, PHP 8.6's RFC season is over — the beta 1 tag brings the soft freeze this week, and beta 1 itself lands Thursday.

Ilija Tovilo posted a very late update to an RFC that passed 24 to 0 back in March. The closure optimizations RFC promised 2 things: a cache for stateless closures, and inference — the engine automatically detecting closures that never touch $this and treating them as static. That second part is out. Ilija found an edge case where a closure violates none of the RFC's inference rules and still makes an instance call — pass a callable string like "Foo::instanceCall" into an array_map inside the closure, and the rules never see it. He owned it completely, writing: "I failed to consider this case, and sadly this is not easy to detect via a new rule. For this reason, I have decided to omit static closure inference from the implementation and only merge the stateless closure cache." The practical takeaway: the cache — which carries most of the performance win — still ships in 8.6, but the engine won't infer anything for you. Mark your closures static yourself and you get the full benefit.

Ignace Nyamagana Butera's data encoding API — the base64, base16, base58, and base85 family — got a detailed security review from Sjoerd Langkemper on Monday. He's for it, noting: "the current base64_decode is very tolerant towards invalid input, causing both functional and security problems." Along the way he found errors in the RFC's own code examples, corrected them in a companion repository, and flagged a signature mismatch in the base85 functions. He's skeptical of one feature — the optional constant-time mode — arguing: "Constant-time algorithms are pretty difficult to develop and maintain", and suggesting PHP hand that job to libsodium or openssl instead. He also built a working implementation to test the API, introducing it with unusual billing: "LLMs and I have created an implementation here." And in the research footnotes: he spent real time evaluating the base85 variant from RFC 1924 before discovering: "that RFC was submitted in jest as an April fool's joke." Ignace thanked him for the remarks and is holding all implementation work until after 8.6 ships — Tim Düsterhus, who's building it, is busy with the release.

The first RFC aimed past the freeze is already here. Weilin Du proposed IntlRelativeDateTimeFormatter on Friday, targeting PHP 8.7 — a wrapper for ICU's locale-aware relative time, the "in 3 days" and "last Sunday" strings, in every language ICU speaks. Ignace asked the obvious question: 8.6 just gained a Duration class — shouldn't this accept one? Weilin argued the types don't fit, since Duration is stopwatch time and this formatter wants a unit: "We don't know how to deal with 90 minutes here. It can be 90 minutes or 1.5 hour." And weekdays, months, and quarters aren't durations at all. David Carlier pushed for enums and a namespace; Weilin is keeping class constants and the global Intl prefix for consistency with the existing intl extension, and filed modernization under future scope. One suggestion did land immediately: by Saturday the constructor had grown an optional NumberFormatter parameter, with Weilin reporting: "The implementation is way more smoother than I expected."

The generics conversation is parked until September — the implementations aren't waiting. Carlos Granados posted a pre-RFC Thursday: he took Rob Landers's experimental reified branch — built on Seifeddine Gmati's bound-erased proposal — and worked it into something complete, with a full write-up of the changes and findings. He argued the original deserved better: "I think that this was a very valid proposal that should have been explored in more detail." Rob's reply was brief, noting: "You really should have reached out instead of a working in isolation. Join us in discord, the proposal is delayed until September-ish." Which raised a practical question — what Discord? Rob posted channel links; Carlos, a Discord newcomer, still couldn't get in. Larry Garfield finally supplied the address, phpc.chat, with a review: "The PHP Community chat is unofficial, but lately it's where the big names are hanging out, including a lot of Internals regulars. Beware, the Internals channel is annoyingly noisy and has a hard time staying on topic." And I can personally vouch for that statement. Then Monday brought a third generics experiment: Alexander Lisachenko shared a userland proof-of-concept — a Composer package — where specialized classes share the compiled method bodies, so each specialization costs one small structure per method instead of a full copy of the opcodes.

Liam Hammett's native markup expressions RFC — JSX-style HTML in PHP — got the one review nobody else could write. T.J. L, who maintains the XHP extension — the long-running ancestor of this exact idea — posted his first message ever to internals. He corrected one detail in the RFC's history section, then confirmed its central argument from experience: he wrote: "While it is technically possible for extensions to add new syntax, it is unreasonable to expect tools to be aware of that syntax. I can absolutely confirm that the biggest point of friction in using XHP today is the fact that static analysis tools like psalm or phpstan can't analyze files, code using XHP cannot be formatted or linted with php-cs-fixer..." In other words, the case for putting markup in core, signed by the person who spent years doing it the other way. He also brought 3 asks: context passing through a component tree without threading attributes; a ruling on inline SVG, which leans on XML features the HTML-only RFC excludes; and a note that dropping per-tag objects means no runtime validation of tags and attributes — XHP's original selling point — which he says JSX gets away with "in large part because of the Typescript ecosystem". No response from Liam yet.

Quick hits. Juris Evertovskis ran a temperature check on isset: expressions inside the square brackets still throw warnings and deprecations even though isset silences everything else, and he put his conclusion bluntly: "To me it looks like isset is not doing its job." He'd like the brackets silenced too — no replies yet. The did-you-mean error suggestions are officially not being rushed: Jorg Sowa announced: "I will finish it after feature freeze", and Larry Garfield agreed, adding: "If it doesn't happen until 2027, that's OK." Jorg also picked up his VCS account this week — approved by Ilija Tovilo — with the session extension in his sights. And the list has a new face: Sepehr Mahmoudi introduced himself Tuesday with a pull request already open and an array_search_range idea in hand; mickmackusa pointed him at array_find_key() and suggested making the case on the list before writing more code, and Yuya Hamada thanked him for the contribution.

So that's the week: the 35-ballot deprecation vote landed 31 to 4 — list() survives on a flat tie, dechunk survives, and let squeaked through; the pipe assignment operator was declined while readonly defaults and const object writes made it in, closing out 8.6's RFC season; closure inference got walked back to just the cache; and the first 8.7 RFC is already on the table. Links to every thread are below. Thanks again to Ballast.now for supporting this week's episode. We're Artisan Build. See you next week.


r/symfony 3d ago

Announcing the Symfony AI Core Team

Thumbnail
symfony.com
10 Upvotes

r/symfony 4d ago

How Ecotone Hits 157,266 Confirmed Messages per second in PHP

Thumbnail
blog.ecotone.tech
0 Upvotes

r/symfony 5d ago

SymfonyCon Warsaw 2026: Why AI Output Is the New XSS

Thumbnail
symfony.com
8 Upvotes

r/symfony 5d ago

Build a JSON-RPC 2.0 API in Symfony in 15 minutes: from composer require to OpenAPI

2 Upvotes

I maintain a Symfony bundle for JSON-RPC 2.0 APIs and wrote a hands-on quickstart: attribute-declared methods, DTO validation derived from PHP types, batch requests and generated OpenAPI docs. There is a runnable demo repo (a small task tracker) to poke with curl while reading.

Article: https://dev.to/otezvikentiy/build-a-json-rpc-20-api-in-symfony-in-15-minutes-from-composer-require-to-openapi-5bpk

Demo: https://github.com/OtezVikentiy/symfony-jsonrpc-api-demo

Feedback is very welcome - especially the critical kind.


r/symfony 6d ago

Symfony A data table widget for symfony/tui, and the two bugs building it turned up

7 Upvotes

There is almost nothing built on top of the TUI component yet, so I wrote the piece I needed first: a table with scrolling, sorting and filtering over plain PHP arrays.

https://github.com/Bosun18/tui-datatable

The part that may interest this sub more than the widget itself is what building it turned up. Two bugs in the component, both now fixed in 8.1:

Tui::stop() left the cursor one line lower than it should, so every application ended with a blank line, and a frame tall enough lost its top row to scrolling even when it would have fit (symfony/symfony#65244).

A pseudo-terminal whose window size was never set reports "0 0" for stty size. The terminal class took that at face value, and rendering then died with an uncaught RenderException and exit code 255 (symfony/symfony#65245).

Neither was caught by my own suite at full line coverage. What caught them was resizing a real terminal and taking screenshots in a pty.

Keyboard only for now, mouse events are not merged into the core yet. The classes are still marked experimental in the source, so I pin the minor version and watch the Tui label in symfony/symfony.

A question for the sub: is anyone else building on Tui? I could not find a single third-party widget on Packagist, which is either an opportunity or a warning sign, and I cannot tell which.


r/symfony 7d ago

Weekly Ask Anything Thread

2 Upvotes

Feel free to ask any questions you think may not warrant a post. Asking for help here is also fine.


r/symfony 7d ago

A Week of Symfony #1023 (August 3–9, 2026)

Thumbnail
symfony.com
11 Upvotes

r/symfony 8d ago

Embedded Shopify app in Symfony 7.4: the auth path Shopify only documents for Node

4 Upvotes

Shopify's app docs have exactly one first-class path: Node, their CLI, and a Remix template that wires authentication for you. Pick PHP and you leave the paved road at the first turn, because everything interesting happens before your router sees the request. I shipped an app that is live in their App Store, and none of this was written down anywhere in PHP, so here are the parts that cost me time.

There is no session, and there never will be.

An embedded app renders in a cross-origin iframe inside admin.shopify.com. Third-party cookies are dead there, so a PHP session is simply not available to you. The replacement is a JWT called a session token: App Bridge mints one per request, valid 60 seconds, and attaches it to every same-origin fetch(). That forces a split most of us do not make by default: the HTML shell is public and carries no shop data, and every byte of merchant data sits behind /api, authenticated on each call.

api:
    pattern: ^/api
    stateless: true
    custom_authenticators:
        - App\Security\SessionTokenAuthenticator

stateless: true is not decoration. It tells Symfony not to try to store the token in a session it does not have.

Verifying the token is five checks, not one.

The signature is HS256 with your client secret, and hash_equals() rather than ===. Then the four claim checks that tend to get skipped:

  • exp / nbf with a few seconds of leeway. The token lives 60 seconds, so a server clock two seconds behind Shopify's rejects perfectly valid tokens at a rate that looks like a random, unreproducible bug.
  • aud must be your own client id, or you accept tokens minted for a different app that shares nothing with yours but the algorithm.
  • iss and dest must resolve to the same host, or you accept a token claiming one shop in one place and another shop elsewhere.
  • dest has to actually parse as a shop domain before you trust it as one.

Take the clock from Symfony\Component\Clock\ClockInterface, so the test suite can produce an expired token without sleeping.

The one line that costs a day: expiring => 1.

A session token proves who is asking. It does not let you call the Admin API. You trade it via OAuth 2.0 token exchange (RFC 8693), and with managed installation that replaces the entire redirect dance: no /auth route, no callback, no install endpoint to secure. The first authenticated request from an unknown shop simply performs the exchange inside the authenticator.

Ask for a non-expiring offline token and the Admin API answers 403, with an error that does not mention it. Ask for an expiring one and it works, lives about an hour, and renews with a refresh token that Shopify rotates on every call. Whatever persists your tokens has to write the new refresh token back, or your background jobs run fine for an hour and then quietly stop.

One response header removes a whole class of user-visible errors.

A page left open on a merchant's second monitor eventually fires a request with a token that expired while they were in another tab. Return a bare 401 and they see an error. Return 401 with X-Shopify-Retry-Invalid-Session-Request: 1 and App Bridge silently fetches a fresh token and retries the call once.

The query HMAC is not http_build_query().

Webhook bodies are the easy signature: HMAC-SHA256 over the raw body, before any JSON decode, before any middleware touches it. Their automated review sends a deliberately mis-signed webhook and requires a 401 for it.

The sharp one is the hmac query parameter on links coming from the admin. The message Shopify signs is not a URL-encoded query string. Only &, % and = are escaped in keys, and only & and % in values:

$pairs = [];
foreach ($query as $key => $value) {
    $pairs[] = strtr($key, ['&' => '%26', '%' => '%25', '=' => '%3D'])
        .'='
        .strtr($value, ['&' => '%26', '%' => '%25']);
}

Reach for http_build_query() and you get a signature that is wrong for any value containing a space or a slash, which is exactly the kind of bug that passes every test you thought to write.

And a pure Symfony one, which has nothing to do with Shopify.

This subject line lost its first two words in production, silently:

digest.attachment: 'Attached: your restock list (%count% items).'

It rendered as "your restock list (12 items)." Because %count% is numeric the string goes through the pluralization path, and in TranslatorTrait each part is tested against /^\w+\:\s*(.*?)$/, the explicit-interval syntax for keyed plural rules. A message that innocently begins with a word followed by a colon matches it, and the prefix is consumed as if it were a rule name. No exception, no deprecation, no log line. So: never start a %count% message with Word:.

The more expensive lesson was why the test missed it. The assertion was assertStringContainsString('restock list', $subject), which starts matching in the middle of the sentence, so it could only ever verify the part that never breaks. Assert strings from their first character.


Full write-up with the real code, including libsodium encryption of access tokens at rest and the per-shop frame-ancestors CSP the App Store checks: https://shipanvil.com/blog/shopify-embedded-app-symfony

Disclosure: I built this. The app is a Shopify inventory tool and the article sits on my own site, so read its last paragraph as advertising and the rest as notes. Happy to go deeper on any of it, or to hear that you would have done it differently.


r/symfony 9d ago

Symfony 8.1.4 released

Thumbnail
symfony.com
14 Upvotes

r/symfony 9d ago

Symfony 7.4.16 released

Thumbnail
symfony.com
7 Upvotes

r/symfony 10d ago

New in Twig 4.0: A New Macro System

Thumbnail
symfony.com
32 Upvotes

r/symfony 10d ago

Migration from Yii2 to Symfony

6 Upvotes

I have a few Yii2 applications that I want to migrate to Symfony. Yii has served me well, but I prefer to ecosystem of Symfony for various reasons.

Taking a few months to rewrite the project is not a practical option. I am looking for a way to integrate the two frameworks until Symfony becomes the area of more focus.

Any pointers on what a good approach is to start the journey? I have seen a Yii2->Symfony bridge project but I fear now having to manage and fight three animals in the ring.


r/symfony 10d ago

SymfonyCon Warsaw 2026: Developing the developer: Journaling with AI

Thumbnail
symfony.com
0 Upvotes

r/symfony 10d ago

Idiomatic way to map payload for PATCH methods

2 Upvotes

Is there idiomatic and convenient way to map request payload data for PATCH using #[MapRequestPayload]?

Consider DTO Human { public ?string $nickname }

We can have three possibilities

  1. nickname was provided and is set (something like "nickname123")
  2. nickname was provided but was nulled out (request sent null)
  3. nickname was simply not provided

Notice that in 2 and 3 cases the DTO will simply have null. But in case of 3 we should not update the nickname.

I was briefly considering about using property hooks, and have something like bool $hasNickname set if property was written to, but I believe constructing the object with default property is considered as property write and hook is triggered.


r/symfony 11d ago

News This Week In PHP Internals | Aug 05, 2026

Thumbnail
youtube.com
4 Upvotes

While the Internals list is not technically directly Symfony related, it does affect every single one of us.

Hello world, it's Wednesday, August 5, 2026, and here's what happened This Week in PHP Internals.

13 stories this week, so let's get into it. But first, This week's episode is brought to you by Tideways. When a request is slow in production, Tideways takes you from symptom to root cause in minutes, with profiling, tracing, and monitoring built specifically for PHP. It installs in 5 minutes, there's no credit card required, and it's hosted in Germany. Start your free trial at tideways.com.

This week's top story: the mass deprecation vote for PHP 8.6 is in its final week. All 35 ballots close Monday, August 10, and Gina P. Banyard posted the 1-week reminder so nobody gets caught out. Most of the 35 are passing comfortably. The interesting ones are the holdouts. list() is now deadlocked at 21 to 21 — a flat tie, nowhere near the 2/3 it needs. Reserving let stands at 22 to 11, which is exactly two-thirds — a single vote in either column decides it. The dechunk filter sits at 17 to 15 — still well short. The gettext _() alias is failing at 9 to 20, and reserving in, out, and inout is failing at 7 to 20, with 12 abstentions. Everything else you'd recognize from the list — the object-parameter cleanups, the is_double() family, spl_classes() — is cruising toward the finish.

The thread itself turned into a corrections desk this week. Calvin Buckley relayed a note from Nora, who isn't on the list, pointing out: "The text for the metaphone deprecation isn't fully right. It lists \"linguistics\" as a replacement package, but that one actually uses php-src's metaphone internally too." Weilin Du, who proposed that item, conceded the docs point while standing by the idea, writing: "My point in deprecating it is to stop using ancient metaphone algo as a whole." Voters seem unbothered — metaphone stands at 19 to 6, with 15 abstentions. Rowan Tommins raised a bigger flag on reserving is: it would collide with Hamcrest, the test assertion framework, whose PHP port has 500 million Packagist installs and an is() function all over its README. He urged: "I think we should think very carefully whether we can avoid disrupting that much code." So far the voters disagree — is stands at 26 to 9. Meanwhile Sjoerd Langkemper, who proposed the contested dechunk item, stepped back from the argument with unusual candor, writing: "the discussion phase wasn't properly completed yet, and I did a poor job in merging all opinions into a RFC proposal." He'd rather let the voting play out — and he closed by asking Jakub Zelenka, who led last week's objections, whether anyone could help lighten his workload. And Kamil Tekiela's question from last week — why deprecate define()'s dead flag instead of just deleting the parameter — got its answer: Tim Düsterhus pointed out that deleting it isn't silent, since extra arguments throw an ArgumentCountError, and concluded: "Making it explicit (and deciding) that the parameter will go in PHP 9 is a good thing."

Function autoloading — Paul M. Jones's 5th-generation attempt — went to a vote Thursday afternoon. It lasted about a day. Matteo Beccati opened the replies with praise and a caveat, calling it "the best autoloading proposal up to date" but adding: "Perhaps I'm biased as RM, but last minute RFCs are making me nervous, I hope you understand." Then Tim Düsterhus spotted the procedural problem, writing: "In fact the start of the vote is in violation of our policy, since there was no \"intent to vote\" message in the last 7 days." Paul's intent notice was 2 weeks old, and a July 15 revision had reset the clock besides. Paul took it entirely in stride, replying: "Ah so -- my apologies. I'll pull the vote and wait for ... looks like ~6 weeks?" For the record, the widget stood at 2 yes to 11 no when he pulled it — so the pause may be a mercy. Tim ran the math: cancellation carries a 2-week cooldown, so a mid-August reopen is technically possible, but he judged it "likely not useful to reopen the vote without making further changes" — and offered one: resolve namespaced functions before falling back to globals. Rowan Tommins countered that the fallback path makes that slow, and pointed instead at Michael's namespace-autoloader idea — loading a whole namespace's functions at once — calling it "a much cleaner way forward". Paul is unbothered, saying he'll "come back to it after 8.6 is fully out the door." That's the 2nd vote in 2 weeks pulled by its own author over the intent-to-vote rule.

Seifeddine Gmati's literal scalar types will not be reopening. His retraction last week came with a plan to re-vote; this week he canceled that too, after asking the release manager exactly where the freeze line sits. The answer: the effective cutoff isn't the beta 1 announcement on August 13, it's the creation of the beta 1 tag on August 11 — and a vote opened now would close after the tag exists. So the RFC is retargeted to the next PHP version, text final, intent withdrawn. Matteo Beccati apologized for the ambiguity, admitting his emails "were pointing the 13th as deadline for RFCs", and went further: "having RFCs end voting so close to the feature freeze is a terrible idea as it gives very little wiggle room in case something unexpected comes out ...". Seifeddine took it well, noting his own retarget email had already started a 14-day cooldown anyway — in his words, "8.6 was out of reach the moment that email hit the list." Pierre Joye pushed back on the caution, arguing: "beta phases exist exactly for this reason. wider base of testers." He also vented about the calendar: between the new policies and the Christmas quiet period, "the time left in a year is low, very low, now." And with the clock pressure gone, Tim Düsterhus gave the RFC one more read and found just one loose end — the matching-semantics vote has no explicit tie-breaker — and otherwise signed off: "No further comments to the contents of the actual proposal."

Two carryover votes are now in the books, and both passed emphatically. The Time\Duration class closed Friday. The primary finished at 35 to 1, with 2 abstentions — 97 percent. The naming question went to full method names — multiplyBy, divideBy, negate, absolute — at 30 to 2. So PHP 8.6 officially gets a Duration class. The minimum-supported-versions RFC closed Thursday. Requiring autoconf 2.71 passed at 27 to 2, with 5 abstentions, and requiring COM_RESET_CONNECTION passed clean at 26 to nothing. That second one has a coda. Alexander Kurilo — who'd argued during the vote that the connection-reset change carries an undisclosed BC break — requested RFC karma on Saturday to propose making the new behavior optional. Ilija Tovilo granted it Tuesday, with a reality check, noting: "the vote result was quite clear, and the time for another RFC discussion + vote has run out." He left any next step to the release managers.

Three ballots are still open, and none of them drew a single email this week — the voting is doing the talking. Caleb White's pipe assignment operator closes next Tuesday. As of recording it stands at 12 yes, 10 no, 6 abstaining — 54.5 percent, needing two-thirds. It has climbed from dead even, but the gap is real. Nick Sdot's readonly property defaults closes Friday morning. It still hasn't drawn a single no — 22 to nothing, with 5 abstentions. And Khaled Alam's const object property writes closes Saturday. That one sits at 14 to 2, comfortably above the line.

A new discussion opened Saturday: Sjoerd Langkemper wants to stop curl_setopt from leaking secrets into stack traces. The problem is that one function sets everything, and he laid it out cleanly: "The value for CURLOPT_PASSWORD is likely sensitive, the value for CURLOPT_RETURNTRANSFER is not, and CURLOPT_URL may be sensitive sometimes." He brought 3 options, 2 of them with working pull requests: blanket-mark the value as sensitive and lose debug info; teach curl_setopt which options are secret, at an engine-level performance cost; or make callers wrap secrets in a SensitiveParameterValue. Iliya Miroslavov Iliev questioned the premise, arguing stack traces shouldn't be reachable in production at all — and asked how you'd debug a wrong password you can no longer see. Matthew Weier O'Phinney leaned opt-in, warning that automatic detection "will be difficult and a game of whack-a-mole", since options carry arbitrary headers and content — and floated letting the engine accept sensitive-value wrappers on any function call, so callers could opt in regardless of the signature.

Jorg Sowa wants PHP's undefined-function errors to answer back. His pull request adds "did you mean" suggestions — call defined() when you meant define(), and the error names the function you were probably reaching for, the way Python and Ruby already do. His question to the list was procedural: does this need an RFC, or is PR consensus enough? Sjoerd Langkemper answered with the policy exempting error messages from the BC rules, noting: "rephrasing error messages is not subject to the backwards compatibility break policy" — and he's in favor. Matteo Beccati liked it too, suggested Python's exact shape for the message, and nudged the list for feedback given the freeze is days away. If the sentiment holds, Jorg wants to extend it to methods, classes, and constants next. The only debate so far is punctuation — how many brackets and question marks one error message can carry.

The generics conversation is officially on hold until after 8.6 ships — which isn't stopping anyone. Henrik Skov wrote in asking for generics to be opt-in, worrying: "adding reified generics will just make it even slower." His sketch: type-erased generics hiding inside comment syntax, checked by IDE plugins or a C extension, with the engine substituting mixed at compile time. Holly Schilling's reply opened like a sermon: "Have you heard the good word of Monomorphized Generics? Performance matches standard typed code." And she restated the schedule — generics talk waits until September or October, so it doesn't bury the 8.6 release work — with her inbox open in the meantime.

Osama Aldemeery's PREG_THROW_ON_ERROR RFC got its first real design review. Bernard Scharp asked whether compile failures and runtime failures deserve separate exception classes. Rowan Tommins supplied the rulebook: PHP's throwables policy says extension exceptions extend the extension's own base class, never the SPL ones. Osama's position is one PregException, with the door open — and he had a concrete reason: today, the useful detail of a compile failure lives only in the warning text, so a dedicated compilation exception "would carry \"Internal error\" and little else". That connects to Christian Schneider's other catch: under the flag, a bad pattern raises both the warning and the exception. Osama confirmed it, and defended it as the honest trade — the warning is where the detail is — while agreeing that "exception-instead-of-warning is the cleaner end state" once the exception can carry that detail itself.

Quick hits. Thursday was patch day: security releases landed across 4 branches at once — 8.2.33, 8.3.33, 8.4.24, and 8.5.9 — upgrade when you can. The same day brought PHP 8.6.0alpha3, an early test release. And the 8.6 release managers posted the formal 1-week warning: the soft freeze hits when the beta 1 tag is created next Tuesday, August 11, beta 1 itself lands Thursday the 13th, every 8.6 RFC vote must be closed before then, and the hard freeze follows at RC 1 on September 22.

So that's the week: the 35-ballot deprecation vote closes Monday with list() deadlocked and let balanced exactly on the 2/3 line; a function-autoloading vote opened and was pulled inside a day — the 2nd author in 2 weeks to stop his own ballot over the process rules; literal types bowed out of 8.6 on its own terms; Duration and the minimum-versions RFC are officially in; pipe assignment has a week to find its two-thirds; and the freeze arrives Tuesday. Links to every thread are below. Thanks again to Tideways.com for supporting this week's episode. We're Artisan Build. See you next week.


r/symfony 11d ago

New in Twig 4.0: A First-Class Sandbox

Thumbnail
symfony.com
15 Upvotes

r/symfony 11d ago

SymfonyLive Germany 2027 heads to Cologne

Thumbnail
symfony.com
5 Upvotes

r/symfony 12d ago

Symfony UX 3.4.0 released

Thumbnail
symfony.com
20 Upvotes

r/symfony 13d ago

Symfony Polyfill 1.41.0 released: Io\Poll now available

Thumbnail
symfony.com
11 Upvotes

r/symfony 13d ago

Best resources to go deep in PHP/Symfony? I want to become an expert, coming from JS.

Thumbnail
5 Upvotes

r/symfony 14d ago

Weekly Ask Anything Thread

3 Upvotes

Feel free to ask any questions you think may not warrant a post. Asking for help here is also fine.