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: 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 <https://news- web.php.net/php.internals/131024>

Reply via email to