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

Search Discussions

  • Kris Craig at Oct 14, 2013 at 11:38 pm

    (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
  • Rowan Collins at Oct 15, 2013 at 3:47 pm

    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]
  • Johannes Schlüter at Oct 15, 2013 at 4:12 pm

    On Mon, 2013-10-14 at 22:33 +0100, Rowan Collins wrote:
    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
  • Rowan Collins at Oct 17, 2013 at 3:31 pm

    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]
  • Pierre Joye at Oct 17, 2013 at 3:47 pm

    On Thu, Oct 17, 2013 at 8:31 AM, Rowan Collins wrote:
    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.
    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
  • Rowan Collins at Oct 17, 2013 at 5:48 pm

    On 17/10/2013 16:47, Pierre Joye wrote:
    On Thu, Oct 17, 2013 at 8:31 AM, Rowan Collins wrote:
    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.
    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]
  • Pierre Joye at Oct 17, 2013 at 5:52 pm

    On Thu, Oct 17, 2013 at 10:48 AM, Rowan Collins wrote:
    On 17/10/2013 16:47, Pierre Joye wrote:

    On Thu, Oct 17, 2013 at 8:31 AM, Rowan Collins <rowan.collins@gmail.com>
    wrote:
    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.

    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
  • Rowan Collins at Oct 17, 2013 at 6:25 pm

    On 17/10/2013 18:52, Pierre Joye wrote:
    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.
    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]
  • Pierre Joye at Oct 17, 2013 at 7:29 pm

    On Thu, Oct 17, 2013 at 11:24 AM, Rowan Collins wrote:
    On 17/10/2013 18:52, Pierre Joye wrote:

    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.

    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
  • Rowan Collins at Oct 17, 2013 at 9:22 pm

    On 17/10/2013 20:29, Pierre Joye wrote:
    On Thu, Oct 17, 2013 at 11:24 AM, Rowan Collins wrote:
    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.
    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]
  • Pierre Joye at Oct 18, 2013 at 5:25 am

    On Thu, Oct 17, 2013 at 2:22 PM, Rowan Collins wrote:
    On 17/10/2013 20:29, Pierre Joye wrote:

    On Thu, Oct 17, 2013 at 11:24 AM, Rowan Collins <rowan.collins@gmail.com>
    wrote:
    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.

    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
  • Rowan Collins at Oct 18, 2013 at 12:42 pm

    On 18/10/2013 06:25, Pierre Joye wrote:
    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 :-)
    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]
  • Marc Bennewitz at Oct 17, 2013 at 7:23 pm

    Am 17.10.2013 17:47, schrieb Pierre Joye:
    On Thu, Oct 17, 2013 at 8:31 AM, Rowan Collins wrote:
    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.
    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.
    Please note that there are open bugs with "create_function" the should
    than be fixed including memory issue.
    Cheers,
  • Pierre Joye at Oct 17, 2013 at 11:20 am

    On Mon, Oct 14, 2013 at 11:33 PM, Rowan Collins wrote:

    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
  • Marcel Araujo at Oct 17, 2013 at 1:00 pm
    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**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,

    --
    Rowan Collins
    [IMSoP]
  • Nikita Popov at Oct 18, 2013 at 9:26 am

    On Mon, Oct 14, 2013 at 11:33 PM, Rowan Collins 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
  • Crypto Compress at Oct 18, 2013 at 10:40 am

    Am 18.10.2013 11:26, schrieb Nikita Popov:
    On Mon, Oct 14, 2013 at 11:33 PM, Rowan Collins 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
    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
  • Alexey Zakhlestin at Oct 18, 2013 at 10:51 am

    On 18.10.2013, at 14:39, Crypto Compress wrote:

    Am 18.10.2013 11:26, schrieb Nikita Popov:
    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).
    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.
  • Crypto Compress at Oct 18, 2013 at 10:58 am

    Am 18.10.2013 12:51, schrieb Alexey Zakhlestin:
    On 18.10.2013, at 14:39, Crypto Compress wrote:

    Am 18.10.2013 11:26, schrieb Nikita Popov:
    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).
    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.
    It is possible to write most of the array functions in plain php with a
    trivial foreach. Can't see the point.
  • Sebastian Krebs at Oct 18, 2013 at 11:06 am
    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**>
    wrote:

    Am 18.10.2013 11:26, schrieb Nikita Popov:
    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).
    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 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.
    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.



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

    --
    github.com/KingCrunch
  • Nikita Popov at Oct 18, 2013 at 12:19 pm

    On Fri, Oct 18, 2013 at 12:39 PM, Crypto Compress 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
  • Ferenc Kovacs at Oct 18, 2013 at 12:39 pm

    On Fri, Oct 18, 2013 at 2:19 PM, Nikita Popov wrote:

    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
    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
  • Rowan Collins at Oct 18, 2013 at 1:02 pm

    On 18/10/2013 13:39, Ferenc Kovacs wrote:
    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]
  • Crypto Compress at Oct 18, 2013 at 1:37 pm

    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.
  • Ryan McCue at Oct 18, 2013 at 1:26 pm

    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.)
  • Rowan Collins at Oct 18, 2013 at 1:55 pm

    On 18/10/2013 14:26, Ryan McCue wrote:
    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.)
    That's interesting to hear - I have no knowledge of the Wordpress
    community and decision-making apparatus, so wasn't sure what the
    reaction would be. While digging around for references, I did find this
    ticket about removing a lot of the create_functions from core:
    http://core.trac.wordpress.org/ticket/14424

    The usages I did find in the core code were what inspired my idea for a
    wrapper that took a list of variables to "close over" (like a use()
    clause without the extra syntax) and used var_export() to inject them
    into the function body, as that is the pattern used in a few places.

    The other interesting case I spotted was creating a function which
    always returned the same string (an SQL LIMIT clause), so that it could
    be registered as a filter callback. That could use an even simpler
    BC-wrapper, which wouldn't need any eval() at all in >=5.3 (as long as
    code was arranged such that older versions didn't try to compile it):

    function lambda($return_value)
    {
          return function() use($return_value) { return $return_value; };
    }


    A fallback definition for <=5.2 would have a single var_export:


    function lambda($return_value)
    {
          return create_function('', 'return ' . var_export($return_value,
    true) . ';');
    }

    --
    Rowan Collins
    [IMSoP]
  • Ryan McCue at Oct 18, 2013 at 2:02 pm

    Rowan Collins wrote:
    That's interesting to hear - I have no knowledge of the Wordpress
    community and decision-making apparatus, so wasn't sure what the
    reaction would be. While digging around for references, I did find this
    ticket about removing a lot of the create_functions from core:
    http://core.trac.wordpress.org/ticket/14424

    For context, one of the big uses was returning static values, like
    true/false/etc. We now have __return_false()/__return_empty_array()/etc
    for those uses.

    We also discourage it from being used for callbacks, as the
    runtime-generated-naming means it's impossible to later remove it
    without a variable reference to the name (ditto for closures, but people
    typically only use those in development, not production).

    There's only one place I can think of in the plugin community where it's
    still used a fair bit (widget registration), but we can work on
    discouraging that and there's a fair amount of time until the next
    release in any case.

    Personal +1 on this.
  • Rowan Collins at Oct 18, 2013 at 2:14 pm

    On 18/10/2013 15:02, Ryan McCue wrote:
    There's only one place I can think of in the plugin community where it's
    still used a fair bit (widget registration), but we can work on
    discouraging that and there's a fair amount of time until the next
    release in any case.
    Don't forget we're only talking about deprecating, not removing it
    immediately, so discouraging usage rather than eliminating it is very
    much to the point.

    The absolute earliest this would actually be removed would be in 5.7,
    sometime in 2015. In fact, deprecating now but not expecting removal to
    be possible until 5.8 / 2016 seems reasonable to me.

    (Above assumes the current release sequence continues, and PHP 6 isn't
    revived or something.)

    --
    Rowan Collins
    [IMSoP]
  • Pierre Joye at Oct 18, 2013 at 2:16 pm

    On Fri, Oct 18, 2013 at 7:13 AM, Rowan Collins wrote:
    On 18/10/2013 15:02, Ryan McCue wrote:

    There's only one place I can think of in the plugin community where it's
    still used a fair bit (widget registration), but we can work on
    discouraging that and there's a fair amount of time until the next
    release in any case.

    Don't forget we're only talking about deprecating, not removing it
    immediately, so discouraging usage rather than eliminating it is very much
    to the point.

    The absolute earliest this would actually be removed would be in 5.7,
    sometime in 2015. In fact, deprecating now but not expecting removal to be
    possible until 5.8 / 2016 seems reasonable to me.
    I don't think we can ever remove it in 5.x.

    --
    Pierre

    @pierrejoye | http://www.libgd.org
  • Rowan Collins at Oct 18, 2013 at 2:38 pm

    On 18/10/2013 15:16, Pierre Joye wrote:
    On Fri, Oct 18, 2013 at 7:13 AM, Rowan Collins wrote:
    The absolute earliest this would actually be removed would be in 5.7,
    sometime in 2015. In fact, deprecating now but not expecting removal to be
    possible until 5.8 / 2016 seems reasonable to me.
    I don't think we can ever remove it in 5.x.
    Is there a particular rule that separates the kind of BC breaks that are
    possible between 5.x releases vs those which would require bumping the
    major version? It is absolutely not the case that a program written for
    PHP 5.0 can be guaranteed to run under PHP 5.5 without modification.

    I thought PHP version numbers couldn't really be considered semantic
    like that, ever since PHP 6 was abandoned, and major language features
    from it were dropped into PHP 5.3 and 5.4. The current release policy
    could plausibly continue indefinitely, with a 5.13 in 2021; "never" is a
    long time...

    --
    Rowan Collins
    [IMSoP]
  • Ferenc Kovacs at Oct 18, 2013 at 2:51 pm

    On Fri, Oct 18, 2013 at 4:38 PM, Rowan Collins wrote:
    On 18/10/2013 15:16, Pierre Joye wrote:

    On Fri, Oct 18, 2013 at 7:13 AM, Rowan Collins <rowan.collins@gmail.com>
    wrote:
    The absolute earliest this would actually be removed would be in 5.7,
    sometime in 2015. In fact, deprecating now but not expecting removal to
    be
    possible until 5.8 / 2016 seems reasonable to me.
    I don't think we can ever remove it in 5.x.
    Is there a particular rule that separates the kind of BC breaks that are
    possible between 5.x releases vs those which would require bumping the
    major version? It is absolutely not the case that a program written for PHP
    5.0 can be guaranteed to run under PHP 5.5 without modification.

    I thought PHP version numbers couldn't really be considered semantic like
    that, ever since PHP 6 was abandoned, and major language features from it
    were dropped into PHP 5.3 and 5.4. The current release policy could
    plausibly continue indefinitely, with a 5.13 in 2021; "never" is a long
    time...
    shouldn't really happen if you strictly follow the "new" release process
    rfc was accepted: https://wiki.php.net/rfc/releaseprocess , unfortunatelly
    it seems that there are some cases, when this can happen (some bug fixes,
    but the biggest offender was dropping deprecated features for 5.4.0 which
    were already removed in the 6.0 branch), but if you check out
    http://hu1.php.net/manual/en/migration55.incompatible.php you can see that
    the actual intentional BC breaks was really small, the only non bugfix BC
    break was removing the php logo urls, which was never meant to be a public
    api, but to be used by phpinfo().

    --
    Ferenc Kovács
    @Tyr43l - http://tyrael.hu
  • Rowan Collins at Oct 18, 2013 at 4:03 pm

    On 18/10/2013 15:51, Ferenc Kovacs wrote:
    shouldn't really happen if you strictly follow the "new" release
    process rfc was accepted: https://wiki.php.net/rfc/releaseprocess ,
    unfortunatelly it seems that there are some cases, when this can
    happen (some bug fixes, but the biggest offender was dropping
    deprecated features for 5.4.0 which were already removed in the 6.0
    branch), but if you check out
    http://hu1.php.net/manual/en/migration55.incompatible.php you can see
    that the actual intentional BC breaks was really small, the only non
    bugfix BC break was removing the php logo urls, which was never meant
    to be a public api, but to be used by phpinfo().
    Ah, I see. I guess it was the slew of changes in 5.3 and 5.4 which made
    it seem like this wasn't the case, because they would collectively have
    been 6.0. So the aim is that a script made to work on PHP 5.4 will now
    be guaranteed to run on any version <6, although some required modules
    might have moved to PECL?

    As a user, it is certainly not obvious that features discussed as being
    removed "soon" will only actually disappear once there is a 6.0, because
    there doesn't seem to be any reason to expect PHP 6 to be "soon". Unless
    a release within the next few years is numbered 6.0 (or something else
    5) simply to clean up the deprecated functionality, without actually
    including major changes like the Unicode string concept.

    --
    Rowan Collins
    [IMSoP]

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedOct 14, '13 at 9:33p
activeOct 18, '13 at 4:03p
posts33
users12
websitephp.net

People

Translate

site design / logo © 2022 Grokbase