On 15/10/2013 17:11, Johannes Schlüter wrote:
In general: Getting rid of it is good. But mind that closures are no
full replacement as with create_function() the code can be created on
the fly.
Yes, I agree that there is no trvial solution which is 100% feature (and bug) compatible with create_function(). However, I think the more important question is whether there are any particular *use cases* which can't be easily migrated to a different mechanism.
My gut feel is that at least 95% of uses of create_function are to create dynamic callbacks for usort, preg_replace_callback, array_filter, etc. For these uses, the implementation as an eval() is a liability, and reimplementing with real closures is trivial (assuming no need to run on <=5.2).
The remaining uses may be taking deliberate advantage of the fact that it's an eval() wrapper, but most of those could in turn be trivially replaced with a user-defined function that uses eval() to return a new closure. Only code that is somehow relying on the fact that the return is a string of the function name would need to worry about picking a unique name, and an even smaller proportion of those would care that the prefix begins with a null byte rather than some other arbitrary string.
Emulating it with eval() is also complicated as it has this
nice trick of creating function names which start with \0 and therefore
don't appear in function lists.
The only function list I know of is get_defined_functions(), which does indeed exclude properties with a leading null byte, via an internal function named copy_function_name. It's not clear from the logs whether that was a deliberate decision or a side-effect of some other use of null bytes. Elsewhere, function_exists() returns true for these "anonymous" functions, and ReflectionFunction is able to see them, although it confusingly thinks their name is still __lambda_func.
Since closures are also not visible in get_defined_functions(), for this to matter, somebody would have needed to write code that relied simultaneously on their function being referable to by name *and* it not appearing in that particular list.
It's certainly possible that somebody would be forced to do some more serious rewrites if that exact combination weren't possible, but it seems extremely unlikely to me.
Regards,
--
Rowan Collins
[IMSoP]