[RFC] use-from syntax for namespace use declarations

php.internals

Stuardo -StR- Rodríguez

238 days ago
Hello internals, I am writing to open the discussion for the RFC "use-from syntax for namespace use declarations": https://wiki.php.net/rfc/use-from This proposal introduces an alternative syntax for namespace imports: ```php use Name from Prefix; use {A, B} from Prefix; ``` This form is purely syntactic sugar for the traditional `use Prefix\Name;` syntax. The primary motivation is to improve readability and ergonomic sorting of imports by placing the imported symbol name first (e.g. `use User from App\Models`), similar to import styles in other languages like Python or JavaScript. The implementation introduces `from` as a contextual keyword in `use` declarations, ensuring backward compatibility for existing uses of `from` as method names or identifiers. You can find the proof-of-concept implementation here: https://github.com/php/php-src/pull/20844 I look forward to your thoughts and feedback. Best regards, Stuardo Rodríguez str@maphpia.com
-- Stuardo Rodríguez Mercenary Web Developer La Maphpia 🌎 maphpia.com ✉ str@maphpia.com 📞 +502 3462-7169

Rowan Tommins [IMSoP]

236 days ago
On 06/01/2026 02:14, Stuardo -StR- Rodríguez wrote:
> Hello internals, > > I am writing to open the discussion for the RFC "use-from syntax for > namespace use declarations": > https://wiki.php.net/rfc/use-from
Hi, and welcome! As you say in the RFC, a new syntax like this "requires a clear and strong justification". Looking at the reasons given, I'm not convinced they pass that test. Let's look at them in order: RATIONALE 1: "makes it easier to scan and (optionally) sort import lists by imported symbol" At first glance, this seems like a reasonable idea, but there are two aspects of PHP's existing syntax which work against it. The first problem is the braced-list form for aliasing multiple symbols from one namespace. Taking the example from your RFC, grouping gives this: ``` use Carbon from Illuminate\Support; use Inertia from Inertia; use {SettingService,TaskService} from App\Services; use {Status,Task,User} from App\Models; use {TaskCreated,TaskUpdated} from App\Events; use TaskRepository from App\Repositories; use TaskUpdateData from App\DTOs; use ZipArchive; ``` This is much more concise, but sorting no longer helps find a symbol (e.g. you have to read each entry to find "User"). Sorting by the first item in a group, as shown, is also unstable: importing "App\Models\Agent" would require moving the fourth line to the top of the list. The second problem is custom aliases, which you propose not one but two new styles for, neither of which allow you to sort or scan by the symbol as used in the file. The first variant actively harms scanning, putting the symbol we're looking for in the *middle* of the statement: use TaskRepository as Repository from App\Repositories; The second variant splits the real name and the alias to opposite ends of the line. The reader has to check both to see which symbol is actually being defined: use TaskRepository from App\Repositoriesas Repository; The existing syntax places the symbol being defined consistently at the end, next to the real name it is aliasing: use App\Repositories\TaskRepositoryas Repository; RATIONALE 2(a): "reducing cognitive friction for developers who regularly move between languages that already use a similar form" This seems to fall down almost immediately, because you quote Python as an example, but it's not in the proposed order! In fact, JavaScript seems to be a rare outlier in placing the imported symbol first: JavaScript: import { Widget } from "acme-lib"; Python: from acmeLib import Widget Java: import AcmeLib.Widget; C#: using AcmeLib.Widget; Swift: import class AcmeLib.Widget Kotlin: import AcmeLib.Widget Scala: import AcmeLib.Widget PHP: use AcmeLib\Widget; RATIONALE 2(b): "makes the import semantics immediately recognizable to a wider audience" As Ben Ramsey pointed out, the opposite is true: the semantics of "use" are *not* the same as JavaScript's "import", so making them look similar sets up false expectations. PHP's "use" statement does not load any code, and doesn't even need to refer to a real class; it is purely a compile-time rewrite rule, more similar to C's #define pre-processor macro. Worse, JavaScript actually has two *different* import syntaxes which resemble the proposal: import { Widget } from "acme-lib" import Widget from "acme-lib" The first is the one which superficially resembles a PHP "use" statement, while the second is actually a short-hand for this, which has no equivalent in PHP at all: import { default as Widget } from "acme-lib" RATIONALE 3: "projects that prefer namespace-first ordering can continue to do so" Superficially, this is true; but having more than one way to write something has a non-zero cost. First, every tool processing the language's syntax has to support the new syntax, even if only to enforce a coding standard that it should not be used. Second, users will not immediately know that the different syntaxes mean the same thing. For instance, users frequently ask the difference between "exit" and "die": https://stackoverflow.com/questions/1795025/what-are-the-differences-in-die-and-exit-in-php This is even more likely given the previous two points: the new syntax will look like JS, where the various different "import" syntaxes *do* mean different things. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import All things considered, if this is ever taken to a vote, I will vote No.
-- Rowan Tommins [IMSoP]