# RFC: Deprecation of fallback to root scope

- Status: Inactive
- Authors: WesNetmo, Levi Morrison, Ocramius
- Date: 2017-03-05
- Version: 0.1
- Original: https://wiki.php.net/rfc/fallback-to-root-scope-deprecation
- Page: https://externals.io/rfc/fallback-to-root-scope-deprecation
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Discussions on the mailing list

- [\[RFC\]\[DISCUSSION\] Deprecation of fallback to root scope](https://externals.io/message/101745.md) — started on 2018-02-03, 51 messages
- [Opt-in "use function *;" for skipping check for function/const in alternate namespace](https://externals.io/message/107877.md) — started on 2019-11-28, 12 messages

---

## Introduction

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

```php
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 deprecation notice, 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:

```php
// Fallback to global scope shim
// This code simply aliases \strlen to \Current\NS\strlen
// Note: this is just a non-binding PoC
autoload_register(AUTOLOAD_FUNCTION | AUTOLOAD_CONST, function(string $namespaced, int $type){
    // Assumes $namespaced is NOT prepended with \
    // Assumes $namespaced is NOT already loaded
 
    // Find last occurrence of \
    $offset = \strrpos($namespaced, "\\");
 
    // Return if none; this is only active for namespaced symbols
    if($offset === false){ return; }
 
    // Fallback symbol's name:
    $fallback = \substr($namespaced, $offset + 1);
 
    // Alias the function
    if($type & \AUTOLOAD_FUNCTION && \function_exists($fallback /*, false [1] */)){
        \function_alias($fallback, $namespaced); // May be introduced too, works like class_alias
    }
 
    // Alias the constant
    if($type & \AUTOLOAD_CONST && \defined($fallback /*, false [1] */)){
        \define($namespaced, \constant($fallback));
    }
});
 
// [1] = may not trigger autoloading from an autoloader
```

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

## Migration Tools

- [PHP-CS](https://github.com/squizlabs/PHP_CodeSniffer)
- [PHP-CS-FIXER](https://github.com/FriendsOfPHP/PHP-CS-Fixer)
- [PHPStorm](https://www.jetbrains.com/phpstorm/)
- More coming soon...

## Backward Incompatible Changes

None (the `Notice` can be silenced if needed).

## Proposed PHP Version:

7.3

## Voting

2/3 majority will be required.

## References

\- [Discussion on externals](https://externals.io/message/101745)
