Re: Nested functions
| From: | Claude Pache | Date: | Thu, 13 Aug 2020 13:52:39 +0000 |
| Subject: | Re: Nested functions | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-111505@lists.php.net to get a copy of this message | ||
> Le 12 août 2020 à 22:05, Luis - SoftSAT Sistemas <luis@softsatsistemas.com.br> a écrit
> :
>
>>> 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()™�F«ì`¢8á¡À
> ^ï 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
About global variables; it is an issue I encountered once upon a time when refactoring code. The
short term solution is to declare the global variables both in the inner and the outer scope:
```php
// b.php
global $something;
$something = 10;
function bar() {
global $something;
return $something;
}
```
Functions in PHP have the following characteristics: they are defined globally, and they don’t
inherit variables from their parent scope. On the other hand, anonymous functions (closures) are
available locally, and they may import variables from their parent scope. Both sort of functions
have their usages.
About the RFC page: It looks to me like an old abandoned stub. It isn’t even listed on https://wiki.php.net/rfc <https://wiki.php.net/rfc>
—Claude