On Wed, May 27, 2026 at 8:13 AM hmennen90@gmail.com hmennen90@gmail.com
wrote:
Hi internals,
I intend to submit an RFC introducing a new file extension for pure-code
PHP source files (no leading <?php required) and would like to gather
feedback before drafting.Proposal in brief:
Files ending in .phpc would be parsed starting in ST_IN_SCRIPTING state.
No <?php or ?> tags permitted inside such files. Existing .php files and
their semantics are completely unchanged. This is purely additive and
BC-clean.Motivation:
PHP's mixed-mode default reflects its 1995 templating origins. Since PHP
7+, the language has evolved into a credible general-purpose tool: strict
types, enums, readonly classes, property hooks, JIT compilation. I
personally maintain PHPolygon, a CPU-bound 3D engine written in PHP – a use
case where the templating heritage is pure ceremony. Other modern uses (CLI
tooling, queue workers, code generators) share this pattern. A dedicated
pure-code file format would be a small but meaningful acknowledgment that
PHP-as-language is now a first-class use case alongside PHP-as-template.Prior art and what's different:
I have read both rfc/source_files_without_opening_tag (Boutell, 2012,
abandoned by author) and rfc/nophptags (Ohgaki, 2014, inactive). My
proposal deliberately avoids what I believe were the two design choices
that killed them:
- No new include syntax (Boutell's AS keyword). Extension-based detection
only.- No php.ini-based mode switch (Ohgaki's template_mode). No global config
side effects.- No security framing. The mode-switch overhead is parse-time only and
OPcache/JIT eliminate it in practice; this proposal is about conceptual
clarity and tooling, not performance or LFI mitigation.Implementation:
I will write and maintain the implementation patch. Initial scope:
extension registration in zend_compile_file, lexer state initialization,
OPcache awareness, CLI support, and rejection of <?php/?> tokens inside
.phpc files. I will also coordinate with Composer maintainers ahead of RFC
submission to confirm autoload support.Open questions for the list:
- Is the .phpc extension acceptable as the disambiguator, or is there
appetite for something else (e.g. shebang line, declare directive – both of
which I think are worse, but I'd hear the case)?- Should #! shebang lines and UTF-8 BOM be permitted before the implicit
scripting state begins? My intent is yes for both.- Should __halt_compiler() retain its current behavior in .phpc files? My
intent is yes.I welcome substantive critique. If the concept itself is unwanted, I would
rather know now than discover it during a vote.Thanks.
Hendrik Mennen
Maintainer, PHPolygon
I've proposed things very similar to this before, so these are my thoughts
and points raised earlier.
-
Extension based parsing isn't a popular idea. The first few responses to
this have echoed this, but there's a certain power in allowing the parser
to not care about the extension. -
IDE's will have to be updated for these files as they parse PHP based on
the presence of the <?php tag being detected. -
My suggestions have been to use a special require statement to pull
these files in - require_module, require_library. This gets around the
problem of the extension mattering. The rule could be set that these files
are always include only once. However, this introduces a new problem -
composer will need to somehow know which require technique to use if
there's more than one to choose from. -
PHP has several braceless syntax control structure commands - Would
these stay around or should they too go away since they aren't really
needed in a code first file. -
The ability to avoid an accidental echo and therefore mess up headers is
pretty valuable, but what else is going to be picked up? Can the token
parser iterate over the file faster if it doesn't have to look for <?php ?>
tags? -
I would caution against any code only include being implemented without
taking the opportunity to fix certain bugs that have gotten to stick around
because of the enormous BC breaks such fixes introduce. There are no
existing files in this format, therefore no existing code to have a BC
break. This is a rare opportunity to clean some things that should not be
passed on. Please, Please look into this as part of this.