# [RFC] Four Pragmatic Directions for PHP: Simplicity, Arrays, Performance, Concurrency

- Thread: https://externals.io/message/130424
- Original archive: https://news-web.php.net/php.internals/130424
- Started by 631256435@qq.com on 2026-03-24T10:08:41+00:00
- Messages: 12
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #130424 — 631256435@qq.com — 2026-03-24T10:08:41+00:00

URL: https://externals.io/message/130424#130424

Hi internals,


I'm a developer who uses both Java and PHP regularly. I'm writing
because I care about PHP's future.


PHP's strength has always been simplicity and pragmatism. But since
PHP 7 and especially PHP 8, we've been adding "enterprise features"
(typed properties, attributes, property hooks) that make PHP more like
Java – without achieving Java's type safety or ecosystem.


I believe PHP should refocus on what made it great. Here are four
pragmatic directions:


---


1. Stop Chasing Java


Every "enterprise feature" pushes developers like me toward Java. Not
because Java is better, but because if I need enterprise complexity
anyway, I'd rather use a language designed for it.


PHP cannot beat Java at its own game. But it can beat Java where it
matters: rapid prototyping, simple deployment, web-native development,
low learning curve.


Please keep PHP simple. Keep it pragmatic.


---


2. Add Practical Array Helpers


PHP is a web language – 90% of what we do is manipulate arrays. Yet
basic operations are still verbose:


