I used this function to create dynamic functions with dynamix names. There
are lot of use. I have sure the clousures are not final replacement.
My two cents
Em 14/10/2013 18:33, "Rowan Collins" rowan.collins@gmail.com escreveu:
Hi All,
(First, a quick aside: I'm new here, so let me know if I'm treading on any
toes or failing to do my homework properly. Also, apologies for
long-windedness; it's a personal flaw.)
I would like to propose that create_function()
be officially deprecated, to
encourage people to use the much safer and more powerful anonymous
functions we've had since 5.3, and eventually allow this relic to be
removed from the language.
In case any of you aren't familiar with the details, create_function,
according to Zeev's comment in the source "Creates an anonymous function,
and returns its name (funny, eh?)". It does this by wrapping some
boilerplate around two strings provided by the user, and eval()ing the
result to (hopefully) create a function called __lambda_func; it then
renames this to a unique name beginning with a null byte, so that it can't
conflict with any "real" functions, and returns the new name as a string.
Until PHP 5.3, this was the only way to dynamically create a callback
function, and is thus a widely used feature, so it should not be removed in
a hurry. Many projects (e.g. Wordpress) still support PHP 5.2, so cannot
switch over to true anonymous functions yet; but we can hope that most
people will have abandoned 5.2 by the time 5.7 or 5.8 comes around, and
re-evaluate then.
The argument for deprecating it is largely the same as for the /e modifier
in preg_replace - namely that it's a wrapper around eval(), with all the
dangers that brings. In fact, I've seen a few people trying to "fix" uses
of preg_replace using create_function()
to create the argument for
preg_replace_callback()
!
Specifically:
- It performs absolutely no checks before eval()ing the string. It is
therefore trivial for code to end up injected into it, and even be
run immediately, e.g. create_function('', '} echo "hi"; if (0) {');
[http://3v4l.org/YtmVT] - Since the function body is simply a string, the only way to "close
over" a variable is to use var_export, serialize, or similar. Even
string variables need careful escaping. - The function name it creates, although guaranteed unique, is
entirely predictable, and the function exists in the global
namespace. It's impossible to truly isolate it to a particular scope. - The function, once created, is never destroyed, so repeated use of
create_function "leaks" memory.
A seeming alternative to deprecating it would be to reimplement it in terms
of closures. However, this would be the worst of both worlds: on the one
hand, it would still need to eval() its body argument, so have much the
same security risk; on the other, it would still represent a BC break,
because it would have a different return type. It is, for instance,
possible to reference one "anonymous" function within another, by judicious
use of var_export or similar to inject the null-prefixed string into the
function body; I doubt anyone heavily uses such tricks, but if they did,
create_function()
returning a closure object would be more irritating than
it not existing at all.
I mentioned in StackOverflow chat that the documentation still had examples
using create_function, and NikiC went ahead and fixed several, as well as
adding a warning to the top of the documentation page. [
https://github.com/salathe/phpdoc-en/commit/
1d57b16e69dfd8d93dd6e4a354d3ed**20bd21494dhttps://github.com/salathe/phpdoc-en/commit/1d57b16e69dfd8d93dd6e4a354d3ed20bd21494d
].
I think it would be sensible to take this a step further and emit an
E_DEPRECATED
message if it is used in PHP 5.6, and add to the warning that
it may be removed in a future version of PHP.
If anyone can think of any counter-arguments - and in particular, any uses
of create_function()
which can't trivially be replaced with either a true
closure or a direct call to eval() - I would be interested to hear them.
Regards,
--
Rowan Collins
[IMSoP]