[RFC] Deprecations for PHP 7.1

php.internals

Nikita Popov

10 years ago
Hi internals! I've created a bulk-deprecation RFC for PHP 7.1: https://wiki.php.net/rfc/deprecations_php_7_1 I'm using this RFC to collect various deprecations targeting PHP 7.1, as having individual RFCs for these is too much management overhead. Each deprecated feature will get its own vote, of course. This RFC is incomplete -- I'm posting it now so people can suggest other things that should be deprecated. I expect it to grow over time and don't plan to vote on it in the immediate future. Thanks, Nikita

Zeev Suraski

10 years ago
> -----Original Message----- > From: Nikita Popov [mailto:nikita.ppv@gmail.com] > Sent: Thursday, February 18, 2016 2:42 PM > To: PHP internals <internals@lists.php.net> > Subject: [PHP-DEV] [RFC] Deprecations for PHP 7.1 > > Hi internals! > > I've created a bulk-deprecation RFC for PHP 7.1: > https://wiki.php.net/rfc/deprecations_php_7_1 > > I'm using this RFC to collect various deprecations targeting PHP 7.1, as having > individual RFCs for these is too much management overhead. Each deprecated > feature will get its own vote, of course. > > This RFC is incomplete -- I'm posting it now so people can suggest other things > that should be deprecated. I expect it to grow over time and don't plan to vote > on it in the immediate future.
How do you envision discussing each of those though? Should we discuss each proposal as it becomes available? Zeev

Unnamed Person

10 years ago
Nikita Popov wrote on 18.02.2016 13:41:
> Hi internals! > > I've created a bulk-deprecation RFC for PHP 7.1: > https://wiki.php.net/rfc/deprecations_php_7_1 > > I'm using this RFC to collect various deprecations targeting PHP 7.1, as > having individual RFCs for these is too much management overhead. Each > deprecated feature will get its own vote, of course. > > This RFC is incomplete -- I'm posting it now so people can suggest other > things that should be deprecated. I expect it to grow over time and don't > plan to vote on it in the immediate future. > > Thanks, > Nikita >
I'm proposing: allow_url_include Regards Thomas

Andrew Faulds

