# Proposal to deprecate create_function()

- Thread: https://externals.io/message/69554
- Original archive: https://news-web.php.net/php.internals/69554
- Started by Rowan Collins on 2013-10-14T21:33:18+00:00
- Messages: 32
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/69554.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #69554 — Rowan Collins — 2013-10-14T21:33:18+00:00

URL: https://externals.io/message/69554#69554

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/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]

---

## #69556 — Kris Craig — 2013-10-14T23:38:21+00:00

URL: https://externals.io/message/69554#69556 · In reply to: #69554

> (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 disagree.  Verbosity is preferable to cheap one-liners.  =)


>
> 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.


Would you consider drafting an RFC for this?  Please also include details
on the current (post-5.3) functionality that replaces it.

--Kris

---

## #69567 — Rowan Collins — 2013-10-15T15:47:09+00:00

URL: https://externals.io/message/69554#69567 · In reply to: #69556

Kris Craig wrote (on 15/10/2013):
>
>     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.
>
>
> Would you consider drafting an RFC for this?  Please also include 
> details on the current (post-5.3) functionality that replaces it.

Hi Kris,

I thought that would be the way to go, and am happy to write one up. As 
I say, I'm new here, and all the guidelines strongly advised to get an 
initial reaction from the list first, so I thought I'd draft the key 
points in an e-mail first, and make sure I wasn't wasting my time on 
something that had no chance of being accepted.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #69568 — johannes@schlueters.de — 2013-10-15T16:11:55+00:00

URL: https://externals.io/message/69554#69568 · In reply to: #69554

> 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 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. 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.

I don't think this is a commonly used feature, but when kicking
create_function() we should not call closures+eval a full replacement.

johannes

---

## #69601 — Pierre Joye — 2013-10-17T11:20:27+00:00

URL: https://externals.io/message/69554#69601 · In reply to: #69554

> 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.

I think a documentation (as Nikic did or maybe improve it if
necessary) is enough. The deprecation tag is not about educating
people but about actually thinking about removing something at some
point. I don't see how we could remove create_function any time soon.

Cheers,
-- 
Pierre

@pierrejoye |  http://www.libgd.org

---

## #69633 — Rowan Collins — 2013-10-17T15:31:00+00:00

URL: https://externals.io/message/69554#69633 · In reply to: #69568

> 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]

---

## #69636 — Pierre Joye — 2013-10-17T15:47:16+00:00

URL: https://externals.io/message/69554#69636 · In reply to: #69633

> 
> > […]
>
>
> 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.

That's the actual question, why should they?


> 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).

Yes, as many other new features allow cleaner codes. However I do not
see this case as good enough to add more deprecated notices to
perfectly valid codes.

Cheers,
-- 
Pierre

@pierrejoye | http://www.libgd.org

---

## #69645 — Rowan Collins — 2013-10-17T17:48:17+00:00

URL: https://externals.io/message/69554#69645 · In reply to: #69636

> 
> > […]
> That's the actual question, why should they?
>
> > […]
> Yes, as many other new features allow cleaner codes. However I do not
> see this case as good enough to add more deprecated notices to
> perfectly valid codes.

I guess to me it seems much the same as deprecating the /e modifier in 
preg_replace: code using it right now largely works, but it presents a 
security risk that many users probably don't appreciate.

I wasn't subscribed when that was being discussed, so if there are 
points from that discussion which would be pertinent here, I'd welcome 
links/summaries.

The only real difference I can see with create_function is that it 
is/was more widely used; is that your concern, or do you see a 
fundamental difference between the two situations?

-- 
Rowan Collins
[IMSoP]

---

## #69646 — Pierre Joye — 2013-10-17T17:52:06+00:00

URL: https://externals.io/message/69554#69646 · In reply to: #69645