```php
// Current
$names = array_values(array_filter($users, fn($u) =&gt; $u-&gt;active));
$first = count($names) &gt; 0 ? $names[0] : null;


// Proposed
$names = array_pluck($users, 'name');
$names = array_where($users, fn($u) =&gt; $u-&gt;active);
$first = array_first($users);
$grouped = array_group_by($users, 'role');
$compact = array_compact($data);

These helpers would make everyday code cleaner without adding
complexity.




Improve Performance


Performance has always been a strength. Keep optimizing:


JIT for real-world web workloads



Reduce memory allocation in array operations



Make OpCache smarter



Provide Built-in Concurrency (Without Complexity)


Concurrency is the biggest missing piece. But instead of complex
async/await or coroutines, consider a simple worker management API:
php



$server = new WorkerServer(); $server-&gt;onWorkerStart(fn() =&gt; loadApp()); $server-&gt;onRequest(fn($req) =&gt; handle($req)); $server-&gt;start(4);


This would:


Run standalone: php server.php&nbsp;– no nginx, no PHP-FPM



Keep process isolation (each worker is separate)



Allow resource initialization once per worker



Give developers control without new concepts


Why not just use FrankenPHP? FrankenPHP is excellent, but requires an
additional binary and new deployment workflow. Many developers just
want a simple, built-in way to run their app without configuring two
services.


Why This Matters

PHP's competitors are winning on concurrency (Node.js, Go) and syntax
(Python). PHP's advantages – simplicity, web-native deployment, low
learning curve – are being eroded.

I don't want to leave PHP. I want PHP to stay great. I want to keep
choosing PHP for years to come.

Thank you for your time and for maintaining PHP. I'm happy to provide
more examples or participate in discussions.

Best regards,
[qinhao]

---

## #130425 — Aleksander Machniak — 2026-03-24T10:31:13+00:00

URL: https://externals.io/message/130424#130425 · In reply to: #130424

> // Current
> $names = array_values(array_filter($users, fn($u) => $u->active));
> $first = count($names) > 0 ? $names[0] : null;

Not the best example, as you can also do:

$first = array_find($users, fn ($user) => $user->active)?->name;

There are some existing functions like `array_column()` and `array_first()` 
that seems you didn't know existed. So, there's been some progress in 
this territory too.

-- 
Aleksander Machniak
Kolab Groupware Developer        [https://kolab.org]
Roundcube Webmail Developer  [https://roundcube.net]
----------------------------------------------------
PGP: 19359DC1 # Blog: https://kolabian.wordpress.com

---

## #130427 — Dan Liebner — 2026-03-24T11:04:31+00:00

URL: https://externals.io/message/130424#130427 · In reply to: #130425

I agree with this sentiment.

My main gripe with PHP 8 is that undefined array key accesses trigger a
warning. There is no solution to this that doesn't require destroying the
readability of a legacy codebase or using some hacky global error handler.

I think the direction should always have been this: undefined array key
accesses should simply return null by default.

To ensure data integrity in critical paths, a new language construct could
be used: strict_access($arr['key']). This construct `strict_access`
(similar to isset which is not a "real" function) would tell the compiler
to emit a specialized opcode that triggers a warning if the key is missing.
Maybe a shorthand like `$arr['key']!` could be used. This would give
developers the best of both worlds: clean, 'script-style' code by default,
and explicit, high-performance validation only where it's actually
requested.

- Dan



> 
> > […]
>
> Not the best example, as you can also do:
>
> $first = array_find($users, fn ($user) => $user->active)?->name;
>
> There are some existing functions like `array_column()` and `array_first()`
> that seems you didn't know existed. So, there's been some progress in
> this territory too.
>
> --
> Aleksander Machniak
> Kolab Groupware Developer        [https://kolab.org]
> Roundcube Webmail Developer  [https://roundcube.net]
> ----------------------------------------------------
> PGP: 19359DC1 # Blog: https://kolabian.wordpress.com

---

## #130428 — Morgan — 2026-03-24T11:38:25+00:00

URL: https://externals.io/message/130424#130428 · In reply to: #130424

> 
> // Proposed
> $names = array_pluck($users, 'name');
> $names = array_where($users, fn($u) => $u->active);
> $first = array_first($users);
> $grouped = array_group_by($users, 'role');
> $compact = array_compact($data);
> 

Of those, array_compact() is obscure in its purpose, and of the others 
one exists under the suggested name and three of the others exist under 
different names.

array_group_by() is the only one that isn't already implemented. I think 
it means:

$roles = array_unique(array_column($users, 'role'));
$grouped = array_combine($roles, array_map(fn($r) => 
array_filter($users, fn($u) => $u['role']==$r), $roles));

though there are more efficient (and readable) ways of doing that.

--

Optimising the implementation would be more difficult if the language 
were allowed to be sloppier. Conversely, tightening up the language 
allows improved optimisation.

---

## #130436 — Larry Garfield — 2026-03-24T19:02:23+00:00

URL: https://externals.io/message/130424#130436 · In reply to: #130424

> Hi internals,
>
>
> I'm a developer who uses both Java and PHP regularly. I'm writing
> because I care about PHP's future.
>
> PHP's strength has always been simplicity and pragmatism. But since
> PHP 7 and especially PHP 8, we've been adding "enterprise features"
> (typed properties, attributes, property hooks) that make PHP more like
> Java – without achieving Java's type safety or ecosystem.
>
> I believe PHP should refocus on what made it great. Here are four
> pragmatic directions:
>
> ---
>
> 1. Stop Chasing Java
>
> Every "enterprise feature" pushes developers like me toward Java. Not
> because Java is better, but because if I need enterprise complexity
> anyway, I'd rather use a language designed for it.
>
> PHP cannot beat Java at its own game. But it can beat Java where it
> matters: rapid prototyping, simple deployment, web-native development,
> low learning curve.
>
> Please keep PHP simple. Keep it pragmatic.

This accusation has been thrown at PHP every few months since PHP 5.0 came out (which did indeed ape Java 2 for much of its OOP syntax and behavior).  It's really a farcical misunderstanding of language design, "enterprise features," and "pragmatism."

Many of the features added in the 8.0+ era are simple syntactic sugar to reduce typing.  Is that "enterprise?"  Typed properties greatly reduce the amount of error handling needed, and the amount of tests needed.  Is that "enterprise?"  Property hooks vastly reduce the need for boilerplate code, making it faster and easier to bang out code that is forward-compatible.  Is that "enterprise?"

The programming language community at large keeps learning, and has learned a ton since the 90s.  One thing it has learned, but many developers have not, is that "code that finds errors for you at compile time" is NOT an enterprise feature.  It's an everybody feature, which is why virtually every untyped language has had some form of types added to it, in various ways.  (PHP directly, Python via unenforced annotations, Javascript via TypeScript, etc.)

> 2. Add Practical Array Helpers
>
> PHP is a web language – 90% of what we do is manipulate arrays. Yet
> basic operations are still verbose:
>
> ```php
> // Current
> $names = array_values(array_filter($users, fn($u) => $u->active));
> $first = count($names) > 0 ? $names[0] : null;
>
> // Proposed
> $names = array_pluck($users, 'name');
> $names = array_where($users, fn($u) => $u->active);
> $first = array_first($users);
> $grouped = array_group_by($users, 'role');
> $compact = array_compact($data);
>
> These helpers would make everyday code cleaner without adding
> complexity.

You may have noticed that a number of array and string helper functions have been added in recent years.  If there are more that you feel should be, RFCs are welcome.  Just adding an array function is probably one of the simplest technical RFCs to write.

>  1. Improve Performance
>
> Performance has always been a strength. Keep optimizing:
>
>  • JIT for real-world web workloads
>
>  • Reduce memory allocation in array operations
>
>  • Make OpCache smarter

All of these are happening, to the extent possible.