10 years ago
Hi Nikita, Nikita Popov wrote:
> I've created a bulk-deprecation RFC for PHP 7.1: > https://wiki.php.net/rfc/deprecations_php_7_1
I'd be fine with getting rid of all of the ones suggested so far (__autoload, $php_errormsg, create_function, rand/srand). I've actually used create_function on occasion for programmatically generating functions (in particular to create a function for each PHP operator), but it's trivially polyfillable, and it'd be better if people were implementing it themselves (and thus knowing it's based on eval()) than using it directly without this knowledge. Regarding rand() and srand(), I'm fine with getting rid of them. Note that we should also deprecate getrandmax() at the same time, though. It's the function which returns the C RAND_MAX constant.
> I'm using this RFC to collect various deprecations targeting PHP 7.1, as > having individual RFCs for these is too much management overhead. Each > deprecated feature will get its own vote, of course. > > This RFC is incomplete -- I'm posting it now so people can suggest other > things that should be deprecated. I expect it to grow over time and don't > plan to vote on it in the immediate future.
Hmm. Well, if we're doing mass deprecations, maybe we should finally get rid of hebrev() and hebrevc()? It feels out-of-place to have a poorly-documented standard library function specifically for converting between two different legacy 8-bit encodings used for Hebrew, especially when one of them is just the other with nl2br() included! Users who need to convert between different variants of ISO-8859-8 can use iconv() instead, or perhaps use a userland polyfill of hebrev/c(). That said, hebrev/c() might be used a lot in legacy code, and there's probably little harm in keeping it. Similarly, we have utf8_decode() and utf8_encode() for converting between ISO-8859-1 and UTF-8, which could also be replaced with iconv(), but they're probably heavily used. Even if we don't get rid of or deprecate any of those functions, they should probably be moved into a more appropriate section of ext/ and the manual. Thanks!
-- Andrea Faulds https://ajf.me/

Fleshgrinder

10 years ago
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 On 2/18/2016 8:57 PM, Andrea Faulds wrote:
> > Nikita Popov wrote: >> https://wiki.php.net/rfc/deprecations_php_7_1 > > I've actually used create_function on occasion for > programmatically generating functions (in particular to create a > function for each PHP operator), but it's trivially polyfillable, > and it'd be better if people were implementing it themselves (and > thus knowing it's based on eval()) than using it directly without > this knowledge. > > Regarding rand() and srand(), I'm fine with getting rid of them. > Note that we should also deprecate getrandmax() at the same time, > though. It's the function which returns the C RAND_MAX constant. > > Hmm. Well, if we're doing mass deprecations, maybe we should > finally get rid of hebrev() and hebrevc()? It feels out-of-place to > have a poorly-documented standard library function specifically for > converting between two different legacy 8-bit encodings used for > Hebrew, especially when one of them is just the other with nl2br() > included! Users who need to convert between different variants of > ISO-8859-8 can use iconv() instead, or perhaps use a userland > polyfill of hebrev/c(). > > That said, hebrev/c() might be used a lot in legacy code, and > there's probably little harm in keeping it. Similarly, we have > utf8_decode() and utf8_encode() for converting between ISO-8859-1 > and UTF-8, which could also be replaced with iconv(), but they're > probably heavily used. > > Even if we don't get rid of or deprecate any of those functions, > they should probably be moved into a more appropriate section of > ext/ and the manual. > > Thanks! >
+1 for all that are in the RFC and I would like to second Andrea’s proposals. All of them including utf8_encode() and utf8_decode(). Those two are used incorrectly in most cases I encounter them. People seem to assume that they are able to encode anything to proper UTF-8 when calling utf8_encode(). There are more questionable string functions available: - - quotemeta() -- bad function name and purpose is unclear. - - convert_cyr_string() -- iconv() again ... Candidates for moving to appropriate section of ext/ (or PECL) since they are all kind of special and nothing a *normal* program would ever need. Especially since they target English only and there are much better algorithms and tools available to work with such use cases. - - levenshtein() - - metaphone() - - similar_text() - - soundex() - -- Richard "Fleshgrinder" Fussenegger -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJWxioTAAoJEOKkKcqFPVVrE8oQAL4GmeeBFGTBiE90sYutyljz hkAZEKBkFVnSK1Ta92DB4+3mWYYtce7C6th9QsqXP871+XAQ92E69YTjP0GrcAm+ Q62kHWzhtDwsN1cePz3DVfuiuNZ0d2mGWoW4ak1azMhWbQGjx+c7nEiugmWOzsRO WjSJrd2SoZClSy/yGhmqs/5OFdj3hlnI4KX0xsM4A03I+reKqZc3VOWyZFXOqjBK VK+Bj8G8hz5bNYk3WFXr2NNA8/r4FAOdOZS4CSsfHTbux/8szqbz2dB2V7oUU9FV 8Z5tpPNPe37GyLjcxvlqcM8QGVjwc3zbxoFK2Jfz6UlnRQxDqH/6XRqNMQF1JslS 7FS8jc57SaUb/9tcg+XwOOkH6yoc30JXjq1BBR0SuNGCB1HDG4vcvWIus2YcI0xO hhPmp/8Rqujv0ybhuikPBdM1XK5E/3dk+G9xsE2sXNWRYbaeu1moahm52RUWnoFx YNAHeYIsA3M1LSncFwiTop6ouqmAAN55wo1rGfocilrwo4lPBF0F6TP8LEeT55vb AwS70sp/gVfyoTN3MEzubn5XZ3jKft82ZEWIdEBwGs7L3BctE2ubCDozrOBqes9W sVcj2zhQV636BC8UbKx0x+5PzlGFDX7xayWvP1J8aks+Th35G7WkU4gb5ajLLXOa W2sMr3dl5EzfgKVLI6+n =Ip+5 -----END PGP SIGNATURE-----

Zeev Suraski

10 years ago
> On 18 בפבר? 2016, at 21:58, Andrea Faulds <ajf@ajf.me> wrote: > > > Hmm. Well, if we're doing mass deprecations, maybe we should finally get rid of hebrev() and hebrevc()? It feels out-of-place to have a poorly-documented standard library function specifically for converting between two different legacy 8-bit encodings used for Hebrew, especially when one of them is just the other with nl2br() included! Users who need to convert between different variants of ISO-8859-8 can use iconv() instead, or perhaps use a userland polyfill of hebrev/c().
I'm not aware that you can use iconv to convert visual to logical Hebrew or vice versa. Not saying you can't, just that I'm not aware it does - I don't think it support visual encodings at all. Do you know how to convert between them using iconv? If you do, I'm fine reimplementing these functions using iconv, again, if we can eliminate the pointless upgrade hassle. The other alternative of a userland version isn't that simple to write, would be slower, and most importantly buys us nothing. I'm guessing that hebrevc() predates nl2br() (could be wrong), but regardless, I wouldn't touch it as there's zero gain to be had. Last - we're not or at least shouldn't be doing mass deprecations. There should be an extremely strong reason to break perfectly good code. Zeev

Stas Malyshev

10 years ago
Hi!
>> Hmm. Well, if we're doing mass deprecations, maybe we should finally get rid of
I must note that I think this drive to "get rid of" functions that does not stand in anybody's way (as opposed to the case of __autoload which is incompatible with superior stackable autoloader solution) is deeply misguided. Yes, there are functions that are very niche and maybe not a lot of people use them. But the advantage of PHP was always to try and serve a lot of needs and be a versatile pragmatic instrument, even at the expense of theoretical purity. I do not think we should abandon this approach. If there is a conceivable use case where this function can be useful, and it does not impede progress or prevent implementation of better features - IMO there's no reason at all to remove it. It's better to have a hundred of functions and have 10 year old code running perfectly in modern version than to have new squeaky clean API than has no code to run because 100% of existing code can not use this version (and thus even if people wanted to use clean API in new code they can't because old one does not work).
-- Stas Malyshev smalyshev@gmail.com

Andrew Faulds

10 years ago
Hi Zeev, Zeev Suraski wrote:
> >> On 18 בפבר? 2016, at 21:58, Andrea Faulds <ajf@ajf.me> wrote: >> >> >> Hmm. Well, if we're doing mass deprecations, maybe we should finally get rid of hebrev() and hebrevc()? It feels out-of-place to have a poorly-documented standard library function specifically for converting between two different legacy 8-bit encodings used for Hebrew, especially when one of them is just the other with nl2br() included! Users who need to convert between different variants of ISO-8859-8 can use iconv() instead, or perhaps use a userland polyfill of hebrev/c(). > > I'm not aware that you can use iconv to convert visual to logical Hebrew or vice versa. Not saying you can't, just that I'm not aware it does - I don't think it support visual encodings at all. Do you know how to convert between them using iconv? If you do, I'm fine reimplementing these functions using iconv, again, if we can eliminate the pointless upgrade hassle. The other alternative of a userland version isn't that simple to write, would be slower, and most importantly buys us nothing.
Looking into it, iconv() doesn't seem to support converting between ISO-8859-8 and ISO-8859-8-I, at least on my system. Nor can mb_convert_encoding(). Both only support ISO-8859-8. I should have researched this before. hebrev() isn't redundant, then, sorry about that.
> I'm guessing that hebrevc() predates nl2br() (could be wrong), but regardless, I wouldn't touch it as there's zero gain to be had.
Ah, that might explain the difference.
> Last - we're not or at least shouldn't be doing mass deprecations. There should be an extremely strong reason to break perfectly good code.
Yeah, I'd be cautious about removing any of these. I do think these functions should be moved in the manual (and possibly source), though. Thanks for your input.
-- Andrea Faulds https://ajf.me/

Johannes Schlueter