> 
> > […]
>
>
> I guess to me it seems much the same as deprecating the /e modifier in
> preg_replace: code using it right now largely works, but it presents a
> security risk that many users probably don't appreciate.
>
> I wasn't subscribed when that was being discussed, so if there are points
> from that discussion which would be pertinent here, I'd welcome
> links/summaries.
>
> The only real difference I can see with create_function is that it is/was
> more widely used; is that your concern, or do you see a fundamental
> difference between the two situations?

I do. create_function is used for many very valid use cases, safely,
much more than /e ever was (and its security impact was much bigger).
Deprecating it does not help us nor our users at this stage.

Cheers,
-- 
Pierre

@pierrejoye | http://www.libgd.org

---

## #69653 — Rowan Collins — 2013-10-17T18:24:58+00:00

URL: https://externals.io/message/69554#69653 · In reply to: #69646

> > […]
> I do. create_function is used for many very valid use cases, safely,
> much more than /e ever was (and its security impact was much bigger).
> Deprecating it does not help us nor our users at this stage.

If create_function did not exist, would any of those use cases persuade 
you that it should?

If not, it sounds like existing usage is the concern. Which is not to 
belittle the importance of that, I just want to be sure we're coming 
from the same place.

-- 
Rowan Collins
[IMSoP]

---

## #69655 — Marc Bennewitz — 2013-10-17T19:23:15+00:00

URL: https://externals.io/message/69554#69655 · In reply to: #69636

Am 17.10.2013 17:47, schrieb Pierre Joye:
> 
> > […]
> 
> That's the actual question, why should they?
> 
> 
> > […]
> 
> Yes, as many other new features allow cleaner codes. However I do not
> see this case as good enough to add more deprecated notices to
> perfectly valid codes.

Please note that there are open bugs with "create_function" the should
than be fixed including memory issue.

> 
> Cheers,

---

## #69657 — Pierre Joye — 2013-10-17T19:29:25+00:00

URL: https://externals.io/message/69554#69657 · In reply to: #69653

> 
> > […]
>
>
> If create_function did not exist, would any of those use cases persuade you
> that it should?

Not with latest PHP releases, but that's the point: we try to keep BC.



-- 
Pierre

@pierrejoye | http://www.libgd.org

---

## #69658 — Rowan Collins — 2013-10-17T21:22:20+00:00

URL: https://externals.io/message/69554#69658 · In reply to: #69657

> 
> > […]
> Not with latest PHP releases, but that's the point: we try to keep BC.

Well, to an extent - it is not true that any PHP script which works in 
PHP 5.2 will work in PHP 5.5, let alone work identically. For instance, 
call-time pass-by-reference causes a fatal error in PHP >= 5.4; unlike 
calls to create_function, it's tricky to search for code that used that, 
and to be confident of the implications of changing it.

So it is not a case of "thou shalt not break BC", but a case of "how big 
a BC break is this?" Obviously, there are other questions (e.g. 
challenging the reasons *for* removing it), but I'd like to break this 
one apart a bit:

Q: Is it difficult to upgrade code to not use the feature?
A: For 95%+ of cases, my contention is that refactoring use of 
create_function() to use closures is pretty trivial. A few cases which 
explicitly used its quirks may need a wrapper around eval() etc. Nobody 
has yet piped up with a use case which would rely on the 
harder-to-emulate aspects of the current implementation.

Q: Can code be migrated to the new solution in advance?
A: Yes, for all supported versions of PHP...

