Nested functions
| From: | Luis - SoftSAT Sistemas | Date: | Wed, 12 Aug 2020 20:05:11 +0000 |
| Subject: | Nested functions | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-111499@lists.php.net to get a copy of this message | ||
>> Le 12 août 2020 à 20:19, Luis - SoftSAT Sistemas <luis@softsatsistemas.com.br> a
>> écrit :
>>
>> In the effort to make PHP a better language i want to ask why not "fix" nested
>> functions as suggested in (https://wiki.php.net/rfc/true-nested-function-support) or block their
>> usage?
>> The current behavior is a lot unexpected.
>>
>> I am new here, sorry if it was already discussed, i can't find a good way to search
>> the mailing history.
>
> Hi,
>
> Defining a global function inside another function is not useless. Here is a dummy example:
>
> ```php
> // a.php
> spl_autoload_register(function ($classname) {
> if ($classname === 'Foo\\B')
> require 'foo/b.php';
> })
>
> // foo/b.php
> namespace Foo;
>
> class B {
> // ...
> }
>
> function some_helper(....$args) {
> // ...
> }
> ```
>
> The global function
Foo\some_helper is defined inside the
> function used as autoloader.
>
> Also, from the RFC:
>
>> They exist in the global namespace.
>
> I think you meant “They exist in the global scope”? because they are defined in the
> namespace corresponding to the eventual namespace declaration of the
> file.
>
> —Claude
You are right Claude, i wasn't thinking about this use case.
But outside of this use case more problems arise.
If foo/b.php have some global variable and some function that use it the function
breaks because the global variable will be "included" into current scope, while the
functions into namespace scope.
```php
//a.php
function foo() {
require 'b.php';
//var_dump($something);
}
foo();
var_dump(bar());
//b.php
$something = 10;
function bar() {
global $something;
return $something;
}
```
I expected the var_dump(bar()); output to be int (10), but it was
NULL, while if i do var_dump($something); from foo() it
outputs int(10) as "normally expected".
Given that "bar()" are at namespace scope, this can be "fixed" changing
$something = 10; to $GLOBALS['something'] = 10;, but that
doesn't change the fact that this behavior are odd and not intuitive.
PS: I known that global variables are a bad thing, it was just an example.
Anyway now i see that changing this will break the auto loader system.
About the RFC you are right, they are wrong about the scope, but the RFC aren't mine, i just
found it while searching about the subject.
--L. Henrique