10 years ago
On Thu, 2016-02-18 at 19:57 +0000, Andrea Faulds wrote:
> I've actually used create_function on occasion for programmatically > generating functions (in particular to create a function for each PHP > operator), but it's trivially polyfillable, and it'd be better if > people > were implementing it themselves (and thus knowing it's based on > eval()) > than using it directly without this knowledge.
Just as a detail: You can't create a 100% compatible polyfill to create_function(). create_function() names functions starting with \0. Functions starting with \0 are hidden from get_defined_functions() and possibly other places. php > echo sizeof(get_defined_functions()['user']); 0 php > create_function('', ''); php > echo sizeof(get_defined_functions()['user']); 0 php > eval('function foo() {}'); php > echo sizeof(get_defined_functions()['user']); 1 johannes

Stephen Coakley

10 years ago
On 03/04/2016 07:53 AM, Johannes Schlüter wrote:
> On Thu, 2016-02-18 at 19:57 +0000, Andrea Faulds wrote: >> I've actually used create_function on occasion for programmatically >> generating functions (in particular to create a function for each PHP >> operator), but it's trivially polyfillable, and it'd be better if >> people >> were implementing it themselves (and thus knowing it's based on >> eval()) >> than using it directly without this knowledge. > > Just as a detail: You can't create a 100% compatible polyfill to > create_function(). create_function() names functions starting with \0. > Functions starting with \0 are hidden from get_defined_functions() and > possibly other places. > > php > echo sizeof(get_defined_functions()['user']); > 0 > php > create_function('', ''); > php > echo sizeof(get_defined_functions()['user']); > 0 > php > eval('function foo() {}'); > php > echo sizeof(get_defined_functions()['user']); > 1 > > johannes >
Good point. Another approach to a polyfill would be to use a closure then: function create_function(string $args, string $code) { return eval("return function($args) { $code };"); } $newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);'); echo $newfunc(2, M_E) . "\n"; Not a complete polyfill, since $newfunc is a closure and not a string, so you cannot print out the function name. I have no idea if any code relies on the lambda itself being a string though.
-- Stephen

Johannes Schlueter

10 years ago
On Fri, 2016-03-04 at 12:29 -0600, Stephen Coakley wrote:
> Not a complete polyfill, since $newfunc is a closure and not a string, > so you cannot print out the function name. I have no idea if any code > relies on the lambda itself being a string though.
This has impact on a few things, i.e. Reflection or users might guess the name. Anyways: Take away: A polyfill won't be 100% identical. However the typical use case should be around usort() or similar where this doesn't matter. johannes

Stephen Coakley

10 years ago
On 03/04/2016 03:49 PM, Johannes Schlüter wrote:
> On Fri, 2016-03-04 at 12:29 -0600, Stephen Coakley wrote: >> Not a complete polyfill, since $newfunc is a closure and not a string, >> so you cannot print out the function name. I have no idea if any code >> relies on the lambda itself being a string though. > > This has impact on a few things, i.e. Reflection or users might guess > the name. Anyways: Take away: A polyfill won't be 100% identical. > > However the typical use case should be around usort() or similar where > this doesn't matter. > > johannes >
I'm not entirely sure about what you mean. On my system, create_function returns something like '\x00lambda_1'. Do you mean that users are guessing such a string in order to use it? Sounds like the smelliest of code smells.
-- Stephen

Johannes Schlueter

10 years ago
On Fri, 2016-03-04 at 21:50 -0600, Stephen Coakley wrote:
> Sounds like the smelliest of > code smells.
Considering what I've seen (and in some cases done myself to outsmart my later self) I wouldn't be surprised if some did. :-) We can't imagine all the creativity of PHP users, johannes

Rowan Collins

10 years ago
On 05/03/2016 03:50, Stephen Coakley wrote:
> I'm not entirely sure about what you mean. On my system, > create_function returns something like '\x00lambda_1'. Do you mean > that users are guessing such a string in order to use it? Sounds like > the smelliest of code smells.
Maybe not constructing it, but detecting it? I'm not sure why you'd *need* to tell the difference between a create_function "lambda" and a Closure instance, but somebody somehwere might have hacked it in. Regards,
-- Rowan Collins [IMSoP]

Stas Malyshev

10 years ago
Hi!
> I've created a bulk-deprecation RFC for PHP 7.1: > https://wiki.php.net/rfc/deprecations_php_7_1 >
I like dropping php_errormsg. Last time I tried to make error suppression work more efficiently this was a major problematic thing AFAIR, and in general using magic variables that pop out of nowhere is not a good thing. For __autoload I guess since it's incompatible with superior SPL mechanism it has to go too. I'm not sure about create_function() - while it is old, I don't see why we should break working code using it just because better option is available. With rand functions, I don't think we need to touch them. For some applications, low-key randomness is just fine - if you need to shuffle array of 20 elements or randomize unit test to ensure you're not testing same value all the time, low-quality randomness is completely fine. For other applications, there are superior solutions and everybody who needs them already uses them, but again I see no value in removing those functions. It would only cause more breakage and make adoption of new versions (already horrible) even slower.
-- Stas Malyshev smalyshev@gmail.com

Zeev Suraski