Q: ...OK, but what about code bases which still run on older releases?
A: Private code bases will generally either run entirely on an old 
release (in which case BC isn't an issue) or upgraded entirely to a new 
release (in which case BC is a matter of upgrade cost). Public code, 
however, is often written to support a wide range of releases, to 
maximise the install base. An obvious example is Wordpress, which 
currently has a minimum version requirement of 5.2.4, and supported PHP 
4 until remarkably recently.

If create_function were removed in version X (which is not right now), 
there would be an issue if a project such as Wordpress decided to 
support both 5.2 *and* version X from the same code base. The code base 
could then contain neither create_function nor anonymous functions - 
unless some wrapper(s) were written which abstracted both, which is 
possible for all but the most exotic usages.

For some value of X, it is reasonable to assume that this will not be 
the case, although when depends a lot on external factors. I don't know 
whether "X is too far in the future" should be considered an argument 
against deprecating or not. On the one hand, a long period of 
deprecation is a good thing, as it gives people time to plan a strategy 
for the eventual removal; on the other, it makes it uncertain whether 
you should pay attention to the deprecation yet or not.

Q: How much legacy code is "out there" that uses the feature?
A: This is probably the biggest issue, and the number one reason for not 
removing it would be the inconvenience of editing old code in order to 
run it on newer systems. Again, we are trying to predict future trends 
here: at the time of version X, how much old code will be around for 
which removing create_function would be a significant part of the 
upgrade cost?

I'm not proposing to know the "right" answer here, but I'd be interested 
to hear something other than a gut reaction of exactly why deprecating 
it would be a bad idea (or an insufficiently good one).

Apologies again for long-windedness.
Regards,

-- 
Rowan Collins
[IMSoP]

---

## #69663 — Pierre Joye — 2013-10-18T05:25:16+00:00

URL: https://externals.io/message/69554#69663 · In reply to: #69658

> 
> > […]
>
>
> Well, to an extent - it is not true that any PHP script which works in PHP
> 5.2 will work in PHP 5.5, let alone work identically. For instance,
> call-time pass-by-reference causes a fatal error in PHP >= 5.4; unlike calls
> to create_function, it's tricky to search for code that used that, and to be
> confident of the implications of changing it.

Comparing a widely used feature, working well with something that
never really worked (and why we have removed it) is hardly a good
argument to remove create_function :-)

> So it is not a case of "thou shalt not break BC", but a case of "how big a
> BC break is this?" Obviously, there are other questions (e.g. challenging
> the reasons *for* removing it), but I'd like to break this one apart a bit:


It is, create_function works and is widely used. We can provide
good/better documentation to inform our users about better, cleaner,
sexier ways to achieve the same but deprecating it in a 5.x release is
not going to work out well.


> Q: Is it difficult to upgrade code to not use the feature?
> A: For 95%+ of cases, my contention is that refactoring use of
> create_function() to use closures is pretty trivial. A few cases which
> explicitly used its quirks may need a wrapper around eval() etc. Nobody has
> yet piped up with a use case which would rely on the harder-to-emulate
> aspects of the current implementation.

Code should not be updated in the 1st place unless there is a really
critical issue, something we absolutely have to change. That's not the
case here, we do not enforce good practices (or we could enforce so
many other things in the language ;).


Also I think we disagree on that, we discussed pretty much all points,
let face it :). I have to suggest to create a RFC if you feel like it
has to be deprecated and see what other developers want.

Cheers,
-- 
Pierre

@pierrejoye | http://www.libgd.org

---

## #69665 — Nikita Popov — 2013-10-18T09:26:18+00:00

URL: https://externals.io/message/69554#69665 · In reply to: #69554

On Mon, Oct 14, 2013 at 11:33 PM, Rowan Collins <rowan.collins@gmail.com>wrote:

> 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**20bd21494d<https://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,
>

I'm +1 on deprecating create_function. It is a security liability, it is
slow and it eats memory. We have better alternatives nowadays (anonymous
functions) and in cases where you need wide-range version support
(including PHP 5.2 or lower) you are still better off using a normal, named
function rather than create_function. You can even replicate the exact
behavior (minus the hiding from get_defined_functions) with just four lines
of code (though I have no idea what you could possibly need this for):

function create_function($params, $code) {
    static $i = 0;
    $name = "create_function_" . $i++;
    eval("function $name($params) { $code }");
    return $name;
}

I tried to look on Github what people currently use create_function for,
but with little success. Nearly all results I get are uses in the php
testsuite (copied over to various projects). The only other use case I saw
was in conjunction with the WordPress add_action() function. In this case
the create_function call could always be replaced directly with an
anonymous function (i.e. it didn't need any magic create_function
capabilities).

