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
Am 15.06.2026 um 10:43 schrieb Kamil Tekiela tekiela246@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 MennenI 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
Hi Kamil,
Thanks for the substantive pushback - these are exactly the right
questions, and you're correct on more of them than the RFC as currently
worded admits.
Conceding upfront: "strictly additive" is a necessary property, not a
motivation. I leaned on it too much. Same for the three weaker arguments
(CLI ergonomics, convention clarity, ceremony shift) - none of them
alone justifies the mechanism.
The honest single-sentence motivation:
Most new PHP files written today are pure code (framework classes,
autoloaders, console commands, configuration). For those files the
<?php opener carries zero semantic information. PHP is the only
modern mainstream language where it is mandatory.
If that friction is not worth solving, that is a legitimate position
and I would rather hear that than dress the proposal up to look
weightier than it is. Three honest paths from here, and I would find
it useful if respondents could say which they are closest to:
- The friction is real and a small targeted addition is worth
shipping. (what the RFC proposes) - The friction is real but the mechanism is wrong. (in which case:
what signal would you prefer? per-file declare, magic first line,
SAPI-only, ...) - The friction is not real, or not worth a language change at all.
That is a sharper question than re-litigating each motivation in turn,
and the answer determines whether to refine, pivot, or withdraw before
voting.
On your last point - that .phpc "restricts" PHP's text-as-print
feature - I think we agree more than disagree. .phpc would not change
.php behaviour at all. It is opt-in by filename. Authors who want the
templating shape keep using .php, ?> drop-out continues to work inside
.phpc, and the engine on existing files is byte-for-byte identical.
The "restriction" you describe (no top-of-file inline content;
<?php-as-tag rejected inside .phpc) is intentional - it is what makes
the mode meaningful for the cases that opt in.
I will update the RFC's Motivation section to reflect this
clarification in the next day or two so the rest of the Discussion
runs on the stronger framing rather than the weaker one I shipped
with.
Thanks again,
Hendrik
Am 15.06.2026 um 10:43 schrieb Kamil Tekiela tekiela246@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 MennenI 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,
KamilHi Kamil,
Thanks for the substantive pushback - these are exactly the right
questions, and you're correct on more of them than the RFC as currently
worded admits.Conceding upfront: "strictly additive" is a necessary property, not a
motivation. I leaned on it too much. Same for the three weaker arguments
(CLI ergonomics, convention clarity, ceremony shift) - none of them
alone justifies the mechanism.The honest single-sentence motivation:
Most new PHP files written today are pure code (framework classes,
autoloaders, console commands, configuration). For those files the
<?php opener carries zero semantic information. PHP is the only
modern mainstream language where it is mandatory.If that friction is not worth solving, that is a legitimate position
and I would rather hear that than dress the proposal up to look
weightier than it is. Three honest paths from here, and I would find
it useful if respondents could say which they are closest to:
- The friction is real and a small targeted addition is worth
shipping. (what the RFC proposes)- The friction is real but the mechanism is wrong. (in which case:
what signal would you prefer? per-file declare, magic first line,
SAPI-only, ...)- The friction is not real, or not worth a language change at all.
That is a sharper question than re-litigating each motivation in turn,
and the answer determines whether to refine, pivot, or withdraw before
voting.On your last point - that .phpc "restricts" PHP's text-as-print
feature - I think we agree more than disagree. .phpc would not change
.php behaviour at all. It is opt-in by filename. Authors who want the
templating shape keep using .php, ?> drop-out continues to work inside
.phpc, and the engine on existing files is byte-for-byte identical.
The "restriction" you describe (no top-of-file inline content;
<?php-as-tag rejected inside .phpc) is intentional - it is what makes
the mode meaningful for the cases that opt in.I will update the RFC's Motivation section to reflect this
clarification in the next day or two so the rest of the Discussion
runs on the stronger framing rather than the weaker one I shipped
with.Thanks again,
Hendrik
I don't get a vote, but mark me as opposed. If we ever do this, it needs to
accompany something akin to JavaScript's strict mode which shards off
several long standing warts that can't otherwise be gotten rid of because
of BC. If we ever do a strict mode we'd better get it right and do it only
once.
As it stands, there just isn't anything here other than lifting the need to
type 5 characters at the start of every file. Worse, it could be closing a
door we'll never see again.
Am 16.06.2026 um 06:52 schrieb Michael Morris tendoaki@gmail.com:
Am 15.06.2026 um 10:43 schrieb Kamil Tekiela <tekiela246@gmail.com mailto:tekiela246@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 MennenI 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,
KamilHi Kamil,
Thanks for the substantive pushback - these are exactly the right
questions, and you're correct on more of them than the RFC as currently
worded admits.Conceding upfront: "strictly additive" is a necessary property, not a
motivation. I leaned on it too much. Same for the three weaker arguments
(CLI ergonomics, convention clarity, ceremony shift) - none of them
alone justifies the mechanism.The honest single-sentence motivation:
Most new PHP files written today are pure code (framework classes,
autoloaders, console commands, configuration). For those files the
<?php opener carries zero semantic information. PHP is the only
modern mainstream language where it is mandatory.If that friction is not worth solving, that is a legitimate position
and I would rather hear that than dress the proposal up to look
weightier than it is. Three honest paths from here, and I would find
it useful if respondents could say which they are closest to:
- The friction is real and a small targeted addition is worth
shipping. (what the RFC proposes)- The friction is real but the mechanism is wrong. (in which case:
what signal would you prefer? per-file declare, magic first line,
SAPI-only, ...)- The friction is not real, or not worth a language change at all.
That is a sharper question than re-litigating each motivation in turn,
and the answer determines whether to refine, pivot, or withdraw before
voting.On your last point - that .phpc "restricts" PHP's text-as-print
feature - I think we agree more than disagree. .phpc would not change
.php behaviour at all. It is opt-in by filename. Authors who want the
templating shape keep using .php, ?> drop-out continues to work inside
.phpc, and the engine on existing files is byte-for-byte identical.
The "restriction" you describe (no top-of-file inline content;
<?php-as-tag rejected inside .phpc) is intentional - it is what makes
the mode meaningful for the cases that opt in.I will update the RFC's Motivation section to reflect this
clarification in the next day or two so the rest of the Discussion
runs on the stronger framing rather than the weaker one I shipped
with.Thanks again,
HendrikI don't get a vote, but mark me as opposed. If we ever do this, it needs to accompany something akin to JavaScript's strict mode which shards off several long standing warts that can't otherwise be gotten rid of because of BC. If we ever do a strict mode we'd better get it right and do it only once.
As it stands, there just isn't anything here other than lifting the need to type 5 characters at the start of every file. Worse, it could be closing a door we'll never see again.
Hi Michael,
Thanks - registered as opposed, conditional on "not bundled with
something larger". That conditional is a useful distinction.
The "you're closing the door on a bigger one-shot opportunity"
framing is worth answering directly. Two reasons I don't think it
holds:
-
.phpc and a hypothetical JS-strict-mode-style language cleanup
are best designed as orthogonal axes, not bundled. Strict mode
naturally lives in declare() or an attribute - both work inside
.php AND .phpc. Coupling "pure code" with "strict mode" would
force every .phpc adopter into strict mode whether they want it
or not, which is a much bigger ask than "opt into either
independently". -
PHP already has per-file opt-ins that landed individually -
declare(strict_types=1), declare(ticks=1), readonly classes,
enums, property hooks. None of them consumed "the one-shot
file-mode slot" because there isn't one. .phpc adds one more
opt-in along a different axis; it does not consume design space
a future strict mode would need.
Bundling would make BOTH proposals harder, not easier. Strict mode
is contentious by design (every behaviour change has defenders) and
would extend Discussion and Voting by months or years. Removing the
opener does not have to wait on that.
If you have concrete ideas about what a PHP strict mode should
contain - which warts, which behaviours, which design - I would be
genuinely interested, separate from this RFC. That is a conversation
worth having on its own merits, in its own thread.
Regards,
Hendrik
<snip> > > If that friction is not worth solving, that is a legitimate position > and I would rather hear that than dress the proposal up to look > weightier than it is. Three honest paths from here, and I would find > it useful if respondents could say which they are closest to: > > 1. The friction is real and a small targeted addition is worth > shipping. (what the RFC proposes) > 2. The friction is real but the mechanism is wrong. (in which case: > what signal would you prefer? per-file declare, magic first line, > SAPI-only, ...) > 3. The friction is not real, or not worth a language change at all.
I am strongly in camp 3; I see zero value in this.
Adding meaning to a specific extension is a BC break when no extensions have meaning prior. In addition, it makes it difficult to identify the file type from the code alone if you're not familiar with it.
There really isn't any friction here, any decent editor or IDE will give you a default file header with the open tag (at least). At worst they'll auto-complete after at most 2 characters.
It's also important to note that other languages have explicit template files like Jinja or ERB, PHP does not have this and is itself essentially both the template language and the full programming language.
Yes it's a legacy way of doing things like ASP classic or ColdFusion, but that doesn't make it wrong or bad.
- Davey
Am 16.06.2026 um 09:26 schrieb Davey Shafik me@daveyshafik.com:
<snip> > > If that friction is not worth solving, that is a legitimate position > and I would rather hear that than dress the proposal up to look > weightier than it is. Three honest paths from here, and I would find > it useful if respondents could say which they are closest to: > > 1. The friction is real and a small targeted addition is worth > shipping. (what the RFC proposes) > 2. The friction is real but the mechanism is wrong. (in which case: > what signal would you prefer? per-file declare, magic first line, > SAPI-only, ...) > 3. The friction is not real, or not worth a language change at all.I am strongly in camp 3; I see zero value in this.
Adding meaning to a specific extension is a BC break when no extensions have meaning prior. In addition, it makes it difficult to identify the file type from the code alone if you're not familiar with it.
There really isn't any friction here, any decent editor or IDE will give you a default file header with the open tag (at least). At worst they'll auto-complete after at most 2 characters.
It's also important to note that other languages have explicit template files like Jinja or ERB, PHP does not have this and is itself essentially both the template language and the full programming language.
Yes it's a legacy way of doing things like ASP classic or ColdFusion, but that doesn't make it wrong or bad.
- Davey
Hi Davey,
Thanks for the direct camp-3 position - the (1/2/3) framing was
intended exactly to surface that kind of clarity, and a voter
landing explicitly in 3 with substantive reasons is more useful
to me than vague reservations would have been.
I won't try to argue you out of camp 3 - your stance is
well-formed and arguing past it would just escalate. A few
responses point-by-point, primarily for other readers who are
still forming a view.
Adding meaning to a specific extension is a BC break when no
extensions have meaning prior.
Mostly conceded, with one nuance: .phar already carries
filename-aware semantics in the engine (the phar:// stream
wrapper resolves entries against the .phar filename, and the
archive opens differently from a regular file). It is not a
clean precedent for "extension drives lexer mode at file-open
time", but PHP does not have //zero// precedent for filenames
mattering to the engine.
You are right that this RFC would be the first to make filename
drive lexer state. That is a categorical shift even if no
existing code's behaviour changes. The RFC was leaning too hard
on "strictly additive" framing; I have added an explicit "this
is a categorical precedent shift" entry to the "What this RFC
does NOT claim" section in v0.4 (just published, see Changelog).
It makes it difficult to identify the file type from the code
alone if you're not familiar with it.
Conceded as a real cost. The <?php opener is a portable "this
is PHP" marker that travels with code into Stack Overflow
answers, blog posts, diff views, IDEs that hide extensions. A
naked .phpc snippet loses that signal until the reader has
learned what .phpc means. Also added as an explicit downside in
the v0.4 "does NOT claim" section.
The flip side (most snippets already drop <?php in practice
because the surrounding context is clear) softens the cost but
does not erase it. Reasonable to weigh it at "small but real".
There really isn't any friction here, any decent editor or IDE
will give you a default file header with the open tag
Agreed; the typing cost is microscopic. The RFC has tried to
say this honestly ("not a big ergonomic win" was already in
the Motivation section). What remains is the //read// cost: the
visual noise of <?php on every file you open. You can reasonably
value that at zero, especially if your IDE renders the opener
in a muted colour or folds it.
Other languages have explicit template files like Jinja or
ERB, PHP does not have this and is itself essentially both the
template language and the full programming language. [...] Yes
it's a legacy way of doing things like ASP classic or
ColdFusion, but that doesn't make it wrong or bad.
Agreed - PHP's template-and-programming-language duality is a
real and ongoing identity, defended even by people who never
write inline templates themselves. .phpc does not change that:
.php files continue to support full templating, mixed mode,
short tags, ?>, the lot. .phpc is an opt-in for files where the
author has decided "this is code, no template behaviour wanted".
On the legacy framing: those languages died for many reasons,
but "you could use them as a template engine" was not one. PHP's
longevity is partly because of that duality, not in spite of it.
I would not pitch .phpc as "removing the legacy" - it is purely
adding a way for individual files to opt out of inheriting it.
If you have time, one clarifying question that would help shape
the rest of the discussion:
Is your camp-3 stance disqualifying the specific mechanism
(.phpc-extension dispatch), or disqualifying the broader concept
of "let me write a PHP file without <?php" regardless of
mechanism? Camp 3 on the mechanism is actionable for future
iteration; camp 3 on the concept is information that tells me
to stop spending the Discussion's air time on this.
Either answer is useful to know.
Regards,
Hendrik
Le 16/06/2026 à 10:47, Hendrik Mennen a écrit :
Adding meaning to a specific extension is a BC break when no
extensions have meaning prior.
Mostly conceded, with one nuance: .phar already carries
filename-aware semantics in the engine (the phar:// stream
wrapper resolves entries against the .phar filename, and the
archive opens differently from a regular file). It is not a
clean precedent for "extension drives lexer mode at file-open
time", but PHP does not have //zero// precedent for filenames
mattering to the engine.
Wong: the ".phar" extension is just a reminder. A PHAR file is "just" a
PHP file that contains the "__HALT_COMPILER(); ?>" statement that tells
the engine and extension "where" to look to decompress the archive into
code, with an internal filesystem covered under the "phar://" stream.
Any PHAR file could use any extension, and ".phar" is just indicative.
It runs natively with PHP without needing an extension to be considered
as an archive.
I'm also camp-3, I think this feature doesn't add anything to PHP, and
breaks BC by introducing file extension as a constraint for conditional
parsing methods.
Am 16.06.2026 um 09:26 schrieb Davey Shafik me@daveyshafik.com:
<snip> > > If that friction is not worth solving, that is a legitimate position > and I would rather hear that than dress the proposal up to look > weightier than it is. Three honest paths from here, and I would find > it useful if respondents could say which they are closest to: > > 1. The friction is real and a small targeted addition is worth > shipping. (what the RFC proposes) > 2. The friction is real but the mechanism is wrong. (in which case: > what signal would you prefer? per-file declare, magic first line, > SAPI-only, ...) > 3. The friction is not real, or not worth a language change at all.I am strongly in camp 3; I see zero value in this.
Adding meaning to a specific extension is a BC break when no extensions have meaning prior. In addition, it makes it difficult to identify the file type from the code alone if you're not familiar with it.
There really isn't any friction here, any decent editor or IDE will give you a default file header with the open tag (at least). At worst they'll auto-complete after at most 2 characters.
It's also important to note that other languages have explicit template files like Jinja or ERB, PHP does not have this and is itself essentially both the template language and the full programming language.
Yes it's a legacy way of doing things like ASP classic or ColdFusion, but that doesn't make it wrong or bad.
- Davey
Hi Davey,
Thanks for the direct camp-3 position - the (1/2/3) framing was
intended exactly to surface that kind of clarity, and a voter
landing explicitly in 3 with substantive reasons is more useful
to me than vague reservations would have been.
Did you generate this reply with an LLM? It certainly reads like that.
I'm asking because I find it an extremely rude thing to do, unless it is to assist with language.
Because if people don't want to spend their own time and effort coming with an argument, then I also don't find it necessary for me to reply to them, or hear what they're saying.
cheers
Derick
Am 16.06.2026 um 20:43 schrieb Derick Rethans derick@php.net:
Am 16.06.2026 um 09:26 schrieb Davey Shafik me@daveyshafik.com:
<snip> > > If that friction is not worth solving, that is a legitimate position > and I would rather hear that than dress the proposal up to look > weightier than it is. Three honest paths from here, and I would find > it useful if respondents could say which they are closest to: > > 1. The friction is real and a small targeted addition is worth > shipping. (what the RFC proposes) > 2. The friction is real but the mechanism is wrong. (in which case: > what signal would you prefer? per-file declare, magic first line, > SAPI-only, ...) > 3. The friction is not real, or not worth a language change at all.I am strongly in camp 3; I see zero value in this.
Adding meaning to a specific extension is a BC break when no extensions have meaning prior. In addition, it makes it difficult to identify the file type from the code alone if you're not familiar with it.
There really isn't any friction here, any decent editor or IDE will give you a default file header with the open tag (at least). At worst they'll auto-complete after at most 2 characters.
It's also important to note that other languages have explicit template files like Jinja or ERB, PHP does not have this and is itself essentially both the template language and the full programming language.
Yes it's a legacy way of doing things like ASP classic or ColdFusion, but that doesn't make it wrong or bad.
- Davey
Hi Davey,
Thanks for the direct camp-3 position - the (1/2/3) framing was
intended exactly to surface that kind of clarity, and a voter
landing explicitly in 3 with substantive reasons is more useful
to me than vague reservations would have been.Did you generate this reply with an LLM? It certainly reads like that.
I'm asking because I find it an extremely rude thing to do, unless it is to assist with language.
Because if people don't want to spend their own time and effort coming with an argument, then I also don't find it necessary for me to reply to them, or hear what they're saying.
cheers
Derick
Hi Derick,
Yes, I use AI but for assist - not to „copy-paste“ reply.
Reason for this: I’m native German and it’s easier for me to write an answer with LLM instead of using google translator for words, which don’t come to my mind.
To clarify my position with LLM: It’s a tool and not a placement.
Hendrik
Am 16.06.2026 um 20:43 schrieb Derick Rethans derick@php.net:
Am 16.06.2026 um 09:26 schrieb Davey Shafik me@daveyshafik.com:
<snip>If that friction is not worth solving, that is a legitimate position
and I would rather hear that than dress the proposal up to look
weightier than it is. Three honest paths from here, and I would find
it useful if respondents could say which they are closest to:
- The friction is real and a small targeted addition is worth
shipping. (what the RFC proposes)- The friction is real but the mechanism is wrong. (in which case:
what signal would you prefer? per-file declare, magic first line,
SAPI-only, ...)- The friction is not real, or not worth a language change at all.
I am strongly in camp 3; I see zero value in this.
Adding meaning to a specific extension is a BC break when no extensions
have meaning prior. In addition, it makes it difficult to identify the file
type from the code alone if you're not familiar with it.There really isn't any friction here, any decent editor or IDE will give
you a default file header with the open tag (at least). At worst they'll
auto-complete after at most 2 characters.It's also important to note that other languages have explicit template
files like Jinja or ERB, PHP does not have this and is itself essentially
both the template language and the full programming language.Yes it's a legacy way of doing things like ASP classic or ColdFusion, but
that doesn't make it wrong or bad.
- Davey
Hi Davey,
Thanks for the direct camp-3 position - the (1/2/3) framing was
intended exactly to surface that kind of clarity, and a voter
landing explicitly in 3 with substantive reasons is more useful
to me than vague reservations would have been.Did you generate this reply with an LLM? It certainly reads like that.
I'm asking because I find it an extremely rude thing to do, unless it is
to assist with language.Because if people don't want to spend their own time and effort coming
with an argument, then I also don't find it necessary for me to reply to
them, or hear what they're saying.cheers
DerickHi Derick,
Yes, I use AI but for assist - not to „copy-paste“ reply.
Reason for this: I’m native German and it’s easier for me to write an
answer with LLM instead of using google translator for words, which don’t
come to my mind.To clarify my position with LLM: It’s a tool and not a placement.
Hendrik
Here's a thought - Instead of .phpc as an extension, why not <?phpc or even
<?psf (PHP source file). Explicitly tell the engine "nothing should be
before this other than a shebang, no further tags will be in this file.
That also solves the inadverted echo problem and would be fully BC.
Not convinced it would be useful, but it has fewer problems.
Here's a thought - Instead of .phpc as an extension, why not <?phpc or
even <?psf (PHP source file). Explicitly tell the engine "nothing should be
before this other than a shebang, no further tags will be in this file.That also solves the inadverted echo problem and would be fully BC.
Not convinced it would be useful, but it has fewer problems.
I could actually get behind an alternative tag that reads everything as
PHP. It would at least solve the problem of accidental output prior to the
opening tag, though I'm not sure how big of a problem that really is. Could
we expect any performance benefits from not having to parse for any closing
tags? I imagine it would be minuscule if anything
On Tue, Jun 16, 2026 at 7:02 PM Sarina Corrigan sarina.corrigan@gmail.com
wrote:
Here's a thought - Instead of .phpc as an extension, why not <?phpc or
even <?psf (PHP source file). Explicitly tell the engine "nothing should be
before this other than a shebang, no further tags will be in this file.That also solves the inadverted echo problem and would be fully BC.
Not convinced it would be useful, but it has fewer problems.
I could actually get behind an alternative tag that reads everything as
PHP. It would at least solve the problem of accidental output prior to the
opening tag, though I'm not sure how big of a problem that really is. Could
we expect any performance benefits from not having to parse for any closing
tags? I imagine it would be minuscule if anything
Thinking on this a bit more, if it is an independent tag it could hold
directives on how the file should be parsed.
<?psf strict ?> Parse the file with strict mode. Here the closing tag means
we're done passing directives, no further tags will be allowed in the file
and the parser will remain in PHP mode for this file.
<?psf new_scope ?> Create a new scope - that is no variables, symbols or
autoloaders will be shared with the file that included this one. This is an
alternate way to do containers aside from creating a new function.
Thoughts?
Am 17.06.2026 um 02:58 schrieb Michael Morris tendoaki@gmail.com:
Here's a thought - Instead of .phpc as an extension, why not <?phpc or even <?psf (PHP source file). Explicitly tell the engine "nothing should be before this other than a shebang, no further tags will be in this file.
That also solves the inadverted echo problem and would be fully BC.
Not convinced it would be useful, but it has fewer problems.
I could actually get behind an alternative tag that reads everything as PHP. It would at least solve the problem of accidental output prior to the opening tag, though I'm not sure how big of a problem that really is. Could we expect any performance benefits from not having to parse for any closing tags? I imagine it would be minuscule if anything
Thinking on this a bit more, if it is an independent tag it could hold directives on how the file should be parsed.
<?psf strict ?> Parse the file with strict mode. Here the closing tag means we're done passing directives, no further tags will be allowed in the file and the parser will remain in PHP mode for this file.
<?psf new_scope ?> Create a new scope - that is no variables, symbols or autoloaders will be shared with the file that included this one. This is an alternate way to do containers aside from creating a new function.
Thoughts?
Hm my core idea was, to get PHP a bit more like C#, Python and so on - they also don’t have a start -/ end tags
But as a first goal, your idea seems logical
Hendrik
Hi
Am 2026-06-17 01:02, schrieb Sarina Corrigan:
opening tag, though I'm not sure how big of a problem that really is.
Could
we expect any performance benefits from not having to parse for any
closing
tags? I imagine it would be minuscule if anything
I wouldn't be surprised if that would even be a negative performance
improvement, because it's more “conditions” that the parser needs to
keep track of.
But this is all a purely academic discussion: The file is supposed to
sit in OPcache anyways and not be reparsed and recompiled all the time.
Best regards
Tim Düsterhus
It would at least solve the problem of accidental output prior to
the opening tag, though I'm not sure how big of a problem that really
is.
I'm not sure it would even solve the problem. It's surely very easy to
spot bogus output when the opening <?php is missed in a pure-code file
(even before the file is saved if the editor is highlighting syntax).
There is a much better chance of missing the tag in the middle of a
template file - perhaps on a code path that isn't always taken - down
where a lot of similar punctuation is already happening.
Hi
Am 2026-06-16 21:33, schrieb Hendrik Mennen:
Reason for this: I’m native German and it’s easier for me to write an
answer with LLM instead of using google translator for words, which
don’t come to my mind.
The majority of participants on this list are not native speakers of
English. Personally I'm a native German as well. Minor grammar mistakes
or a sub-optimal choice of words is not a problem and something that
readers will just autocorrect. If there really is an issue with
something being completely incomprehensible, someone will ask a
clarifying question and usually rephrasing things will keep things
moving. I'd even say that simple language is preferable, because it
increases the chances that folks with varying English skills will be
able to understand what is being said.
LLMs are great at generating incredibly complex sentences with words
that sound smart, but that will make it harder for others, particularly
non-native speakers, to understand things without resorting to tooling
themselves.
If you are really struggling with expressing yourself in English, I
strongly suggest to write the texts in German and translate them to
English. Or write them in English and ask a tool to just correct the
grammar. From my experience DeepL is working well even for technical
texts. This will ensure the resulting message matches the tone and style
of how you would communicate.
All that said, the RFC text itself also appears to come straight from an
LLM. Notably is doesn't follow the RFC template at
https://wiki.php.net/rfc/template and the expected structure from an
RFC. Some important parts are missing. While following the template is
not strictly necessary, it is carefully designed to make sure to guide
authors through the process and make sure they don't forget anything. I
would strongly urge everyone to follow the template, unless they are an
experienced RFC author and have good reasons to diverge.
Specifically missing from your RFC is the “To the Ecosystem” section
from the “RFC Impact”. The voting widgets should also be set up right
from the start so that there is no ambiguity with how the vote will
look.
With regard to the contents of the RFC: The RFC should primarily contain
a factual description of the user-facing behavior of the proposal. The
value for a strong proposal should become obvious by itself.
If it is necessary to specifically argue against “counter-arguments”
within the RFC itself, it is likely that the proposal itself is not
sufficiently strong by itself. Specifically paraphrasing individual
counter-arguments from the discussion within the RFC and then “replying”
to the individual in question is not appropriate for the RFC text,
especially since this easily results in a biased representation by
accident. Discussing the merit of the RFC is what the discussion is for
and to make it easy for folks to find the discussion the reason why the
RFC policy mandates including a link to the discussion thread in the
archives (the link to this discussion is missing from the RFC, only the
pre-RFC discussion is linked).
Similarly, including implementation details within the RFC text is
typically not useful, because the implementation is likely to change
during review and literally is an implementation detail. What is
relevant is how the proposal affects users of PHP.
As for the proposal itself: I don't see value in trading <?php against
an additional c in the filename. And I also don't see writing <?php
as an issue at all. This discussion and the pre-RFC discussion probably
already spent more time than allowing to omit <?php will ever save.
If you want to proceed with the RFC, you should make sure to rework the
RFC to make sure it includes all the important parts from the RFC
template.
Best regards
Tim Düsterhus
- The friction is real and a small targeted addition is worth
shipping. (what the RFC proposes)- The friction is real but the mechanism is wrong. (in which case:
what signal would you prefer? per-file declare, magic first line,
SAPI-only, ...)- The friction is not real, or not worth a language change at all.
I also am in camp 3. I basically never type <?php myself. My IDE does it for me when I create a file. This is a non-issue, and the proposed solution, as others have explained, has many issues and gotchas.
One useful part of Alex's module proposal was a file type that had stricter rules about what it could do; basically it had to follow PSR-1. I think there could be potential in that concept, but it wouldn't be triggered by a different file name; it would be triggered by, say, <?phpo (PHP Only), or some other prefix that indicates the whole file must be code, no ?> allowed, cannot have top-level output or code, etc. The idea needs some development, but I could see that having use in a way that doesn't break BC.
But pivoting off the file name is a non-starter.
--Larry Garfield
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>
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