13.08.2020, 10:52, "Claude Pache" <claude.pa...@gmail.com>:
>> Le 12 août 2020 à 22:05, Luis - SoftSAT Sistemas 
>> <l...@softsatsistemas.com.br> a écrit :
>>
>>>>  Le 12 août 2020 à 20:19, Luis - SoftSAT Sistemas 
>>>> <l...@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
> 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
>
> —Claude

I think it's all clear now, thanks Claude!

-- L. Henrique

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to