Nikita

---

## #69666 — Crypto Compress — 2013-10-18T10:39:58+00:00

URL: https://externals.io/message/69554#69666 · In reply to: #69665

Am 18.10.2013 11:26, schrieb Nikita Popov:
> On Mon, Oct 14, 2013 at 11:33 PM, Rowan Collins <rowan.collins@gmail.com>wrote:
>
> > […]
> I'm +1 on deprecating create_function. It is a security liability, it is
> slow and it eats memory. We have better alternatives nowadays (anonymous
> functions) and in cases where you need wide-range version support
> (including PHP 5.2 or lower) you are still better off using a normal, named
> function rather than create_function. You can even replicate the exact
> behavior (minus the hiding from get_defined_functions) with just four lines
> of code (though I have no idea what you could possibly need this for):
>
> function create_function($params, $code) {
>      static $i = 0;
>      $name = "create_function_" . $i++;
>      eval("function $name($params) { $code }");
>      return $name;
> }
>
> I tried to look on Github what people currently use create_function for,
> but with little success. Nearly all results I get are uses in the php
> testsuite (copied over to various projects). The only other use case I saw
> was in conjunction with the WordPress add_action() function. In this case
> the create_function call could always be replaced directly with an
> anonymous function (i.e. it didn't need any magic create_function
> capabilities).
>
> Nikita
>
Hello,

shure all things can be replaced with more and verbose code. What is the 
benefit of writing all this lines in contrast to one method call?
https://github.com/phpcr/phpcr-utils/blob/master/src/PHPCR/Util/Console/Helper/PhpcrCliHelper.php#L111

-1 for removing wrappers/abbreviations/and such
+1 for bugfixing

Best,
CC

---

## #69667 — Alexey Zakhlestin — 2013-10-18T10:51:07+00:00

URL: https://externals.io/message/69554#69667 · In reply to: #69666

> Am 18.10.2013 11:26, schrieb Nikita Popov:
> > […]
> 
> shure all things can be replaced with more and verbose code. What is the benefit of writing all this lines in contrast to one method call?
> https://github.com/phpcr/phpcr-utils/blob/master/src/PHPCR/Util/Console/Helper/PhpcrCliHelper.php#L111
> 
> -1 for removing wrappers/abbreviations/and such
> +1 for bug fixing


I think you misunderstood Nikita's proposal.
"all these lines" can be put in a library and your code would just continue to work the way it is.

Idea is that it is trivially implemented in userland and there is no much sense to keep it in core.


-- 
Alexey Zakhlestin
CTO at Grids.by/you
https://github.com/indeyets
PGP key: http://indeyets.ru/alexey.zakhlestin.pgp.asc

---

## #69668 — Crypto Compress — 2013-10-18T10:57:53+00:00

URL: https://externals.io/message/69554#69668 · In reply to: #69667

Am 18.10.2013 12:51, schrieb Alexey Zakhlestin:
> 
>
> > […]
>
> I think you misunderstood Nikita's proposal.
> "all these lines" can be put in a library and your code would just continue to work the way it is.
>
> Idea is that it is trivially implemented in userland and there is no much sense to keep it in core.

It is possible to write most of the array functions in plain php with a 
trivial foreach. Can't see the point.

---

## #69669 — Sebastian Krebs — 2013-10-18T11:06:01+00:00

URL: https://externals.io/message/69554#69669 · In reply to: #69668

2013/10/18 Crypto Compress <cryptocompress@googlemail.com>

> Am 18.10.2013 12:51, schrieb Alexey Zakhlestin:
>
>  On 18.10.2013, at 14:39, Crypto Compress <cryptocompress@googlemail.com**>
> > […]
>
> It is possible to write most of the array functions in plain php with a
> trivial foreach. Can't see the point.


That doesn't mean, that it was useful to include some array functions into
the core. For example I still don't really get, why it was so important to
get "array_column()" into the core, whereas it is _really_ trivial in
PHP-userland [1]. In some cases it makes sense, for example for better
performance, but imo it doesn't make sense only for the sake of itself.

