rfc:source_files_without_opening_tag

This is an old revision of the document!


Request for Comments: Source Files Without Opening Tag

This RFC proposes a way to support source code files without <?php at the top.

Introduction

The purpose of this RFC is to provide a way to support source files that do not begin with <?php while maintaining backwards compatibility.

Why is this desirable?

In modern framework development and larger projects in general, it is often considered good practice to implement PHP classes in files which contain only PHP code and typically contain no “raw HTML” (no code which is not wrapped by <?php and ?>), at least not outside the context of a function or method. In such files, typing <?php at the top is:

1. Error-prone in a subtle and hard-to-debug way: if any whitespace is introduced before <?php, the code still runs, but your XHTML doctype fails to be recognized, your header() calls fail, etc. Since you may not use these features in every situation the bug is often not spotted until an inopportune time.

2. Tedious. There is a small but real frustration involved in this redundancy. Small but real frustrations can contribute to long-term disenchantment with a programming language.

However these same projects and frameworks may advocate the use of “raw HTML” in PHP files intended as templates for rendering pages, forms and the like. This is a longstanding feature of PHP (indeed the original feature of PHP). Support for it should be maintained, and may perhaps be improved in future to address PHP's current limitations as a templating language. This proposal aims not to close any doors in this regard.

Proposal

Option 1: Introduce require_path

The following new keyword will be introduced:

require_path

This keyword has two parameters of which the second is optional. The first parameter is the path (filename or URL) to be required, and behaves exactly as the sole parameter of the require keyword behaves. The second parameter is an associative array.

If this second parameter is absent, require_path behaves exactly like require.

If the second parameter is present, the following keys may optionally be present in the array, with the following effects:

If once is present and true, the specified path is loaded no more than once, exactly like require_once.

If warn is present and true, a loading or compilation error results in E_WARNING (per the current behavior of the include keyword). If warn is absent or false, a loading or compilation error results in E_COMPILE_ERROR (per the current behavior of the require keyword).

If code is present and true, the parser begins reading the file as if a <?php open tag had already been encountered. If code is absent or false, the parser reads the file beginning in “HTML mode,” exactly as the require keyword does today.

Examples:

// Behaves just like require
require_path 'filename.php';
// Behaves just like include_once
require_path 'filename.php', array('warn' => true, 'once' => true);
// Loads a file starting out in "PHP mode" so the opening <?php is not required
require_path 'filename.php', array('code' => true);

Option 2: Filename Convention

Although this proposal gives implementers flexibility in how they decide when to apply the `code` flag, it is still desirable in most cases to have a commonly recognized convention to distinguish files that should be read starting in “PHP mode” from legacy and template files that should be read starting in “HTML mode.” The following convention is proposed for environments in which file extensions are a relevant and useful concept:

  • Files that should be read starting in HTML mode should have a .php extension, for backwards compatibility.
  • Files that should be read starting in PHP mode should have a .phpc extension (short for “PHP code”).

However enforcement of this convention is NOT proposed. The require_path keyword does NOT attempt to make inferences from the file extension of the path, if any.

Patch

Proposed by Moriyoshi (see https://wiki.php.net/rfc/nophptags )

Allow users to start PHP statements from the top of the script without putting open tags such as <?php. Complete removal of esoretic <script lanuage=“PHP”> open tag. Allow open tags (<?php, <?, <%) only at the top of the script for compatibility, and issue a parse error when used in other places. Ignore close tags (?> and %>) completely.

Anticipated And Previously Raised Questions

(Thanks to those who raised and responded to some of these questions already on the internals list. I am summarizing in many cases.)

“Does this break my existing code?”

No. Code that never uses the new keyword will not be affected in any way. The proposal allows autoloaders to load files the old-fashioned way and to recognize when to do so by a simple common convention or by other local conventions as appropriate.

“Isn't the require_path keyword even more work than typing <?php?”

Typically projects that will benefit from the code option to require_path also have autoloaders to load classes implicitly when they are first used. So require_path would be typed once in the autoloader, not many times everywhere.

“Won't this slow down the autoloader?”

Not really. Even in a worst-case scenario where stat() calls are slow and the autoloader performs no caching even in a production environment, the autoloader will often be able to assume that only .phpc files are expected because that is the convention of the library or framework from which they came, so it won't be necessary to stat() first for .phpc and then check for .php as well. It is also possible to prewarm autoloader caches as part of deployment.

“Won't this break if you try to use the code with an older version of PHP?”

Of course. A choice to use this feature implies a choice to support only the supporting version of PHP or newer. But it'll break cleanly with a clear error message, just like code that tries to use traits or other newer features. That is one of the advantages of using new keywords rather than applying special behavior to file extensions automatically or similar.

“Why doesn't the proposal forbid the use of ?> to get back to HTML mode in a .phpc file?”

Two reasons:

1. While it is tempting to be a purist about this, those who are creating code generators and the like may sometimes find it useful to leverage HTML mode in a class file (though they also have the option of requiring a regular .php file). It is not the place of this proposal to forbid them from doing what they want if it doesn't interfere with the ability of others to write maintainable, bug-free code more conveniently. Some may find it unsettling to use ?> where you have not explicitly used <?php, but they don't have to use this capability.

2. It is suspected that the implementation of the proposal will be simpler and therefore easier to debug and maintain if it is limited simply to setting the initial state of the parser.

“Why introduce a keyword that takes an array parameter instead of new keywords?”

Using new keywords would require doubling the number of variations on require from four to eight. Other proposals being aired to alter and enhance PHP's functionality as a template language would increase this number even more. An associative array is a sustainable solution which will potentially allow for other enhancements if approved. And since this keyword will primarily be used in autoloaders it does not represent a lot of tedious typing in many places (although the new short array syntax already included in PHP 5.4 would help if you did choose to use this keyword frequently).

Changelog

  • 2011-04-XX Not yet
rfc/source_files_without_opening_tag.1333951641.txt.gz · Last modified: 2017/09/22 13:28 (external edit)