10 years ago
> On 18 בפבר? 2016, at 23:42, Stanislav Malyshev <smalyshev@gmail.com> wrote: > > Hi! > >> I've created a bulk-deprecation RFC for PHP 7.1: >> https://wiki.php.net/rfc/deprecations_php_7_1 > > I like dropping php_errormsg. Last time I tried to make error > suppression work more efficiently this was a major problematic thing > AFAIR, and in general using magic variables that pop out of nowhere is > not a good thing.
I think we need to try and get an idea for the popularity of it before deprecating it, as well as get an idea for what kind of performance benefits it would bring (price/performance for making this change).
> For __autoload I guess since it's incompatible with superior SPL > mechanism it has to go too.
Agreed.
> I'm not sure about create_function() - while it is old, I don't see why > we should break working code using it just because better option is > available.
There's that, and there's the fact closures don't give you the same functionality - as Andrea pointed out. I think deprecating it and forcing people to rewrite their code differently (either with eval or with closures) doesn't make a whole lot of sense when create_function() works perfectly well. In terms of security risks, if you use it like you use closures I don't think it's any riskier. If you need eval() for programmatically creating functions - it would obviously be at the exact same risk levels. So we're left with marginal performance gains - as practically speaking you don't typically create thousands of functions dynamically in a given request. If you do, chances are you've already migrated to closures.
> > With rand functions, I don't think we need to touch them. For some > applications, low-key randomness is just fine - if you need to shuffle > array of 20 elements or randomize unit test to ensure you're not testing > same value all the time, low-quality randomness is completely fine. For > other applications, there are superior solutions and everybody who needs > them already uses them, but again I see no value in removing those > functions. It would only cause more breakage and make adoption of new > versions (already horrible) even slower.
I think the obvious option here is to make rand() and srand() aliases to rand_mt() and srand_mt(), unless I'm missing something very basic, unless I'm missing something very basic here..? I see zero reason to deprecate them and break so much code when we can simply 'upgrade' them at zero cost to both us and users. I think that this is something we should try to do in general, by the way. Deprecating is easy, upgrading is not - and we should strive to minimize code breaks as much as possible. If we can reimplement an old functionality in a new and better and seamlessly provide a painless upgrade experience we should always prefer it to forcing the users to edit their code. Zeev

Nikita Popov

10 years ago
On Thu, Feb 18, 2016 at 11:45 PM, Zeev Suraski <zeev@zend.com> wrote:
> > With rand functions, I don't think we need to touch them. For some > > applications, low-key randomness is just fine - if you need to shuffle > > array of 20 elements or randomize unit test to ensure you're not testing > > same value all the time, low-quality randomness is completely fine. For > > other applications, there are superior solutions and everybody who needs > > them already uses them, but again I see no value in removing those > > functions. It would only cause more breakage and make adoption of new > > versions (already horrible) even slower. > > I think the obvious option here is to make rand() and srand() aliases to > rand_mt() and srand_mt(), unless I'm missing something very basic, unless > I'm missing something very basic here..? I see zero reason to deprecate > them and break so much code when we can simply 'upgrade' them at zero cost > to both us and users. >
The usual argument against aliasing rand() to mt_rand() is that it will change the sequence that is generated for a specific srand() seed, thus breaking code that relies on specific sequences. However, as removing the functions in the future would break the code anyway, I think I agree with you that just aliasing them is a better option. We may need to discuss our non-cryptographic PRNG functionality anyway, there's quite a number of issues: * rand(), the first function anyone will try, uses a potentially horrible libc RNG * It was recently noticed that the mt_rand() implementation contains a typo and our output differs from the original well-researched algorithm. As yet it is unclear what that typo does to the quality of the output. * mt_getrandmax() is 2^31-1 even on 64-bit machines and numbers are scaled using floating point multiplication. That means if you tell mt_rand() to generate a 64-bit random numbers by specifying the range, only a tiny fraction of numbers can actually be hit. I also strongly suspect that the floating point scaling is inherently non-uniform even for smaller ranges. * Functions like array_rand() or shuffle() use rand() and not mt_rand(), so if you're on Windows and your array is larger than some 30k elements the output will likely be severely biased. * The array_rand() implementation is O(N) even if you only choose a single key (likely by far the most common case). If you use array_rand() on a 1M element array, we'll generate 0.5M random numbers on average. Even though changing our PRNG implementations will break seed sequences, I think the time has come to clean up this mess for 7.1. (We might also want to consider to alias rand and mt_rand to an entirely new algorithm, not MT19937. Nowadays PRNGs are available that have both better statistical properties and are faster than MT.) On a different note, I don't think that philosophical discussions on the topic of how much we ought to be deprecating will be very productive -- this is one of those topics people tend to be very stubborn about ;) Some people value stability above everything else, and for others the number one evil in PHP is our reluctance to get rid of old ---crap--- cruft. It would be nice if we could let voting decide that question, and keep this thread focused on specific issues and suggestion. I.e. on one hand suggestions for things that we may want to deprecate, together with reasoning for why we should do it. And on the other hand alternatives to deprecation (your suggestion for rand), reasons why something shouldn't be deprecated (e.g. functionality not otherwise available, see hebrev; or migration would be problematic because XYZ; or project ABC uses this heavily because ...) Thanks, Nikita

Andrew Faulds

10 years ago
Hi Nikita, Nikita Popov wrote:
> On Thu, Feb 18, 2016 at 11:45 PM, Zeev Suraski <zeev@zend.com> wrote: > > * rand(), the first function anyone will try, uses a potentially horrible > libc RNG
The manual could really be better here. It mentions that rand()'s maximum output might be quite small on platforms like Windows, whereas it ought to recommend mt_rand() in most cases.
> * It was recently noticed that the mt_rand() implementation contains a > typo and our output differs from the original well-researched algorithm. As > yet it is unclear what that typo does to the quality of the output.
I'm not a statistician, so take what I say with a grain of salt. But from an amateur analysis, it seems to have fairly uniform output: https://www.reddit.com/r/lolphp/comments/46fxi8/typofixing_commit_in_mersenne_twister_rng_code_is/d0552tb
> * mt_getrandmax() is 2^31-1 even on 64-bit machines and numbers are scaled > using floating point multiplication. That means if you tell mt_rand() to > generate a 64-bit random numbers by specifying the range, only a tiny > fraction of numbers can actually be hit. I also strongly suspect that the > floating point scaling is inherently non-uniform even for smaller ranges.
Perhaps we could produce an E_NOTICE if you give a range that's too large?
> * Functions like array_rand() or shuffle() use rand() and not mt_rand(), > so if you're on Windows and your array is larger than some 30k elements the > output will likely be severely biased.
If we fix this, we should do it at the same time as we fix mt_rand()'s typo, since both could potentially break code (realistically just unit tests) relying on deterministic output.
> Even though changing our PRNG implementations will break seed sequences, I > think the time has come to clean up this mess for 7.1. (We might also want > to consider to alias rand and mt_rand to an entirely new algorithm, not > MT19937. Nowadays PRNGs are available that have both better statistical > properties and are faster than MT.)
If we did that, we could change it to always use a 64-bit value internally (including on 32-bit systems through emulation). That way some of our scaling woes would disappear.
> On a different note, I don't think that philosophical discussions on the > topic of how much we ought to be deprecating will be very productive -- > this is one of those topics people tend to be very stubborn about ;) Some > people value stability above everything else, and for others the number one > evil in PHP is our reluctance to get rid of old ---crap--- cruft. It would > be nice if we could let voting decide that question, and keep this thread > focused on specific issues and suggestion. I.e. on one hand suggestions for > things that we may want to deprecate, together with reasoning for why we > should do it.
I do think we should at least have a good case made for deprecating each item. If something is merely a redundant alias or not very useful, then there's not much case for getting rid of it, because there's little benefit and the large disadvantage of breaking existing code. On the other hand, if it's harmful in some way, then there's a greater case for deprecation. Thanks!
-- Andrea Faulds https://ajf.me/

