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
Hi internals,
Following the pre-RFC discussion from late May [1], I'm moving the
"pure-code source files" proposal into formal RFC stage ashttps://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
Hi,
It seems something broke with the formatting in the "What is unchanged"
section.
Am 15.06.2026 um 10:11 schrieb Lynn kjarli@gmail.com:
Hi internals,
Following the pre-RFC discussion from late May [1], I'm moving the
"pure-code source files" proposal into formal RFC stage ashttps://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 MennenHi,
It seems something broke with the formatting in the "What is unchanged" section.
Hi,
Yeah saw and already fixed it :-) Thanks
Hi Hendrik,
Il 15/06/2026 10:03, Hendrik Mennen ha scritto:
Following the pre-RFC discussion from late May [1], I'm moving the
"pure-code source files" proposal into formal RFC stage ashttps://wiki.php.net/rfc/optional_php_tags <https://wiki.php.net/rfc/
optional_php_tags>
FYI, it seems there's some formatting issue caused by __halt_compiler().
I appreciate the effort, but I'm afraid I think it's unnecessary
complication for practically no real-world benefit.
Cheers
Matteo Beccati
Hi internals,
Following the pre-RFC discussion from late May [1], I'm moving the
"pure-code source files" proposal into formal RFC stage ashttps://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
I tried to catch up on this discussion last night. I see a lot of things
that could go wrong with this, but I don't see a clear motivation for why
would we want this change.
Reduced ceremony in pure-code files.
This is a moot point because after the change you still have the ceremony
of adding .phpc to every file. Just unnecessary churn.
First-class CLI scripts.
Is this really a big concern? Is it going to work better? Are there things
you cannot do today because of it?
Clearer file-mode intent.
We already have that. By convention many people add .php extension to pure
PHP files, and .phtml to templates. It's not mandated by a language and
people are free to choose their naming conventions.
Strictly additive.
That's not entirely true, but that's beside the point. Why is this one of
the main motivations? We don't add things just because we can. They need to
have a purpose.
We already have a good way of writing pure PHP code files. Just add 5
characters at the beginning of the file <?php and the rest of the file will
be treated as PHP source code.
I would also like to echo what others said that PHP source code doesn't
have to be within <?php. A text file will be compiled and interpreted by
PHP as a print statement. Even in pure PHP code files you may want to
escape the PHP context with ?>. Mandating that a file with a certain
extension will have these restrictions is worse than having to start every
file with <?PHP.
Regards,
Kamil