Re: [RFC] Pure-code source files via the .phpc extension
| From: | Morgan | Date: | Tue, 16 Jun 2026 12:51:44 +0000 |
| Subject: | Re: [RFC] Pure-code source files via the .phpc extension | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131320@lists.php.net to get a copy of this message | ||
On 2026-06-15 20:03, Hendrik Mennen wrote:
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 <https://wiki.php.net/rfc/ optional_php_tags>The single core motivation is:
Most new PHP files written today are pure code – framework classes, autoloaded library code, console commands, configuration files, route definitions. For these files the '<?php' opener carries no semantic information; it is a vestige of PHP's templating heritage that every file must repeat. PHP is the only modern mainstream language in which this prefix is mandatory.To which my response is "and that is a bad thing ... how?" On the subject of ceremonial boilerplate ... Maybe it's changed in the years since I had to work with it, but Perl modules had to end with "1;" because they were evaluated as they were imported, and the whole module had to return a truthy value to indicate that it had successfully loaded. (Of course, any truthy value would work and '1' was merely convention - TMTOWTDI.)
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: ownparagraph 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 thisproposal 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 morethoroughly 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 <https://news- web.php.net/php.internals/131024>