>  1. Provide Built-in Concurrency (Without Complexity)
>
> Concurrency is the biggest missing piece. But instead of complex
> async/await or coroutines, consider a simple worker management API:
>
> php
> $server = new WorkerServer();
> $server->onWorkerStart(fn() => loadApp());
> $server->onRequest(fn($req) => handle($req));
> $server->start(4);
> This would:
>
>  • Run standalone: `php server.php` – no nginx, no PHP-FPM
>
>  • Keep process isolation (each worker is separate)
>
>  • Allow resource initialization once per worker
>
>  • Give developers control without new concepts
>
> Why not just use FrankenPHP? FrankenPHP is excellent, but requires an
> additional binary and new deployment workflow. Many developers just
> want a simple, built-in way to run their app without configuring two
> services.

You may not have noticed, if you're new to the list, but there has been an extensive and ongoing discussion of improved async support, with a lot of focus on how to make it easy to use right and hard to use wrong.  Because that is actually a really, really hard problem space.  "Simple worker management" is not actually simple, when you dig into it.  There's a lot of things that can go wrong, and designing it (both the code and the APi) such that it's hard to have things go wrong is itself really hard.  That's why it's going on over a year now.

Rest assured, there's an awful lot of people that really want good async/workers/etc.  But it's nowhere near as easy as you think, or it would be done already.  (See also: generics.)

--Larry Garfield

---

## #130458 — Rob Landers — 2026-03-26T07:51:31+00:00

URL: https://externals.io/message/130424#130458 · In reply to: #130427

I used to have a really long and interesting blog post on PHP arrays about this:


> I agree with this sentiment.
> 
> My main gripe with PHP 8 is that undefined array key accesses trigger a warning. There is no solution to this that doesn't require destroying the readability of a legacy codebase or using some hacky global error handler.
> 
> I think the direction should always have been this: undefined array key accesses should simply return null by default.

And then my disk caught on fire and it was never archived. TL;DR: treating PHP arrays as an infinite field of nulls has some very interesting mathematical properties. No other language on earth gave you this.

Practical usecases were ways to effectively "cheat" on some np-hard and np-complete problems, like subset-sum, knapsack, Hamiltonian Path, etc. This warning (and eventual removal of this property) makes these "cheats" no longer possible in PHP and constrained just like every other language on the planet.

— Rob

---

## #130459 — Rowan Tommins [IMSoP] — 2026-03-26T14:58:18+00:00

URL: https://externals.io/message/130424#130459 · In reply to: #130458

>And then my disk caught on fire and it was never archived. TL;DR: treating PHP arrays as an infinite field of nulls has some very interesting mathematical properties. No other language on earth gave you this.

I agree that some useful use cases have been "thrown out with the bathwater" by trying to make array access less prone to mistakes. 

I think the pragmatic response to that is to propose new features that cater *even better* to those use cases. For instance: 

- an "optional key access" operator like $foo[?'bar'] that makes the intent explicit but concise
- a PHP version of Python's "defaultdict", which lets you *choose* the default value for undefined items, rather than always null 
- copy-on-write structs with predefined keys


At the same time, PHP has always been a long way behind other languages when it comes to lazy lists and iterators; I would love to see:

- a "sparse list" type, where you can define the size and initial value without allocating memory for all elements
- lazy ranges
- built-in functions or operators which can operate lazily on iterators (i.e. without enumerating them)


These aren't trivial to design and implement, but it would be great to transfer some of the energy from "I don't like this thing someone else wanted" into "I want this thing as well".


Regards,

Rowan Tommins
[IMSoP]

---

## #130464 — Morgan — 2026-03-27T03:37:05+00:00

URL: https://externals.io/message/130424#130464 · In reply to: #130459

> 
> 
> - an "optional key access" operator like $foo[?'bar'] that makes the intent explicit but concise

So, syntactic sugar for "($foo['bar'] ?? null)".

---

## #130465 — Dan Liebner — 2026-03-27T05:26:39+00:00

URL: https://externals.io/message/130424#130465 · In reply to: #130464

>
> 
> > […]
> intent explicit but concise
>
> So, syntactic sugar for "($foo['bar'] ?? null)".


That, to me, would be a massive improvement in terms of code readability.



> 
> > […]
> intent explicit but concise
>
> So, syntactic sugar for "($foo['bar'] ?? null)".

---

## #130468 — Alex Rock — 2026-03-27T15:19:23+00:00

URL: https://externals.io/message/130424#130468 · In reply to: #130465

In that case, maybe reuse something similar to the null-safe operator ?

Something like `$foo['bar']?`

With the ability to have some freedom in placing the `?` character.

This way, you have both syntactic sugar:

     return $foo['one']?;
     // is roughly equivalent to:
     return $foo['one'] ?? null;


     return $foo['one']?['two'];
     // is roughly equivalent to:
     return $foo['one']['two'] ?? null;