Rowan Collins

10 years ago
On 18/02/2016 22:45, Zeev Suraski wrote:
>> I'm not sure about create_function() - while it is old, I don't see why >> we should break working code using it just because better option is >> available.
> There's that, and there's the fact closures don't give you the same
functionality - as Andrea pointed out. I think
> deprecating it and forcing people to rewrite their code differently
(either with eval or with closures) doesn't make
> a whole lot of sense when create_function() works perfectly well. In
terms of security risks, if you use it like you
> use closures I don't think it's any riskier. If you need eval() for
programmatically creating functions - it would obviously
> be at the exact same risk levels. So we're left with marginal
performance gains - as practically speaking you don't
> typically create thousands of functions dynamically in a given
request. If you do, chances are you've already
> migrated to closures.
Funnily enough, one of my first contributions to this list was to propose deprecating create_function: http://marc.info/?l=php-internals&m=138178645724006&w=2 The answers to my proposal were mixed, as they have been here: some agreed that it was ugly and a potential security problem if misused; some pointed out use cases which can't trivially be implemented with Closures, such as this: https://github.com/phpcr/phpcr-utils/blob/42db960a6c58dcc3a71c2e4770050cda36f17c5b/src/PHPCR/Util/Console/Command/NodesUpdateCommand.php#L68 In the end I dropped the idea on the grounds that a deprecation notice should have a clear migration path for all reasonable use cases, not just some of them. I tend to agree with Stas that deprecations need to be justified more strongly than a general desire for tidiness. As with "can we rename functions / fix argument order / etc", I wonder if there's scope for publishing an FAQ which, while not holding the force of Official Policy, is nonetheless endorsed as consensus to guide new contributions... Regards,
-- Rowan Collins [IMSoP]

Stephen Coakley

10 years ago
On 02/18/2016 04:45 PM, Zeev Suraski wrote:
> >> With rand functions, I don't think we need to touch them. For some >> applications, low-key randomness is just fine - if you need to shuffle >> array of 20 elements or randomize unit test to ensure you're not testing >> same value all the time, low-quality randomness is completely fine. For >> other applications, there are superior solutions and everybody who needs >> them already uses them, but again I see no value in removing those >> functions. It would only cause more breakage and make adoption of new >> versions (already horrible) even slower. > > I think the obvious option here is to make rand() and srand() aliases to rand_mt() and srand_mt(), unless I'm missing something very basic, unless I'm missing something very basic here..? I see zero reason to deprecate them and break so much code when we can simply 'upgrade' them at zero cost to both us and users.
Aliasing to mt_rand() definitely makes sense. With a name like `rand()`, everyone will use it just because it is an obvious and common name for the normal way to generate random numbers. Aliasing essentially will make `rand()` as everyone uses it, better.
-- Stephen

Zeev Suraski

10 years ago
> On 18 בפבר? 2016, at 14:42, Nikita Popov <nikita.ppv@gmail.com> wrote: > > Hi internals! > > I've created a bulk-deprecation RFC for PHP 7.1: > https://wiki.php.net/rfc/deprecations_php_7_1 > > I'm using this RFC to collect various deprecations targeting PHP 7.1, as > having individual RFCs for these is too much management overhead. Each > deprecated feature will get its own vote, of course. > > This RFC is incomplete -- I'm posting it now so people can suggest other > things that should be deprecated. I expect it to grow over time and don't > plan to vote on it in the immediate future.
Following up on what I wrote earlier, I think we need to separate the discussion of each topic to its own thread. Some threads will be simple with not much discussion, with others probably resulting in more discussion. It's quite messy to discuss so many items (with the list growing and growing) in one thread. It's fine to keep it as one centralized RFC (and probably a good idea), but let's keep the discussions separate. Zeev

François Laupretre

10 years ago
Hi, Le 18/02/2016 13:41, Nikita Popov a écrit :
> > This RFC is incomplete -- I'm posting it now so people can suggest other > things that should be deprecated. I expect it to grow over time and don't > plan to vote on it in the immediate future.
May I suggest to remove the second argument of spl_autoload() ? spl_autoload() is typically called from the PHP core only, and the core never sets this argument. File extensions to consider are set using spl_autoload_extensions(). So, the 2nd argument of spl_autoload() is useless and probably never used anywhere. The problem with this argument is that it creates an annoying issue when thinking about a way to extend autoloading to other symbol types (namely functions and constants). The easiest way to extend autoloading to other types is to add an optional second argument to autoloaders. For a perfect BC, the core would call an autoloader for non-class symbols only if the function accepts 2 arguments. This way, we can achieve full backwards and forward compatibility with existing autoloaders. The pre-requisite is that currently existing autoloaders take only one arg, hence my suggestion to remove the second argument of spl_autoload() (spl_autoload() will remain a class-only autoloader). Regards François

Andrew Faulds

