rfc:on_demand_name_mangling
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:on_demand_name_mangling [2016/01/02 03:38] – Fixed incorrect constant (typo) bishop | rfc:on_demand_name_mangling [2019/07/16 12:25] (current) – Settled on formal polyfill name, php_mangle_superglobal bishop | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: On-demand Name Mangling ====== | ====== PHP RFC: On-demand Name Mangling ====== | ||
- | * Version: 1.1 | + | * Version: 1.4 |
- | * Date: 2016-01-01 | + | * Created |
- | * Author: Bishop Bettini, bishop@php.net | + | * Updated Date: 2019-07-16 |
+ | * Author: Bishop Bettini | ||
* Status: Under Discussion | * Status: Under Discussion | ||
- | * First Published at: http:// | + | * First Published at: http:// |
===== Introduction ===== | ===== Introduction ===== | ||
- | PHP marshals external key-value pairs into super-globals by mangling some disallowed characters to underscores: | + | PHP marshals external key-value pairs into super-globals by [[https:// |
+ | |||
+ | * "'' | ||
+ | * If there is no "'' | ||
+ | * Other characters are left as is | ||
+ | |||
+ | As seen here, both for both '' | ||
< | < | ||
# the shell environment variable " | # the shell environment variable " | ||
- | $ / | + | $ / |
foo | foo | ||
# a " | # a " | ||
- | $ / | + | $ / |
foo | foo | ||
# same mangling rules for $_REQUEST | # same mangling rules for $_REQUEST | ||
- | # curiously "$" does not mangle, even though it's not a valid PHP variable name | + | # Note how $ is ignored |
$ cat mangle.phpt | $ cat mangle.phpt | ||
--TEST-- | --TEST-- | ||
Line 43: | Line 50: | ||
</ | </ | ||
- | Mangling has the undesirable consequence that //many// external variables may map to //one// PHP variable. For example, three separate HTML form elements named '' | + | Mangling has the undesirable consequence that //many// external variables may map to //one// PHP variable. For example, three separate HTML form elements named '' |
- | Automatic name mangling supported '' | + | Automatic name mangling supported '' |
< | < | ||
--TEST-- | --TEST-- | ||
- | Name mangling logic moved to extract() | + | Name mangling logic removed from engine, placed in polyfill |
--GET-- | --GET-- | ||
- | a.b=dot& | + | a.b=dot& |
--FILE-- | --FILE-- | ||
<?php | <?php | ||
- | extract($_GET, EXTR_MANGLE); | + | print_r(get_defined_vars()); |
+ | php_mangle_superglobals(); | ||
print_r(get_defined_vars()); | print_r(get_defined_vars()); | ||
?> | ?> | ||
Line 63: | Line 71: | ||
( | ( | ||
[a.b] => dot | [a.b] => dot | ||
+ | [a_b] => underscore | ||
[a$b] => dollar | [a$b] => dollar | ||
[a b] => space | [a b] => space | ||
[a[b] => bracket | [a[b] => bracket | ||
) | ) | ||
- | + | ) | |
- | [a_b] => bracket | + | Array |
+ | ( | ||
+ | | ||
+ | ( | ||
+ | | ||
+ | [a$b] => dollar | ||
+ | ) | ||
) | ) | ||
</ | </ | ||
- | In this new implementation, | + | In this new implementation, |
+ | |||
+ | In the example above, an '' | ||
+ | |||
+ | Importantly, the user made this mangling happen: the engine did not do it automatically. | ||
+ | |||
+ | The polyfill algorithm is simple: | ||
+ | |||
+ | * find all superglobal keys that violate the PHP unquoted variable name regex ((Unquoted variable names must match the regex '' | ||
+ | * for each, create a new mangled key linked to the corresponding value | ||
+ | |||
+ | Applications requiring name mangling may call the polyfill during their bootstrap phase to emulate prior engine behavior. | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | This RFC proposes to phase out automatic name mangling, | + | This RFC proposes to remove |
- | * Next minor release (currently 7.1): | + | * Upon acceptance: |
- | * Emit an '' | + | * Update documentation |
+ | * Release a userland polyfill that implements the historic mangling behavior | ||
+ | * Polyfill shall be available via composer (but not PEAR) | ||
* Next major release (currently 8.0): | * Next major release (currently 8.0): | ||
- | * Remove all name mangling code in super-global | + | * Remove all name mangling code in super-global |
- | * Update '' | + | |
- | * Add a new constant, '' | + | |
- | * If a prefix is given by any of the '' | + | |
- | * Honor '' | + | |
==== Discussion ==== | ==== Discussion ==== | ||
Line 90: | Line 114: | ||
These questions were raised in the mailing list discussion. | These questions were raised in the mailing list discussion. | ||
- | === Should | + | === Should |
+ | |||
+ | Before version 1.3, this RFC proposed raising an '' | ||
+ | |||
+ | > If I have a well behaved application that doesn’t rely on name mangling or have included the polyfill, how can I prevent a log message from being emitted | ||
+ | |||
+ | and Nikita Popov commented: | ||
- | No, because we do not know how many instances | + | > Even if it's only a single deprecation warning instead |
+ | > Sure, it's informative. But it's enough to be informative about this *once*, rather than every time a user makes an odd-ish request. | ||
- | The message | + | Given that (a) an application could get spammed by malicious users((The '' |
=== Should an INI configuration control mangling? === | === Should an INI configuration control mangling? === | ||
- | Nikita Popov suggested: | + | Nikita Popov suggested |
> I would favor the introduction of a new ini setting. E.g. mangle_names=0 disables name mangling, while mangle_names=1 throws a deprecation warning on startup and enables name mangling. mangle_names=0 should be the default. That is essentially disable name mangling, but leave an escape hatch for those people who rely on it (for whatever reason). | > I would favor the introduction of a new ini setting. E.g. mangle_names=0 disables name mangling, while mangle_names=1 throws a deprecation warning on startup and enables name mangling. mangle_names=0 should be the default. That is essentially disable name mangling, but leave an escape hatch for those people who rely on it (for whatever reason). | ||
- | An INI setting to disable mangling must be engine-wide (i.e., '' | + | An INI setting to disable mangling must be engine-wide (e.g., '' |
- | However, there is an " | + | It's still possible to provide |
- | '' | + | |
+ | The polyfill approach is considered superior to the INI approach for three reasons: | ||
+ | |||
+ | * Userland | ||
+ | * The engine | ||
+ | * No additional weight of configuration values (which | ||
=== Should '' | === Should '' | ||
- | No, because | + | Early versions of this proposal (< v1.2) proposed using '' |
+ | |||
+ | However, '' | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | This proposal introduces backward incompatible changes: any userland code relying on mangled names would have to either (a) change to using original variable names or (b) re-mangle the super-globals with a polyfill. | + | This proposal introduces backward incompatible changes: any userland code relying on mangled names would have to either (a) change to using original |
- | <code php> | + | The polyfill could be accomplished with code like: |
- | $mangler = function () { | + | |
- | // mangle names like before | + | |
- | extract($_ENV, | + | |
- | | + | <code php> |
- | | + | function php_mangle_name($name) { |
- | if (! array_key_exists($var, $_ENV)) { | + | $name = preg_replace(' |
- | $_ENV[$var] = $val; | + | |
+ | } | ||
+ | function php_mangle_superglobals() { | ||
+ | if (version_compare(PHP_VERSION, | ||
+ | return; | ||
+ | } | ||
+ | foreach ($_ENV | ||
+ | $mangled = php_mangle_name($var); | ||
+ | if ($mangled | ||
+ | $_ENV[$mangled] =& $val; | ||
} | } | ||
} | } | ||
- | }; | + | // similar loops for $_GET, $_POST |
- | $mangler(); | + | // similar logic for $_COOKIE and $_FILES |
+ | } | ||
</ | </ | ||
- | Similar algorithms could be applied to the other super-globals. | + | To reduce the burden on userland, |
- | + | ||
- | To reduce the burden on userland, | + | |
< | < | ||
- | $ composer require php/mangle-polyfill | + | $ composer require php/mangle-superglobals |
- | $ cat example.php | + | $ cat app/ |
- | <? | + | <?php |
+ | require __DIR__ . '/ | ||
+ | |||
+ | php_mangle_superglobals(); | ||
+ | // ... | ||
</ | </ | ||
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
- | PHP 7.1 (for notice of impending BC break) and PHP 8.0 (for actual implementation and corresponding BC break). | + | PHP 8.0. |
===== RFC Impact ===== | ===== RFC Impact ===== | ||
Line 160: | Line 207: | ||
===== Open Issues ===== | ===== Open Issues ===== | ||
- | None so far. | + | None. |
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
- | A simple yes/no voting option with a 2/3 majority required. | + | A simple yes/no voting option with a 2/3 majority required: " |
===== Patches and Tests ===== | ===== Patches and Tests ===== |
rfc/on_demand_name_mangling.1451705881.txt.gz · Last modified: 2017/09/22 13:28 (external edit)