rfc:fallback-to-root-scope-deprecation

This is an old revision of the document!


PHP RFC - Deprecation of fallback to root scope

Introduction

Fallback to global scope allows namespaces to access in an unqualified manner symbols actually residing in the root namespace.

namespace Bar;
strlen();
// first tries to call \Bar\strlen()
// if not found, fallbacks to \strlen()

This feature causes more harm than good, since it prevents PHP from implementing in a sensible manner long-requested features like function autoloading. Additionally, it causes PHP to behave weirdly and inefficiently (https://3v4l.org/C0ZLq).

Proposal

This RFC proposes to deprecate the fallback to root scope, by emitting a Notice (E_NOTICE or E_STRICT), e.g.:

Undefined function \My\NS\strlen(), assumed \strlen()
Undefined constant \My\NS\PHP_VERSION, assumed \PHP_VERSION

It also proposes, considered the entity of the change, that the “fallback to root scope” feature must be removed through the RFC process and thus only when the community think is appropriate doing so and only alongside the introduction of the “function and constant autoloading” feature.

In fact, if the feature is removed and autoloading of functions and constants is introduced at the same time, authors that failed to update their code can easily shim it using just few lines of code:

// Fallback to global scope shim
// This code simply copies \strlen to \Current\NS\strlen
register_autoloader(
    AUTOLOAD_FUNCTION | AUTOLOAD_CONST,
    function(string $QN, int $type){
 
        $start = strrpos($QN, "\\");
        if($start === false){ return; }
 
        // e.g. "My\Full\NS"
        $sourceNS = substr($QN, 0, $start);
 
        // e.g. "strlen"
        $rootSymbol = substr($QN, $start + 1);
 
        if(
            ($type & AUTOLOAD_FUNCTION) &&
            function_exists($rootSymbol)
        ){
            eval('
                namespace ' . $sourceNS . ';
                function ' . $rootSymbol . '(...$args){
                    return \\' . $rootSymbol . '(...$args);
                }
            ');
        }elseif(
            ($type & AUTOLOAD_CONST) &&
            defined($rootSymbol)
        ){
            eval('
                namespace ' . $sourceNS . ';
                const ' . $rootSymbol . ' = \\' . $rootSymbol . ';
            ');
        }
    }
);

However, if this RFC passes, authors should try to avoid the Notice by writing `\strlen()` or `use function {strlen, strpos};` in their code, which are plenty of solutions covering any code style.

Migration Tools

Backward Incompatible Changes

None (the Notice can be silenced if needed).

Proposed PHP Version:

7.3

Voting

2/3 majority will be required.

References

rfc/fallback-to-root-scope-deprecation.1517649226.txt.gz · Last modified: 2018/02/03 09:13 by wesnetmo