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.
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:
// 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
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:
// 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.
//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
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:
// 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.
Iffoo/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.//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 beint (10)
, but it wasNULL
, while if i dovar_dump($something);
fromfoo()
it outputsint(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:
// 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
13.08.2020, 10:52, "Claude Pache" claude.pache@gmail.com:
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:
// 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.
Iffoo/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.//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 beint (10)
, but it wasNULL
, while if i dovar_dump($something);
fromfoo()
it outputsint(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:// 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