10 years ago
Hi Nikita, Nikita Popov wrote:
> This RFC is incomplete -- I'm posting it now so people can suggest other > things that should be deprecated. I expect it to grow over time and don't > plan to vote on it in the immediate future.
I think this would be a good opportunity to look at our existing php.ini directives, with view to getting rid of some more of them eventually. Three in particular spring to mind: * `precision` and `serialize_precision` - These determine how many digits are printed when outputting floating-point numbers. - `serialize_precision` is used when serialising or exporting numbers, and would seem to exist solely to allow you to shoot yourself in the foot, by discarding possibly important information when serialising - an operation that's supposed to perfectly reproduce a value! - `precision` is used in other contexts, and is more problematic, because its default value is 14 which is less than the maximum number of decimal digits in a PHP float. This means that, by default, PHP doesn't print floats to their full precision - including in var_dump(). This can create unreasonable confusion when debugging (why are two numbers that appear identical with var_dump() reported as inequal?), means potentially important information is removed by default, and really ought not to be a global setting anyway: if you want to format your numbers with reduced precision, do so explicitly. - Both of these are settings which code may implicitly depend on and break when they are changed. The manual is unhelpful here, because it doesn't warn you that `precision` is used when floats on any page except that for php.ini! * `mbstring.func_overload` - This piece of magic replaces the standard string functions with their mb_* equivalents. It is the character encodings equivalent of magic quotes: it simply assumes that all string operations on binary strings, if replaced by "multi-byte" versions, will suddenly handle character encodings properly. They won't necessarily, so this is quite a reckless setting. Worse, this setting prevents you from using the normal, non-"multi-byte" string functions when you need them for binary data, so PHP packages which deal with binary data are broken when this php.ini setting is turned on. Luckily, apps which rely on this setting being on could be easily fixed: by using find/replace. There might be others worth dealing with, too, these are just the first three I thought of. Thanks.
-- Andrea Faulds https://ajf.me/

Stas Malyshev

