> Am 15.06.2026 um 12:16 schrieb Alex Rock <[email protected]>:
>
> Le 15/06/2026 à 10:03, Hendrik Mennen a écrit :
>> Hi internals,
>>
>> Following the pre-RFC discussion from late May [1], I'm moving the
>> "pure-code source files" proposal into formal RFC stage as
>>
>> https://wiki.php.net/rfc/optional_php_tags
>>
>> The mechanism is a single new opt-in file extension, .phpc, whose
>> semantics are: the file is parsed as pure PHP. The lexer enters
>> ST_IN_SCRIPTING on the first byte; no opening <?php is required.
>> A leading UTF-8 BOM and a CLI shebang are silently skipped. The
>> classic .php extension and every other code-loading path are
>> completely untouched - the change is strictly additive.
>>
>> Reference implementation: PR against php/php-src (link in the RFC).
>> Patch is ~50 lines of straight-line C in
>> Zend/zend_language_scanner.l::open_file_for_scanning, plus 15 new
>> .phpt tests in Zend/tests/phpc/. Full regression run against Zend/,
>> ext/tokenizer/, ext/standard/, ext/spl/, ext/reflection/, ext/phar/
>> (9836 tests): 0 failures, 0 modifications to any pre-existing test.
>>
>> Pre-RFC feedback, addressed in the RFC document:
>>
>> - Ben Ramsey on engine-vs-SAPI dispatch:
>> own section explaining why include/require/Phar all live below
>> SAPI and need engine-level handling. Ben's -p/stdin idea is
>> adopted as Future Scope (a sister RFC after this one).
>>
>> - Alex Rock on alternatives (env var, include_pure keyword,
>> declare(pure=1)): each rebutted individually under "Rejected
>> Alternatives".
>>
>> - Bruce Weirdan on BC of the .phpc extension itself: own
>> paragraph in the BC section, honest about the fact that I have
>> NOT scanned public corpora; asking voters with private-codebase
>> visibility for data points during Discussion.
>>
>> - .pyc visual collision and scattered prior .phpc usage:
>> addressed via a sub-vote on the extension name (.phpc / .phpp /
>> .pcode / .phpx).
>>
>> - Security (source-code exposure via misconfigured webservers,
>> the historic .inc footgun): own section with mandatory
>> documentation commitments and canonical Apache/Nginx/Caddy/
>> FrankenPHP snippets in Appendix A.
>>
>> - Boutell 2012 and Ohgaki 2014: own section distinguishing this
>> proposal mechanically from both.
>>
>> Discussion period: at least two weeks from today. Looking forward
>> to feedback, especially on:
>>
>> - The Open Issues block in the RFC (extension name, real-world
>> .phpc-in-use data, case-sensitivity on Windows/macOS).
>> - Anything in the Phar / OPcache surface I should test more
>> thoroughly before voting opens.
>> - Whether the Security section's commitments are strong enough.
>>
>> Thanks for reading,
>> Hendrik Mennen
>>
>> [1] https://news-web.php.net/php.internals/131024
>
> I still disagree with this proposal, though I have no power anywhere, because
> IMO it doesn't bring lots of benefits compared to the issues it creates.
>
>
>
> Side-note: the proposals I made about potential alternatives to include such
> files were only based on the "What if we still do this, but in another way?"
> motto. The bottom thought is that I disagree with the feature, but if it had
> to be done somehow, these suggestions are about how I would have done this,
> mostly to ensure better (IMO) BC and DX, nothing fancy or professional, just
> my random internet person's opinion :)
>
>
>
> About the motivations, here are my comments:
>
> > Reduced ceremony in pure-code files
>
> As you say: modern PHP code is already pure-PHP, and having to prepend
> "<?php" everywhere doesn't seem to be an issue for maintainers. I don't see
> why removing "<?php" would add any value.
>
> > First-class CLI scripts
>
> You can already use shebang lines on PHP scripts and PHAR files, because
> what's after the shebang line is sent to the environment-based script that is
> requested from said shebang line. It's basically doing "env php {script
> file}" , therefore is already compatible with any shebang-line-compatible
> shell. Having a "<?php" just means it's PHP code. Having pure-PHP code
> without the opening tag wouldn't change a thing.
>
> > Clearer file-mode intent
>
> It's not clearer, it's just moving the intent to the file extension rather
> than the file content itself. It's a really big DX change.
> If I wanted a pure-PHP file with another extension, I could do it today by
> adding "<?php" in the file and it would be interpreted as PHP code without
> issues.
> Here, the proposal is about allowing to shift a 30-plus-years-old working
> habit with PHP with something that is currently not intuitive neither
> expected. Adoption would definitely be complicated for lots of people, and if
> it's opt-in and doesn't bring lots of value, I'm not sure that many people
> would do it anyway.
>
> > Strictly additive
>
> Sure thing, but it's not allowing any kind of BC, since including ".phpc"
> files from older PHP versions would be possible, and would be rendered as
> text instead of being compiled... This has a big impact on the ecosystem.
> And by the way, about the ecosystem, here's my last comment on the
> motivations that definitely makes this proposal really hard to accept, at
> least for me: all existing ecosystem would have to adapt: Composer, IDEs, web
> servers, and so on. So it would be additive, indeed, but adoption would be
> extremely slow.
>
>
>
>
>
> To me, one of the issues you are partially trying to fix is the potential
> closing-tag-echo issue, having "?>" somewhere indicating that PHP will echo
> something during the process. This issue can be solved with "Definition
> files" (that I suggested in another internals thread as a first-step towards
> Modules), but even having "?>" from inside a function is no issue: it just
> exposes a clear intent of "echo-ing something", and isn't really different
> than "echo <<<HTML " followed by a bunch of HTML for instance. IDEs may
> behave a bit differently with syntax highlighting, but modern IDEs are
> capable of injecting languages properly depending on lots of contextual
> metadata (and the "<<<HTML" heredoc syntax isn't random: IDEs can know that
> code inside this context is HTML). Your proposal would enforce using "echo"
> manually, while the "?>" syntax defines the same thing.
> This system would also be useless for template systems based on PHP files,
> which are used in many legacy PHP projects for, well, legacy reasons ; I
> could tell you about many such projects I've been working on in the past 5
> years only, and I'm one single person, so extrapolate this to worldwide devs,
> and you get more people that wouldn't care at all about pure-php files
> because it's useless to their stack.
>
>
>
>
>
Hi Alex,
Thanks for the detailed reply, and for the explicit "I still
disagree" - useful signal, and in the (1/2/3) framing from the
Kamil sub-thread you are at (3), which is exactly the kind of
direct answer I asked for. Even without voting power your
arguments will be read by voters, so engaging substantively.
The genuinely new concern in your reply that the RFC does not
yet address head-on is forward-compatibility. Taking that first.
> Strictly additive
> Sure thing, but it's not allowing any kind of BC, since
> including ".phpc" files from older PHP versions would be
> possible, and would be rendered as text instead of being
> compiled...
You are correct. On PHP < target-version, a .phpc file pulled
in via require/include would be parsed by the existing lexer
in INITIAL state and emitted as inline content. This is the
standard 8.x adoption story in shape (a readonly class on 8.1
is a syntax error; a .phpc file on 8.5 is text emission), but
"text emission" is a worse failure mode than "syntax error"
because it can silently expose source code in a web context.
The realistic mitigation, which the RFC should make explicit
(and will, in the next revision):
- A library shipping .phpc files declares the target version
in composer.json:
"require": { "php": ">=8.6" }
- composer install fails at install time with a clear
PHP-version error on lower versions. The .phpc file never
reaches a running interpreter that doesn't understand it.
- Library authors who want to support older PHP versions
don't ship .phpc files. Same constraint as readonly
classes, property hooks, enums, etc.
- For non-Composer distribution (manual clone, raw .zip),
the user is on their own - same as for any 8.x feature.
For application code (where the deployed PHP version is known)
the FC constraint is moot. For shared libraries it is real and
worth flagging in the RFC. I will add a Forward Compatibility
subsection covering this.
> Reduced ceremony / First-class CLI scripts / Clearer file-mode
> intent
These largely overlap with Kamil's earlier points; I'd rather
not re-litigate the same arguments inline. The Motivation
section is being rewritten this week to drop the four-bullet
framing entirely in favour of one honest sentence ("modern PHP
is overwhelmingly pure-code; <?php is a vestige for those files;
.phpc is the smallest mechanism to remove it opt-in") plus a
"what this RFC does NOT claim" subsection. If after that you
still see no value, that is a fair (3).
> Closing-tag-echo issue, having "?>" somewhere...
To clarify: this RFC does NOT try to solve that. ?> behaviour
inside a .phpc file is byte-for-byte identical to .php - drop-
out to inline mode is preserved, __halt_compiler() works, <?=
has no special meaning. The "What is unchanged" subsection of
the RFC says this; I will make it more prominent.
> All existing ecosystem would have to adapt: Composer, IDEs,
> web servers...
Concede partially. Adoption work is non-zero. The RFC's
position:
- Composer: PSR-4 autoloader already accepts a per-rule
extension list; adding .phpc is documentation + a small
Composer-side acknowledgement. RFC commits to opening
that PR pre-landing.
- IDEs / static analysers: configure file modes by extension
via their per-project config; one-line change per tool.
RFC commits to opening tracking issues on day of vote
acceptance.
- Web servers: explicit handler mapping or deny. Appendix A
of the RFC ships canonical snippets for Apache, Nginx,
Caddy, FrankenPHP.
You are right that adoption would be slow. I do not think
that disqualifies an additive opt-in feature, but I respect
that you do.
> Templating system based on PHP files [...] many such projects
Agreed, and .phpc proposes to harm none of them. It is opt-in
by filename. Template engines (compiled .php cache files
prefixed with <?php) are untouched; hand-written .phtml
templates are untouched; a legacy codebase that never adopts
.phpc loses nothing.
> Definition files (that I suggested in another internals
> thread) [...] but even having "?>" from inside a function is
> no issue
I have not read your Definition files thread yet; pointer
welcome. If that concept subsumes .phpc as a special case of
something broader, I would rather refine the bigger idea than
ship a smaller one that conflicts with it. Genuinely
interested.
Thanks,
Hendrik