This said: Saying "but other xyz …" isn't an argument :)

Regards,
Sebastian


[1] Don't want to start a discussion about that. Just needed an example.


>
>
>
> --
> 
> 
>
>


-- 
github.com/KingCrunch

---

## #69673 — Nikita Popov — 2013-10-18T12:19:37+00:00

URL: https://externals.io/message/69554#69673 · In reply to: #69666

On Fri, Oct 18, 2013 at 12:39 PM, Crypto Compress <
cryptocompress@googlemail.com> wrote:

> Hello,
>
> shure all things can be replaced with more and verbose code. What is the
> benefit of writing all this lines in contrast to one method call?
> https://github.com/phpcr/**phpcr-utils/blob/master/src/**
> PHPCR/Util/Console/Helper/**PhpcrCliHelper.php#L111<https://github.com/phpcr/phpcr-utils/blob/master/src/PHPCR/Util/Console/Helper/PhpcrCliHelper.php#L111>
>
> -1 for removing wrappers/abbreviations/and such
> +1 for bugfixing
>
> Best,
> CC
>

Could you maybe elaborate a bit on your use case there? I.e. provide some
context as to why the create_function call there is necessary and why it
can't be replaced with use of anonymous functions (and maybe also what
additional constraints there are). For people like myself that are not
familiar with the exact workings of that library.

Thanks,
Nikita

---

## #69675 — Ferenc Kovacs — 2013-10-18T12:39:44+00:00

URL: https://externals.io/message/69554#69675 · In reply to: #69673

> On Fri, Oct 18, 2013 at 12:39 PM, Crypto Compress <
> cryptocompress@googlemail.com> wrote:
>
> > […]
> https://github.com/phpcr/phpcr-utils/blob/master/src/PHPCR/Util/Console/Helper/PhpcrCliHelper.php#L111
> > […]
>
> Could you maybe elaborate a bit on your use case there? I.e. provide some
> context as to why the create_function call there is necessary and why it
> can't be replaced with use of anonymous functions (and maybe also what
> additional constraints there are). For people like myself that are not
> familiar with the exact workings of that library.
>
> Thanks,
> Nikita
>

I guess he is trying to say that writing a factory method for producing
callable/anonymous functions are easier with create_function than with
closures, because you call eval implicitly, instead of explicitly.

I've only skimmed through the thread, but did somebody already proposed
changing the return value of create_function to return a closure instead of
deprecating it?
That way we could keep bc and remove the ugly null-prefixed hidden function
from the global function table.
If we really we want 100% compatibility, we could even add a __toString to
the Closure object with an internal function name (similar was proposed by
Joe for anonymous functions and I listed it as a con, because not matching
the current behaviors of Closures) through which it can be called as a
string while throwing a STRICT/DEPRECATED error so people can move away
from manipulating the return value as a string, and we can remove that
behavior later on.

-- 
Ferenc Kovács
@Tyr43l - http://tyrael.hu

---

## #69676 — Rowan Collins — 2013-10-18T12:41:54+00:00

URL: https://externals.io/message/69554#69676 · In reply to: #69663

> > […]
> Comparing a widely used feature, working well with something that
> never really worked (and why we have removed it) is hardly a good
> argument to remove create_function :-)

Absolutely, every proposal has to be evaluated on its merits, and that 
was just an example of a different situation where different conclusions 
were reached. But "it works" seems a little too superficial to me, and I 
wanted to tease out the details of this particular case.

To continue with the call-time pass-by-reference example, it was 
perfectly possible to write code which relied on that feature; it just 
wasn't a terribly good idea. In fact, I came upon this manual page the 
other day: http://php.net/debug_zval_dump The examples rely on the fact 
that the caller can decide whether something is passed by value or 
reference. In PHP >=5.4, that function is slightly more useless than it 
was before.

-- 
Rowan Collins
[IMSoP]

---

## #69678 — Rowan Collins — 2013-10-18T13:02:29+00:00

URL: https://externals.io/message/69554#69678 · In reply to: #69675

> I've only skimmed through the thread, but did somebody already proposed
> changing the return value of create_function to return a closure instead of
> deprecating it?

I mentioned it briefly in my initial post, but felt that unless BC was 
100%, it wasn't worth it, as you couldn't guarantee which of the current 
behaviour people were relying on.

People can always write a version in PHP which is good enough for their 
particular requirements.

> If we really we want 100% compatibility, we could even add a __toString to
> the Closure object with an internal function name (similar was proposed by
> Joe for anonymous functions and I listed it as a con, because not matching
> the current behaviors of Closures) through which it can be called as a
> string while throwing a STRICT/DEPRECATED error so people can move away
> from manipulating the return value as a string, and we can remove that
> behavior later on.

That's an interesting idea, although I'm not sure about adding a feature 
and immediately deprecating it. It seems like if closures had a 
__toString, people would start to use it, so we would have to assume 
that the feature was there to stay.

Another thought I had was to implement a safer version of 
create_function() under a different name, and provide a PHP-level 
implementation which ran under old versions for forwards-compatibility. 
You could, for instance, take an associative array of variables to close 
over, which would be equivalent to the use() statement if implementing 
on top of closures, and use `var_export()` to interpolate into a legacy 
create_function() implementation:

usort(
     $some_array,
     create_eval_closure(
// args, as name only; would lack of default value support be a problem?
         array('a', 'b'),

         // function body, as a static string
         'return strcasecmp($a[$key], $b[$key]);',

         // variables to "close over"
         array('key' => $key)
     )
);

Basically, it would be a bit like a parameterised SQL query: you can't 
actually prevent people interpolating into the strings anyway, but you 
can give them a safe mechanism that means they shouldn't need to.

-- 
Rowan Collins
[IMSoP]

---

## #69679 — Ryan McCue — 2013-10-18T13:26:16+00:00

URL: https://externals.io/message/69554#69679 · In reply to: #69665

Nikita Popov wrote:
> I tried to look on Github what people currently use create_function for,
> but with little success. Nearly all results I get are uses in the php
> testsuite (copied over to various projects). The only other use case I saw
> was in conjunction with the WordPress add_action() function. In this case
> the create_function call could always be replaced directly with an
> anonymous function (i.e. it didn't need any magic create_function
> capabilities).

I can say with confidence that if this gets in to PHP, we'll integrate
BC support as above (although probably some function name like
`_wp_anonymous_function_$i`), and the only real reason we still have
this is 5.2 support.

I suspect by the time 5.next rolls around, we'll be at least considering
dropping 5.2, but that of course depends on usage. At the very least,
the plugin ecosystem is starting to look towards dropping 5.2 support,
which is where the big issue will be anyway, so that's nice.

(FWIW, I always hated the create_function() calls in WordPress anyway.)

-- 
Ryan McCue
<http://ryanmccue.info/

---

## #69680 — Crypto Compress — 2013-10-18T13:37:50+00:00

URL: https://externals.io/message/69554#69680 · In reply to: #69675

> I guess he is trying to say that writing a factory method for 
> producing callable/anonymous functions are easier with create_function 
> than with closures, because you call eval implicitly, instead of 
> explicitly.
>

Exactly this historical "factory method" part is it. Thank You!

sort of documentation for the previous link:
https://github.com/phpcr/phpcr-utils/blob/master/src/PHPCR/Util/Console/Command/NodesUpdateCommand.php#L62
https://github.com/phpcr/phpcr-utils/blob/master/src/PHPCR/Util/Console/Helper/PhpcrCliHelper.php#L111

Not shure about a "safer version" with different name. Maybe breaking BC 
is acceptable to some degree, if touching and refactoring this to same 
codebase as closures.

---

Next page: https://externals.io/message/69554.md?page=2