10 years ago
Hi!
> foot, by discarding possibly important information when serialising - an > operation that's supposed to perfectly reproduce a value!
I'm not sure this is correct. Also, for values that are not exactly representable in binary, I'm not sure you want to see 0.1000000000000000055511151231257827021181583404541015625 instead of 0.1. You certainly don't want var_dump to print that by default - this would make display cluttred and have very high WTF factor - why I entered 0.1 and get this enormous snake of a number? PHP must be broken! Moreover, when you do "$a = 8.2 - 0.2" and then print/send $a, do you want to see 8 or 7.99999999999999911182158029987476766109466552734375? In fact, when we represent 0.1 as 0.1 when serializing our outputting, we are not discarding information, on the contrary - we are preserving exactly the information that was given to us by user.
> print floats to their full precision - including in var_dump(). This can > create unreasonable confusion when debugging (why are two numbers that > appear identical with var_dump() reported as inequal?), means
You really think that displaying 8.2 - 0.2 as 8 is more confusing than displaying it as 7.99999999999999911182158029987476766109466552734375?
> potentially important information is removed by default, and really > ought not to be a global setting anyway: if you want to format your > numbers with reduced precision, do so explicitly.
That would mean optimizing for case that nobody wants, and de-optimizing case that pretty much everybody wants. Ask 100 people using PHP what they want as a result of 8.2 - 0.2 and count how many of them want to see full-precision monster of a number.
> There might be others worth dealing with, too, these are just the first > three I thought of.
I would very much advise not to mess with any options until we are definitely, 100%, without any doubt sure that nobody needs to use it for anything. Removing options earns us nothing in terms of functionality. If nobody uses them - ok, fine - drop them. If we need to remove them e.g. because component they address goes away or changes function in a way that makes it irrelevent - fine, drop them. But doing it just because very small number of people that we can engage in discussion on the list (and that's not going to ever change - PHP user community is vastly larger than people even reading this list, let alone actively participating in it) think it's not needed IMHO is a very wrong approach. Sometimes we have no choice but to take decisions with this incomplete knowledge - but here we have a perfectly good option of just leaving it alone. All other options should be weighted against it.
-- Stas Malyshev smalyshev@gmail.com

Andrew Faulds

10 years ago
Hi Stas, Stanislav Malyshev wrote:
> Hi! > >> foot, by discarding possibly important information when serialising - an >> operation that's supposed to perfectly reproduce a value! > > I'm not sure this is correct. Also, for values that are not exactly > representable in binary, I'm not sure you want to see > 0.1000000000000000055511151231257827021181583404541015625 instead of > 0.1.
This assumes we would print an exact decimal representation, but that's far more than necessary. In order to get the same result when converted back to a float, we need at most 17 digits. In many cases we don't even need to show 17, because there are not that many digits in a full-precision decimal representation (e.g. 0.5). We could use less in many cases if PHP were to switch to the approach other languages use, where we output only the shortest sequence of digits producing the same value when converted back to a float (whereas currently we output in full precision, up to 17 significant figures).
> You certainly don't want var_dump to print that by default - this > would make display cluttred and have very high WTF factor
Why would displaying at most three extra digits have a "high WTF factor"?
> - why I > entered 0.1 and get this enormous snake of a number?
PHP must be broken! var_dump() is a debugging function. If it shows a value, it must represent it accurately. Otherwise: $ php -r 'var_dump(1.00000000000002, 1.00000000000001, 1.00000000000001 === 1.00000000000002);' float(1) float(1) bool(true) Please explain to me why this is intuitive and reasonable behaviour for a debugging function. Furthermore, if PHP developers find floating-point confusing and are genuinely surprised that 0.1 cannot be represented in binary exactly, then perhaps they should go and learn about what floating-point numbers do, rather than naïvely continuing on thinking they're decimals thanks to PHP lying to them! It is not the job of the language to try and hide that floats are imprecise from programmers.
> Moreover, when you do "$a = 8.2 - 0.2" and then print/send $a, do you > want to see 8 or 7.99999999999999911182158029987476766109466552734375?
Let's look at what our contemporary programming languages do. Python:
>>> 8.2 - 0.2
7.999999999999999 JavaScript: 8.2 - 0.2 7.999999999999999 That's much shorter than your suggestion. Heck, let's look at what var_export() does: $ php -r 'var_export(8.2 - 0.2);' 7.9999999999999991 Still a lot shorter.
> In fact, when we represent 0.1 as 0.1 when serializing our outputting,
But we don't represent 0.1 as 0.1: $ php -r 'var_export(0.1);' 0.10000000000000001
> we are not discarding information, on the contrary - we are preserving > exactly the information that was given to us by user.
$ php -r 'var_dump(1.00000000000002);' float(1) That doesn't look very preserved to me.
> >> print floats to their full precision - including in var_dump(). This can >> create unreasonable confusion when debugging (why are two numbers that >> appear identical with var_dump() reported as inequal?), means > > You really think that displaying 8.2 - 0.2 as 8 is more confusing than > displaying it as 7.99999999999999911182158029987476766109466552734375?
It's more *honest*. If two values are different, they should not be displayed the same. And, again, the result would not be that large: $ php -r 'var_export(8.2 - 0.2);' 7.9999999999999991
> >> potentially important information is removed by default, and really >> ought not to be a global setting anyway: if you want to format your >> numbers with reduced precision, do so explicitly. > > That would mean optimizing for case that nobody wants, and de-optimizing > case that pretty much everybody wants.
Who wants to round numbers to the same precision in all situations, for all apps running on their server, for all code running within a given request, even in libraries?
> Ask 100 people using PHP what > they want as a result of 8.2 - 0.2 and count how many of them want to > see full-precision monster of a number.
"7.9999999999999991" isn't that monstrous, and it could be even less so if PHP used a nicer float-to-string conversion approach.
> >> There might be others worth dealing with, too, these are just the first >> three I thought of. > > I would very much advise not to mess with any options until we are > definitely, 100%, without any doubt sure that nobody needs to use it for > anything. Removing options earns us nothing in terms of functionality. > If nobody uses them - ok, fine - drop them. If we need to remove them > e.g. because component they address goes away or changes function in a > way that makes it irrelevent - fine, drop them. But doing it just > because very small number of people that we can engage in discussion on > the list (and that's not going to ever change - PHP user community is > vastly larger than people even reading this list, let alone actively > participating in it) think it's not needed IMHO is a very wrong > approach.
This might be a fine argument, but I'm not arguing these settings are not needed. I'm arguing they're actively harmful.
-- Andrea Faulds https://ajf.me/

Andrew Faulds

10 years ago
Hi, Andrea Faulds wrote:
> $ php -r 'var_dump(1.00000000000002, 1.00000000000001, 1.00000000000001 > === 1.00000000000002);' > float(1) > float(1) > bool(true)
I missed this when proof-reading. The output is actually: php -r 'var_dump(1.00000000000002, 1.00000000000001, 1.00000000000001 === 1.00000000000002);' float(1) float(1) bool(false) Which reflects the point I was trying to make (two numbers that are NOT exactly equal according to === are printed identically by var_dump()). I made a mistake in my original email, sorry.
-- Andrea Faulds https://ajf.me/

Lester Caine

10 years ago
On 24/02/16 01:11, Andrea Faulds wrote:
> Furthermore, if PHP developers find floating-point confusing and are > genuinely surprised that 0.1 cannot be represented in binary exactly, > then perhaps they should go and learn about what floating-point numbers > do, rather than naïvely continuing on thinking they're decimals thanks > to PHP lying to them! It is not the job of the language to try and hide > that floats are imprecise from programmers.
This just about sums up my understanding on the differences between a programmer and a software engineer. There are fundamental limits to each of the different hardware platforms one is running code on, so 'assuming' that the answers you get are always the same simply proves one still has to learn how to program. SQL addressed many of these differences early on, and things like fractional currency fields being managed as integers with a fixed fractional offsets ( NUMBER(8,3) ) which accurately record 'tenth of a cent' provide clean interfaces, but all too often they get transferred into 'float' because it's 'easier to handle'. That PHP makes some of these conversions transparently *IS* the problem of the language, but often it's because the programmer is simply ignorant of why the original methods were adopted? BIGINT is an example of where there are different understandings of just what a number is, and trying to add unlimited accuracy is not a substitution to the fact that when accessed from a database a BIGINT is simply a clean 64bit number. Float has the same limitations based on just what hardware is providing it?
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Fleshgrinder

10 years ago
On 2/24/2016 2:11 AM, Andrea Faulds wrote:
> Furthermore, if PHP developers find floating-point confusing and are > genuinely surprised that 0.1 cannot be represented in binary exactly, > then perhaps they should go and learn about what floating-point numbers > do, rather than naïvely continuing on thinking they're decimals thanks > to PHP lying to them! It is not the job of the language to try and hide > that floats are imprecise from programmers. >
+1 for removing the options and on the RFC. I have to deal with float comparisons and BIGINT being cast to (int) in PHP every day and people simply do not get it. The language should be brutal when it comes to these things and warn, throw exceptions, whatever. :P
-- Richard "Fleshgrinder" Fussenegger

Yasuo Ohgaki

10 years ago
Hi, On Wed, Feb 24, 2016 at 9:48 AM, Stanislav Malyshev <smalyshev@gmail.com> wrote:
>> foot, by discarding possibly important information when serialising - an >> operation that's supposed to perfectly reproduce a value! > > I'm not sure this is correct. Also, for values that are not exactly > representable in binary, I'm not sure you want to see > 0.1000000000000000055511151231257827021181583404541015625 instead of > 0.1. You certainly don't want var_dump to print that by default - this > would make display cluttred and have very high WTF factor - why I > entered 0.1 and get this enormous snake of a number? PHP must be broken! > Moreover, when you do "$a = 8.2 - 0.2" and then print/send $a, do you > want to see 8 or 7.99999999999999911182158029987476766109466552734375? > > In fact, when we represent 0.1 as 0.1 when serializing our outputting, > we are not discarding information, on the contrary - we are preserving > exactly the information that was given to us by user. > >> print floats to their full precision - including in var_dump(). This can >> create unreasonable confusion when debugging (why are two numbers that >> appear identical with var_dump() reported as inequal?), means > > You really think that displaying 8.2 - 0.2 as 8 is more confusing than > displaying it as 7.99999999999999911182158029987476766109466552734375? > >> potentially important information is removed by default, and really >> ought not to be a global setting anyway: if you want to format your >> numbers with reduced precision, do so explicitly. > > That would mean optimizing for case that nobody wants, and de-optimizing > case that pretty much everybody wants. Ask 100 people using PHP what > they want as a result of 8.2 - 0.2 and count how many of them want to > see full-precision monster of a number. > >> There might be others worth dealing with, too, these are just the first >> three I thought of. > > I would very much advise not to mess with any options until we are > definitely, 100%, without any doubt sure that nobody needs to use it for > anything. Removing options earns us nothing in terms of functionality. > If nobody uses them - ok, fine - drop them. If we need to remove them > e.g. because component they address goes away or changes function in a > way that makes it irrelevent - fine, drop them. But doing it just > because very small number of people that we can engage in discussion on > the list (and that's not going to ever change - PHP user community is > vastly larger than people even reading this list, let alone actively > participating in it) think it's not needed IMHO is a very wrong > approach. Sometimes we have no choice but to take decisions with this > incomplete knowledge - but here we have a perfectly good option of just > leaving it alone. All other options should be weighted against it.
This discussion is related to https://wiki.php.net/rfc/precise_float_value If you have comment on this, I appreciate it. Please search old thread for discussions. I'll start final RFC discussion for this when session RFC is finished. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Andrew Faulds

10 years ago
Hi Yasuo, Yasuo Ohgaki wrote:
> This discussion is related to > > https://wiki.php.net/rfc/precise_float_value > > If you have comment on this, I appreciate it. > Please search old thread for discussions. > I'll start final RFC discussion for this when session RFC is finished.
Thank you for bringing that RFC up again, it would improve this situation somewhat. Particularly in that it would use the "0" precision for zend_dtoa, which is the "shortest sequence of digits producing the same value when converted back to a float" behaviour that I mentioned in my email.
-- Andrea Faulds https://ajf.me/

Andrew Faulds

10 years ago
Hi again, Andrea Faulds wrote:
> Hi Yasuo, > > Yasuo Ohgaki wrote: >> This discussion is related to >> >> https://wiki.php.net/rfc/precise_float_value >> >> If you have comment on this, I appreciate it. >> Please search old thread for discussions. >> I'll start final RFC discussion for this when session RFC is finished. > > Thank you for bringing that RFC up again, it would improve this > situation somewhat. Particularly in that it would use the "0" precision > for zend_dtoa, which is the "shortest sequence of digits producing the > same value when converted back to a float" behaviour that I mentioned in > my email. >
This article has a good explanation of the two different approaches: http://blog.reverberate.org/2016/02/06/floating-point-demystified-part2.html
-- Andrea Faulds https://ajf.me/

Yasuo Ohgaki

10 years ago
Hi Andrea, On Thu, Feb 25, 2016 at 10:00 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Andrea Faulds wrote: >> >> Hi Yasuo, >> >> Yasuo Ohgaki wrote: >>> >>> This discussion is related to >>> >>> https://wiki.php.net/rfc/precise_float_value >>> >>> If you have comment on this, I appreciate it. >>> Please search old thread for discussions. >>> I'll start final RFC discussion for this when session RFC is finished. >> >> >> Thank you for bringing that RFC up again, it would improve this >> situation somewhat. Particularly in that it would use the "0" precision >> for zend_dtoa, which is the "shortest sequence of digits producing the >> same value when converted back to a float" behaviour that I mentioned in >> my email. >> > > This article has a good explanation of the two different approaches: > > http://blog.reverberate.org/2016/02/06/floating-point-demystified-part2.html
Nice article! Added URL to reference section of the RFC. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Stephen Coakley

10 years ago
On 02/18/2016 06:41 AM, Nikita Popov wrote:
> Hi internals! > > I've created a bulk-deprecation RFC for PHP 7.1: > https://wiki.php.net/rfc/deprecations_php_7_1 > > I'm using this RFC to collect various deprecations targeting PHP 7.1, as > having individual RFCs for these is too much management overhead. Each > deprecated feature will get its own vote, of course. > > This RFC is incomplete -- I'm posting it now so people can suggest other > things that should be deprecated. I expect it to grow over time and don't > plan to vote on it in the immediate future. > > Thanks, > Nikita >
My stance on deprecations:
> It seems that perfection is attained not when there is nothing more > to add, but when there is nothing more to remove. > - Antoine de Saint Exupéry
I'd say any function that provides duplicate functionality, or encourages bad practice, should be deprecated. Keeping the standard library clean and focused is ideal.
-- Stephen

Tony Marston

10 years ago
"Stephen Coakley" wrote in message news:DB.F0.25279.8C0D9D65@pb1.pair.com...
> >On 02/18/2016 06:41 AM, Nikita Popov wrote: >> Hi internals! >> >> I've created a bulk-deprecation RFC for PHP 7.1: >> https://wiki.php.net/rfc/deprecations_php_7_1 >> >> I'm using this RFC to collect various deprecations targeting PHP 7.1, as >> having individual RFCs for these is too much management overhead. Each >> deprecated feature will get its own vote, of course. >> >> This RFC is incomplete -- I'm posting it now so people can suggest other >> things that should be deprecated. I expect it to grow over time and don't >> plan to vote on it in the immediate future. >> >> Thanks, >> Nikita >> > >My stance on deprecations: > > > It seems that perfection is attained not when there is nothing more > > to add, but when there is nothing more to remove. > > - Antoine de Saint Exupéry > >I'd say any function that provides duplicate functionality, or encourages >bad practice, should be deprecated. Keeping the standard library clean and >focused is ideal.
But who decides what is "bad" practice and what is not? It is impossible for ANY language to prevent a bad programmer from writing bad code, so the only way to prevent bad code 100% would be to have a language that did nothing at all. Deprecating something just because you don't like is NOT a good enough reason.
-- Tony Marston