And here it gets interesting:

     return $foo['one']['two']?['three'];
     // is roughly equivalent to:
     if (!isset($foo['bar']) {
     trigger_error('Undefined key "one" in ...', ...);
     }
     return $foo['one']['two']['three'] ?? null;


This brings a "new" way to deal with nested array keys (like explained 
in the first code samples).

I don't know about the parser yet, but technically, in language 
semantics, it is a unary-right, contrary to the "?" operator which is 
binary left&right and must be used alongside the ":" operator.

Would need an implementation and some tests to ensure the reliability.



Le 27/03/2026 à 06:26, Dan Liebner a écrit :
>
>     
> > […]
>     wrote:
> > […]
>     the intent explicit but concise
>
>     So, syntactic sugar for "($foo['bar'] ?? null)". 
>
>
> That, to me, would be a massive improvement in terms of code readability.
>
> 
>
>     
> > […]
>     wrote:
> > […]
>     the intent explicit but concise
>
>     So, syntactic sugar for "($foo['bar'] ?? null)".

---

## #130476 — Rowan Tommins [IMSoP] — 2026-03-28T18:31:06+00:00

URL: https://externals.io/message/130424#130476 · In reply to: #130468

>
> In that case, maybe reuse something similar to the null-safe operator ?
>
> Something like `$foo['bar']?`
>

I think even if you could make it work in the parser, it would be hard 
to make that read well with the ternary operator:

$foo['a'] ? ['b'] ? ['c'] : ['d'];


>     return $foo['one']?['two'];

Looking at that, it's not obvious to me whether it's 'one' or 'two' 
which is optional.

return $foo['one']  ?['two'];
return $foo['one']?  ['two'];


> And here it gets interesting:
>
>     return $foo['one']['two']?['three'];
>     // is roughly equivalent to:
>     if (!isset($foo['one']) {
>     trigger_error('Undefined key "one" in ...', ...);
>     }
>     return $foo['one']['two']['three'] ?? null;
>

You can have the same ability with a ? inside the brackets, and without 
the ambiguity:

// all three keys required to exist (as of PHP 9):
return $foo['one']['two']['three'];

// 'one' and 'two' required, 'three' optional:
return $foo['one']['two'][?'three'];

// both 'two' and 'three' optional:
return $foo['one'][?'two'][?'three'];

// optional all the way:
return $foo[?'one'][?'two'][?'three'];


This would maybe have similar short-cut semantics to ?->

$foo = [];
return $foo[?'one']['two'];
// OK: the ? neutralises access to the missing section of the array, 
short-cutting to `NULL` 
// Similar to $foo?->bar->baz when $foo is `NULL` 

$foo = ['one' => []];
return $foo[?'one']['two'];
// Error: the ? had no effect, so we're trying to access non-existent 
key 'two' in the empty array $foo['one']
// Similar to $foo?->bar->baz when $foo->bar exists


But an RFC could pin down those details.


-- 
Rowan Tommins
[IMSoP]

---

## #130477 — Dan Liebner — 2026-03-28T19:27:44+00:00

URL: https://externals.io/message/130424#130477 · In reply to: #130476

Yeah, adding `?` after expressions gets weird because of ternary operators.

I do think the long-form `$foo[?'one'][?'two'][?'three']` is acceptable in
terms of developer experience considering it's not a super common scenario.
I'm not sure if that would be annoying to implement on the C side of things.

- Dan

On Sat, Mar 28, 2026 at 2:33 PM Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk>
wrote:

> 
> > […]
>
> I think even if you could make it work in the parser, it would be hard
> to make that read well with the ternary operator:
>
> $foo['a'] ? ['b'] ? ['c'] : ['d'];
>
>
> > […]
>
> Looking at that, it's not obvious to me whether it's 'one' or 'two'
> which is optional.
>
> return $foo['one']  ?['two'];
> return $foo['one']?  ['two'];
>
>
> > […]
>
> You can have the same ability with a ? inside the brackets, and without
> the ambiguity:
>
> // all three keys required to exist (as of PHP 9):
> return $foo['one']['two']['three'];
>
> // 'one' and 'two' required, 'three' optional:
> return $foo['one']['two'][?'three'];
>
> // both 'two' and 'three' optional:
> return $foo['one'][?'two'][?'three'];
>
> // optional all the way:
> return $foo[?'one'][?'two'][?'three'];
>
>
> This would maybe have similar short-cut semantics to ?->
>
> $foo = [];
> return $foo[?'one']['two'];
> // OK: the ? neutralises access to the missing section of the array,
> short-cutting to `NULL` 
> // Similar to $foo?->bar->baz when $foo is `NULL` 
>
> $foo = ['one' => []];
> return $foo[?'one']['two'];
> // Error: the ? had no effect, so we're trying to access non-existent
> key 'two' in the empty array $foo['one']
> // Similar to $foo?->bar->baz when $foo->bar exists
>
>
> But an RFC could pin down those details.
>
>
> --
> Rowan Tommins
> [IMSoP]
