[RFC] Reclassifying engine warnings

  106713
August 28, 2019 09:33 nikita.ppv@gmail.com (Nikita Popov)
Hi internals,

I think it's time to take a look at our existing warnings & notices in the
engine, and think about whether their current classification is still
appropriate. Error conditions like "undefined variable" only generating a
notice is really quite mind-boggling.

I've prepared an RFC with some suggested classifications, though there's
room for bikeshedding here...

https://wiki.php.net/rfc/engine_warnings

Regards,
Nikita
  106714
August 28, 2019 10:07 kjarli@gmail.com (Lynn)
Hi Nikita,

This RFC makes me very happy! I have a few points that I didn't find
clarification on in the RFC. For "Undefined variable: %s" the new proposal
is an Error Exception. For a starter: will it include dynamically declared
variables such as $$foo?

For my second point: in regards of backwards compatibility, is it possible
to first trigger a deprecation for each of the cases that will abort the
flow? If not, I fear I won't be able to upgrade as we still maintain a lot
of legacy code that deals with dynamically declared and undefined
variables, and possibly other violations that we don't know of. We are
working on rewriting all this code but don't have enough developers to
rewrite everything under a few years. If we can start logging these
deprecations, we know where to fix what, rather than having our entire
application crash. This way we can prioritize our maintenance on fixes each
of these cases.

The scenarios where this occurs often in our code base are dynamically
included files that may or may not set a variable. The code is most likely
"broken", but the behavior it produces is what's considered correct at this
point. It can be solved by defining the variable with null value, but it's
hard to trace without logging as we can't always set it with null value.

Regards,
Lynn van der Berg


On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. > > I've prepared an RFC with some suggested classifications, though there's > room for bikeshedding here... > > https://wiki.php.net/rfc/engine_warnings > > Regards, > Nikita >
  106715
August 28, 2019 10:40 zeev@php.net (Zeev Suraski)
On Wed, Aug 28, 2019 at 12:33 PM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. > > I've prepared an RFC with some suggested classifications, though there's > room for bikeshedding here... > > https://wiki.php.net/rfc/engine_warnings
Specifically on undefined variables, the way we deal with them has little to do with register_globals. It's behavior you can find in other dynamic languages (e.g. Perl), and allows for certain code patterns (which rely on the automatic creation of a variable whenever it's used in write context, and on a default known-in-advance value in case it's used in a read context). It's fine not to like this behavior or the code patterns that commonly rely on it (e.g., @$foo++), but it's intentional and isn't related to any historical reasons. I think many (if not all) of your proposals make sense, but most of them make sense as an opt-in - perhaps using something similar to Perl's strict mode (which incidentally, changes the way the language treats undefined variables in exactly the same way). This would also provide a future-proof solution for additional similarly-themed proposals (such as strict ops, etc.). Zeev
  106717
August 28, 2019 11:10 nikita.ppv@gmail.com (Nikita Popov)
On Wed, Aug 28, 2019 at 12:41 PM Zeev Suraski <zeev@php.net> wrote:

> > > On Wed, Aug 28, 2019 at 12:33 PM Nikita Popov ppv@gmail.com> > wrote: > >> Hi internals, >> >> I think it's time to take a look at our existing warnings & notices in the >> engine, and think about whether their current classification is still >> appropriate. Error conditions like "undefined variable" only generating a >> notice is really quite mind-boggling. >> >> I've prepared an RFC with some suggested classifications, though there's >> room for bikeshedding here... >> >> https://wiki.php.net/rfc/engine_warnings > > > Specifically on undefined variables, the way we deal with them has little > to do with register_globals. It's behavior you can find in other dynamic > languages (e.g. Perl), and allows for certain code patterns (which rely on > the automatic creation of a variable whenever it's used in write context, > and on a default known-in-advance value in case it's used in a read > context). It's fine not to like this behavior or the code patterns that > commonly rely on it (e.g., @$foo++), but it's intentional and isn't related > to any historical reasons. >
This argument makes sense for arrays and objects (and I don't promote undefined index/property to exceptions for that reason), but I don't think it holds any water for simple variables. Writing @$counts[$key]++ is a lazy way to count values and avoid ugly boilerplate for if (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. But @$foo++ is just a really bad way of writing either $foo++ or $foo = 1. Outside of variable variables, the concept of a conditionally defined variable just doesn't make a lot of sense.
> I think many (if not all) of your proposals make sense, but most of them > make sense as an opt-in - perhaps using something similar to Perl's strict > mode (which incidentally, changes the way the language treats undefined > variables in exactly the same way). This would also provide a future-proof > solution for additional similarly-themed proposals (such as strict ops, > etc.). >
I don't think this is an appropriate use of an opt-in. It's a case where we can balance language cleanup with backwards compatibility concerns. Code that works after this proposal will also work before it, and as such there is no danger of ecosystem bifurcation that would need to be addressed by an opt-in. Thanks, Nikita
  106719
August 28, 2019 11:45 kjarli@gmail.com (Lynn)
This argument makes sense for arrays and objects (and I don't promote
> undefined index/property to exceptions for that reason), but I don't think > it holds any water for simple variables. Writing @$counts[$key]++ is a lazy > way to count values and avoid ugly boilerplate for if > (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. > But @$foo++ is just a really bad way of writing either $foo++ or $foo = 1. > Outside of variable variables, the concept of a conditionally defined > variable just doesn't make a lot of sense. >
The variables are not conditionally declared on purpose, but as it's code written 15~20 years ago, maintained, copy-pasted over and over and never reviewed, there's a lot of issues that remain that my trigger an error exception if this proposal is passed without migration path. ``` // a.php if ($someCondition) { // comes from another file, never used, can't verify existance $foo = 'foo'; } // b.php $bar = 'bar'; // scenario1.php include 'a.php'; // this would crash include 'b.php'; echo $foo . $bar; // this would crash if the include didn't yet // scenario2.php $someCondition = true; include 'a.php'; // this would not crash include 'b.php'; echo $foo . $bar; // this would not crash ``` The problem with the above legacy code, which we sadly have spread through a spaghetti of thousands of files, is that if it starts throwing errors with no migration path, we simply can't update without spending possibly weeks debugging and trying to find scenarios where this might trigger. Now I'm not sure, but if I would've used `include_once` and combine this with function/class scopes (people loved to do that in our legacy code), all hell breaks loose and it will be nearly impossible to find the cases. All I'm asking is for a clear upgrade path with deprecations so that my code can be safely migrated over time, rather than have it crash with the next version. Compared to
  106720
August 28, 2019 11:57 nikita.ppv@gmail.com (Nikita Popov)
On Wed, Aug 28, 2019 at 1:46 PM Lynn <kjarli@gmail.com> wrote:

> > > > This argument makes sense for arrays and objects (and I don't promote >> undefined index/property to exceptions for that reason), but I don't think >> it holds any water for simple variables. Writing @$counts[$key]++ is a >> lazy >> way to count values and avoid ugly boilerplate for if >> (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. >> But @$foo++ is just a really bad way of writing either $foo++ or $foo = 1. >> Outside of variable variables, the concept of a conditionally defined >> variable just doesn't make a lot of sense. >> > > The variables are not conditionally declared on purpose, but as it's code > written 15~20 years ago, maintained, copy-pasted over and over and never > reviewed, there's a lot of issues that remain that my trigger an error > exception if this proposal is passed without migration path. >
To be clear, this was in response to Zeev's particular argument, which I don't think is valid. I am aware that accesses to undefined variables are a thing in legacy code. However, I feel pretty strongly that converting any of these to deprecations is not a good idea. While there's certainly different views on this, I've seen it often enough deprecation warning are considered an even lower error level than notices (imagine my surprise when PEAR stopped working completely in PHP 8 because nobody ever saw the hundreds of suppressed deprecations). We could throw a deprecation in addition, but I think this will make the development experience really suck for anyone who is not actively working on a migration right now (imagine seeing lots of warnings/notices during development twice). I think it would be better to register an error handler that matches the cases that will throw and can then log those. I'd be happy to provide an implementation if you think this would be useful for your use-case. Also has the nice advantage that you can start using it right now and don't have to wait until you upgrade to a release that has deprecations. Nikita
> > ``` > // a.php > if ($someCondition) { // comes from another file, never used, can't verify > existance > $foo = 'foo'; > } > > // b.php > $bar = 'bar'; > > // scenario1.php > include 'a.php'; // this would crash > include 'b.php'; > > echo $foo . $bar; // this would crash if the include didn't yet > > // scenario2.php > $someCondition = true; > > include 'a.php'; // this would not crash > include 'b.php'; > > echo $foo . $bar; // this would not crash > ``` > > The problem with the above legacy code, which we sadly have spread through > a spaghetti of thousands of files, is that if it starts throwing errors > with no migration path, we simply can't update without spending possibly > weeks debugging and trying to find scenarios where this might trigger. Now > I'm not sure, but if I would've used `include_once` and combine this with > function/class scopes (people loved to do that in our legacy code), all > hell breaks loose and it will be nearly impossible to find the cases. > > All I'm asking is for a clear upgrade path with deprecations so that my > code can be safely migrated over time, rather than have it crash with the > next version. Compared to easy to fix. By having it throw deprecations which we can easily log to a > specific file, we can gather and fix the cases when we have time to spend > on technical debt, and by the time the warning will turn into an error > exception, we'll have fixed probably 90%+ of the cases, making the upgrade > possible. > > Regards, > Lynn van der Berg >
  106722
August 28, 2019 12:18 rowan.collins@gmail.com (Rowan Tommins)
On Wed, 28 Aug 2019 at 12:57, Nikita Popov ppv@gmail.com> wrote:

> However, I feel pretty strongly that converting any of these to > deprecations is not a good idea. While there's certainly different views on > this, I've seen it often enough deprecation warning are considered an even > lower error level than notices (imagine my surprise when PEAR stopped > working completely in PHP 8 because nobody ever saw the hundreds of > suppressed deprecations). We could throw a deprecation in addition, but I > think this will make the development experience really suck for anyone who > is not actively working on a migration right now (imagine seeing lots of > warnings/notices during development twice). >
Again, I considered this carefully for undefined constants and discussed it extensively on the RFC and resulting thread. In short, "deprecation notice" doesn't have to mean "E_DEPRECATED". Arguably, "severity" and "type" should be two different dimensions, and E_DEPRECATION_WARNING would be E_DEPRECATION & E_WARNING; but in practice, a Warning containing the text "this is deprecated" achieves the goal just fine. Whatever the mechanism, the point is to make people aware as far in advance as possible, so that they can start addressing the problem before it becomes a blocker to upgrading. As briefly mentioned, third-party libraries are a key case here: if a library raises extra Warnings, I can take the time to submit a patch to that library, wait for the maintainer to accept it, and make sure I can use the latest version; if the library raises extra Errors, I have to delay my upgrade, or run a patched version of the library, until it's fixed. Regards, -- Rowan Tommins [IMSoP]
  106724
August 28, 2019 13:29 kjarli@gmail.com (Lynn)
However, I feel pretty strongly that converting any of these to
> deprecations is not a good idea. While there's certainly different views on > this, I've seen it often enough deprecation warning are considered an even > lower error level than notices (imagine my surprise when PEAR stopped > working completely in PHP 8 because nobody ever saw the hundreds of > suppressed deprecations). We could throw a deprecation in addition, but I > think this will make the development experience really suck for anyone who > is not actively working on a migration right now (imagine seeing lots of > warnings/notices during development twice). >
You got a very valid point here. As long as there is a clear migration path, albeit with user-land tools, I'll take it.
> I think it would be better to register an error handler that matches the > cases that will throw and can then log those. I'd be happy to provide an > implementation if you think this would be useful for your use-case. Also > has the nice advantage that you can start using it right now and don't have > to wait until you upgrade to a release that has deprecations. >
It would be great to have a package that reports all these cases, though we could try to craft something ourselves if this RFC is approved. Perhaps frameworks providing error handlers can add specific logging for these scenarios as well, saves you from putting more effort in this than required. Regards, Lynn van der Berg
  106721
August 28, 2019 11:58 cschneid@cschneid.com (Christian Schneider)
Am 28.08.2019 um 13:10 schrieb Nikita Popov ppv@gmail.com>:
> On Wed, Aug 28, 2019 at 12:41 PM Zeev Suraski <zeev@php.net> wrote: >> Specifically on undefined variables, the way we deal with them has little >> to do with register_globals. It's behavior you can find in other dynamic >> languages (e.g. Perl), and allows for certain code patterns (which rely on >> the automatic creation of a variable whenever it's used in write context, >> and on a default known-in-advance value in case it's used in a read >> context). It's fine not to like this behavior or the code patterns that >> commonly rely on it (e.g., @$foo++), but it's intentional and isn't related >> to any historical reasons. > > This argument makes sense for arrays and objects (and I don't promote > undefined index/property to exceptions for that reason), but I don't think > it holds any water for simple variables. Writing @$counts[$key]++ is a lazy > way to count values and avoid ugly boilerplate for if > (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. > But @$foo++ is just a really bad way of writing either $foo++ or $foo = 1. > Outside of variable variables, the concept of a conditionally defined > variable just doesn't make a lot of sense.
We often use the pattern $a .= "xy" or $a[] = "xy" and requiring to initialise leads to either boiler-plate code in often very simple functions or even worse to write the first one as $a = "xy" and $a = ["xy"] which both hurt symmetry and extensibility (you need to change two places if you want to add a new first entry). We are already suppressing the E_NOTICE for this as the pattern is too useful to fill our logs. Your simple typo in variable names can be caught well enough by a static analyser, we have a simplistic one in out git commit hook which more than does the job for us. And it does it even better in your average case as it also catches typos in rare code paths not executed by your tests. And no, don't say "make sure you have 100% code coverage", that is a myth. Summary: Promote E_NOTICE to E_WARNINGS, fine, make them abort code execution: Don't do it, don't break our code. For people promoting a stricter PHP mode: Just fix your code if it caused an E_NOTICE/E_WARNING, you don't need an Exception for that. And I don't buy the whole security argument, code has to be secure on a whole different level than undefined variables. - Chris
  106723
August 28, 2019 12:34 zeev@php.net (Zeev Suraski)
On Wed, Aug 28, 2019 at 2:10 PM Nikita Popov ppv@gmail.com> wrote:

> On Wed, Aug 28, 2019 at 12:41 PM Zeev Suraski <zeev@php.net> wrote: > >> >> >> On Wed, Aug 28, 2019 at 12:33 PM Nikita Popov ppv@gmail.com> >> wrote: >> >>> Hi internals, >>> >>> I think it's time to take a look at our existing warnings & notices in >>> the >>> engine, and think about whether their current classification is still >>> appropriate. Error conditions like "undefined variable" only generating a >>> notice is really quite mind-boggling. >>> >>> I've prepared an RFC with some suggested classifications, though there's >>> room for bikeshedding here... >>> >>> https://wiki.php.net/rfc/engine_warnings >> >> >> Specifically on undefined variables, the way we deal with them has little >> to do with register_globals. It's behavior you can find in other >> dynamic languages (e.g. Perl), and allows for certain code patterns (which >> rely on the automatic creation of a variable whenever it's used in write >> context, and on a default known-in-advance value in case it's used in a >> read context). It's fine not to like this behavior or the code patterns >> that commonly rely on it (e.g., @$foo++), but it's intentional and isn't >> related to any historical reasons. >> > > This argument makes sense for arrays and objects (and I don't promote > undefined index/property to exceptions for that reason), but I don't think > it holds any water for simple variables. Writing @$counts[$key]++ is a lazy > way to count values and avoid ugly boilerplate for if > (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. > But @$foo++ is just a really bad way of writing either $foo++ or $foo = 1. > Outside of variable variables, the concept of a conditionally defined > variable just doesn't make a lot of sense. >
This example has nothing to do with arrays. There are many code patterns in which relying on this behavior makes perfect sense for folks who are a lot less strictly-minded. For example: foreach (whatever) { if (sth) { @$whCount++; } } Yes, it may be painful for many eyes that $whCount is not explicitly initialized, but the above code is perfectly legitimate, warning-free notice-compliant code since forever. Moreover - this isn't legacy - there are a lot of folks who appreciate this precise behavior, which is documented and works as expected for the last 20+ years. Or: if ($bookCount>0) { $suffix = 's'; } print "$bookCount book$suffix"; These are just two simple cases I bumped into myself recently. There's an infinite supply of more of those where these came from.
> >> I think many (if not all) of your proposals make sense, but most of them >> make sense as an opt-in - perhaps using something similar to Perl's strict >> mode (which incidentally, changes the way the language treats undefined >> variables in exactly the same way). This would also provide a future-proof >> solution for additional similarly-themed proposals (such as strict ops, >> etc.). >> > > I don't think this is an appropriate use of an opt-in. It's a case where > we can balance language cleanup with backwards compatibility concerns. Code > that works after this proposal will also work before it, and as such there > is no danger of ecosystem bifurcation that would need to be addressed by an > opt-in. >
Calling this 'cleanup' is opinionated, and avoiding bifurcation by forcing that opinion on everyone isn't a very good solution for those who have other opinions. While the opinion that variables must not be used before being initialized is obviously a valid one - it is just that, one valid opinion - and there are others. PHP never took this opinion as an axiomatic requirement (and not because of register_globals) - instead, the intent was to have a default value for uninitialized variables - a consistent, documented behavior since the dawn of the language. Can this be problematic under certain situations? Absolutely. Can it be useful in other cases? Sure (which is why it's very common). A great deal of folks both rely on this behavior and *like *it. Those who don't (and there's plenty of those as well of course) - always had a reasonable solution of enabling E_STRICT and enforcing E_STRICT-compliant code. I still think that having a strict mode (which can encompass strict types, strict ops, stricter error behavior, etc.) makes a lot of sense and would arguably be a superior option for the many folks who prefer a stricter language - but there's simply no way we can change one of the most fundamental behaviors of the language and force it down people's throats - not only because it breaks compatibility, but because it breaks how many people are used to write their PHP code. Perl provided stricter-liking folks with a solution in the form of 'use strict;' decades ago; JS did something similar much more recently. Neither of these created any sort of bifurcation - it's a simple, sensible solution that has virtually no downsides. Zeev
  106725
August 28, 2019 13:30 chasepeeler@gmail.com (Chase Peeler)
On Wed, Aug 28, 2019 at 8:35 AM Zeev Suraski <zeev@php.net> wrote:

> On Wed, Aug 28, 2019 at 2:10 PM Nikita Popov ppv@gmail.com> wrote: > > > On Wed, Aug 28, 2019 at 12:41 PM Zeev Suraski <zeev@php.net> wrote: > > > >> > >> > >> On Wed, Aug 28, 2019 at 12:33 PM Nikita Popov ppv@gmail.com> > >> wrote: > >> > >>> Hi internals, > >>> > >>> I think it's time to take a look at our existing warnings & notices in > >>> the > >>> engine, and think about whether their current classification is still > >>> appropriate. Error conditions like "undefined variable" only > generating a > >>> notice is really quite mind-boggling. > >>> > >>> I've prepared an RFC with some suggested classifications, though > there's > >>> room for bikeshedding here... > >>> > >>> https://wiki.php.net/rfc/engine_warnings > >> > >> > >> Specifically on undefined variables, the way we deal with them has > little > >> to do with register_globals. It's behavior you can find in other > >> dynamic languages (e.g. Perl), and allows for certain code patterns > (which > >> rely on the automatic creation of a variable whenever it's used in write > >> context, and on a default known-in-advance value in case it's used in a > >> read context). It's fine not to like this behavior or the code patterns > >> that commonly rely on it (e.g., @$foo++), but it's intentional and isn't > >> related to any historical reasons. > >> > > > > This argument makes sense for arrays and objects (and I don't promote > > undefined index/property to exceptions for that reason), but I don't > think > > it holds any water for simple variables. Writing @$counts[$key]++ is a > lazy > > way to count values and avoid ugly boilerplate for if > > (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. > > But @$foo++ is just a really bad way of writing either $foo++ or $foo = > 1. > > Outside of variable variables, the concept of a conditionally defined > > variable just doesn't make a lot of sense. > > > > This example has nothing to do with arrays. There are many code patterns > in which relying on this behavior makes perfect sense for folks who are a > lot less strictly-minded. For example: > > foreach (whatever) { > if (sth) { > @$whCount++; > } > } > > Yes, it may be painful for many eyes that $whCount is not explicitly > initialized, but the above code is perfectly legitimate, warning-free > notice-compliant code since forever. Moreover - this isn't legacy - there > are a lot of folks who appreciate this precise behavior, which is > documented and works as expected for the last 20+ years. > > Or: > > if ($bookCount>0) { > $suffix = 's'; > } > > print "$bookCount book$suffix"; > > These are just two simple cases I bumped into myself recently. There's an > infinite supply of more of those where these came from. > > > > > >> I think many (if not all) of your proposals make sense, but most of them > >> make sense as an opt-in - perhaps using something similar to Perl's > strict > >> mode (which incidentally, changes the way the language treats undefined > >> variables in exactly the same way). This would also provide a > future-proof > >> solution for additional similarly-themed proposals (such as strict ops, > >> etc.). > >> > > > > I don't think this is an appropriate use of an opt-in. It's a case where > > we can balance language cleanup with backwards compatibility concerns. > Code > > that works after this proposal will also work before it, and as such > there > > is no danger of ecosystem bifurcation that would need to be addressed by > an > > opt-in. > > > > Calling this 'cleanup' is opinionated, and avoiding bifurcation by forcing > that opinion on everyone isn't a very good solution for those who have > other opinions. While the opinion that variables must not be used before > being initialized is obviously a valid one - it is just that, one valid > opinion - and there are others. PHP never took this opinion as an > axiomatic requirement (and not because of register_globals) - instead, the > intent was to have a default value for uninitialized variables - a > consistent, documented behavior since the dawn of the language. Can this > be problematic under certain situations? Absolutely. Can it be useful in > other cases? Sure (which is why it's very common). A great deal of folks > both rely on this behavior and *like *it. Those who don't (and there's > plenty of those as well of course) - always had a reasonable solution of > enabling E_STRICT and enforcing E_STRICT-compliant code. I still think > that having a strict mode (which can encompass strict types, strict ops, > stricter error behavior, etc.) makes a lot of sense and would arguably be a > superior option for the many folks who prefer a stricter language - but > there's simply no way we can change one of the most fundamental behaviors > of the language and force it down people's throats - not only because it > breaks compatibility, but because it breaks how many people are used to > write their PHP code. Perl provided stricter-liking folks with a solution > in the form of 'use strict;' decades ago; JS did something similar much > more recently. Neither of these created any sort of bifurcation - it's a > simple, sensible solution that has virtually no downsides. > > While I like Zeev's idea of making it opt-in, I think that a deprecation path is needed at the very least. I think this has the potential to be an
even bigger issue to deal with than short tags. At least short tags have been discouraged for a long time. The first short tags RFC would have probably lead to a delay in upgrading to 8.0. This RFC would pretty much guarantee never being able to upgrade to 8.0 until we've totally retired our legacy code base... which will probably be just in time for PHP 28.0 - assuming the PHP project isn't dead at that point due to this RFC.
> Zeev >
-- Chase Peeler chasepeeler@gmail.com
  106726
August 28, 2019 13:48 chasepeeler@gmail.com (Chase Peeler)
On Wed, Aug 28, 2019 at 9:30 AM Chase Peeler <chasepeeler@gmail.com> wrote:

> > > On Wed, Aug 28, 2019 at 8:35 AM Zeev Suraski <zeev@php.net> wrote: > >> On Wed, Aug 28, 2019 at 2:10 PM Nikita Popov ppv@gmail.com> >> wrote: >> >> > On Wed, Aug 28, 2019 at 12:41 PM Zeev Suraski <zeev@php.net> wrote: >> > >> >> >> >> >> >> On Wed, Aug 28, 2019 at 12:33 PM Nikita Popov ppv@gmail.com> >> >> wrote: >> >> >> >>> Hi internals, >> >>> >> >>> I think it's time to take a look at our existing warnings & notices in >> >>> the >> >>> engine, and think about whether their current classification is still >> >>> appropriate. Error conditions like "undefined variable" only >> generating a >> >>> notice is really quite mind-boggling. >> >>> >> >>> I've prepared an RFC with some suggested classifications, though >> there's >> >>> room for bikeshedding here... >> >>> >> >>> https://wiki.php.net/rfc/engine_warnings >> >> >> >> >> >> Specifically on undefined variables, the way we deal with them has >> little >> >> to do with register_globals. It's behavior you can find in other >> >> dynamic languages (e.g. Perl), and allows for certain code patterns >> (which >> >> rely on the automatic creation of a variable whenever it's used in >> write >> >> context, and on a default known-in-advance value in case it's used in a >> >> read context). It's fine not to like this behavior or the code >> patterns >> >> that commonly rely on it (e.g., @$foo++), but it's intentional and >> isn't >> >> related to any historical reasons. >> >> >> > >> > This argument makes sense for arrays and objects (and I don't promote >> > undefined index/property to exceptions for that reason), but I don't >> think >> > it holds any water for simple variables. Writing @$counts[$key]++ is a >> lazy >> > way to count values and avoid ugly boilerplate for if >> > (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. >> > But @$foo++ is just a really bad way of writing either $foo++ or $foo = >> 1. >> > Outside of variable variables, the concept of a conditionally defined >> > variable just doesn't make a lot of sense. >> > >> >> This example has nothing to do with arrays. There are many code patterns >> in which relying on this behavior makes perfect sense for folks who are a >> lot less strictly-minded. For example: >> >> foreach (whatever) { >> if (sth) { >> @$whCount++; >> } >> } >> >> Yes, it may be painful for many eyes that $whCount is not explicitly >> initialized, but the above code is perfectly legitimate, warning-free >> notice-compliant code since forever. Moreover - this isn't legacy - there >> are a lot of folks who appreciate this precise behavior, which is >> documented and works as expected for the last 20+ years. >> >> Or: >> >> if ($bookCount>0) { >> $suffix = 's'; >> } >> >> print "$bookCount book$suffix"; >> >> These are just two simple cases I bumped into myself recently. There's an >> infinite supply of more of those where these came from. >> >> >> > >> >> I think many (if not all) of your proposals make sense, but most of >> them >> >> make sense as an opt-in - perhaps using something similar to Perl's >> strict >> >> mode (which incidentally, changes the way the language treats undefined >> >> variables in exactly the same way). This would also provide a >> future-proof >> >> solution for additional similarly-themed proposals (such as strict ops, >> >> etc.). >> >> >> > >> > I don't think this is an appropriate use of an opt-in. It's a case where >> > we can balance language cleanup with backwards compatibility concerns. >> Code >> > that works after this proposal will also work before it, and as such >> there >> > is no danger of ecosystem bifurcation that would need to be addressed >> by an >> > opt-in. >> > >> >> Calling this 'cleanup' is opinionated, and avoiding bifurcation by forcing >> that opinion on everyone isn't a very good solution for those who have >> other opinions. While the opinion that variables must not be used before >> being initialized is obviously a valid one - it is just that, one valid >> opinion - and there are others. PHP never took this opinion as an >> axiomatic requirement (and not because of register_globals) - instead, the >> intent was to have a default value for uninitialized variables - a >> consistent, documented behavior since the dawn of the language. Can this >> be problematic under certain situations? Absolutely. Can it be useful in >> other cases? Sure (which is why it's very common). A great deal of folks >> both rely on this behavior and *like *it. Those who don't (and there's >> plenty of those as well of course) - always had a reasonable solution of >> enabling E_STRICT and enforcing E_STRICT-compliant code. I still think >> that having a strict mode (which can encompass strict types, strict ops, >> stricter error behavior, etc.) makes a lot of sense and would arguably be >> a >> superior option for the many folks who prefer a stricter language - but >> there's simply no way we can change one of the most fundamental behaviors >> of the language and force it down people's throats - not only because it >> breaks compatibility, but because it breaks how many people are used to >> write their PHP code. Perl provided stricter-liking folks with a solution >> in the form of 'use strict;' decades ago; JS did something similar much >> more recently. Neither of these created any sort of bifurcation - it's a >> simple, sensible solution that has virtually no downsides. >> >> While I like Zeev's idea of making it opt-in, I think that a deprecation > path is needed at the very least. I think this has the potential to be an > even bigger issue to deal with than short tags. At least short tags have > been discouraged for a long time. The first short tags RFC would have > probably lead to a delay in upgrading to 8.0. This RFC would pretty much > guarantee never being able to upgrade to 8.0 until we've totally retired > our legacy code base... which will probably be just in time for PHP 28.0 - > assuming the PHP project isn't dead at that point due to this RFC. > > I've been told I might not have been totally clear in my post.
My position is that this should be done as an opt-in feature like Zeev as proposed. If it is not done as an opt-in feature, then I don't think it should be done at all. If it is still done, then I think a deprecation path is a must. As mentioned earlier, this doesn't necessarily mean E_DEPRECATION messages - warnings will work too. The key is that error logs with more urgency than notices are created that users can use to track down and fix issues.
> Zeev >> > > > -- > Chase Peeler > chasepeeler@gmail.com >
-- Chase Peeler chasepeeler@gmail.com
  106731
August 28, 2019 14:24 markyr@gmail.com (Mark Randall)
On 28/08/2019 14:48, Chase Peeler wrote:
> My position is that this should be done as an opt-in feature like Zeev as > proposed. If it is not done as an opt-in feature, then I don't think it > should be done at all.
IMO one shouldn't have to opt-in to use common-sense error checking of engine operations. It's essential to think of the long-term future of PHP and what makes sense going forward, and to my mind that means things need to be more intuitive and less prone to mistakes. Be it Little Jonny Just-Grad who is starting his first proper PHP project, or the lead engineer of Megacorp, Inc. who is about to write the first line of the company's next multi-million dollar hit, they shouldn't need to pile-up on declares at the top of each page just to make the engine perform as intuitive common sense would dictate. By the very nature of using @ to suppress error messages, the examples given are all fully aware that the behaviour they are using is not good practice. If the engine was perfectly confident in your use of the statements that followed it, then it wouldn't display an error that you would need to suppress in the first place, now would it? Besides, we have tools available for years now to make this behaviour more defined: $counts[$key] = ($counts[$key] ?? 0) + 1; "If $counts[$key] is not set, use the value 0". Null Coalescing was explicitly designed to provide for this behaviour. -- Mark Randall
  106766
August 28, 2019 19:30 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> But @$foo++ is just a really bad way of writing either $foo++ or $foo = 1.
If you're working in an environment where you aren't sure if $foo has been mentioned already or not (ideally, you never have to, practically, you sometimes are) it's much easier to just do $foo++ than write code to figure out whether $foo has been already initialized. Note that while a lot of PHP code is written in IDE-assisted unit-tested statically-analyzed CI-gated environments, it's not all PHP code. Sometimes you want to do stuff in quick-n-dirty way, even if it's not exactly production grade, and PHP traditionally has been excellent (probably one of the best languages around) for that. I think we shouldn't abandon that. -- Stas Malyshev smalyshev@gmail.com
  106716
August 28, 2019 11:07 markyr@gmail.com (Mark Randall)
On 28/08/2019 10:33, Nikita Popov wrote:

This is an absolutely outstanding move and I certainly hope it gets 
passed unanimously.

PHP as a whole has traditionally been a language that is insanely 
forgiving of errors, in many cases allowing code execution to continue 
as if they never even happened, even in utterly egregious cases, and 
that is certainly something that has played a part in PHP's reputational 
difficulties.

I am extremely happy to see this and other changes underway to reverse 
these historic failings. It can only be a good thing for the PHP 
ecosystem as a whole to have the engine and core extensions enforce 
better protections against bad or potentially buggy code.

It won't be an instant transition, and there will be a lot of hold-outs 
on 7.4 who just don't want to deal with it, but as people do eventually 
migrate to 8.0, this error-throwing behaviour will force programmers to 
improve their code rather than just consign the problem to the /dev/null 
error log.

These changes are, no doubt, going to be a painful wake up call for our 
friends in the community who are, shall we say, not as focused on the 
quality of their code as we (and their customers) would perhaps like 
them to be.

For everyone else, it's one more tool to help make us aware of problems, 
and prevent those problems from propagating along the stack and 
effecting other things.

Bring it on.

--
Mark Randall
  106718
August 28, 2019 11:27 rowan.collins@gmail.com (Rowan Tommins)
On Wed, 28 Aug 2019 at 10:33, Nikita Popov ppv@gmail.com> wrote:

> I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. >
While I agree with the reasoning behind this, I think we should be very, very careful of promoting anything beyond Warning. While it's certainly true that bugs may be hiding behind Notices and Warnings, it's equally certain that there is code that is poorly written but has entirely correct behaviour; for such code, the cure will be worse than the disease, because an unhandled Error is like suddenly pulling the plug out of the server in the middle of a transaction. That's why I was very careful with my undefined constant RFC [1] to first raise the Notice to a Warning, and leave an appropriate period before raising to Error. I would be 100% behind raising undefined variable from Notice to Warning, but think the impact of raising to Error is high enough that it would risk delaying take-up of PHP 8. Is it too late to raise to Warning in 7.4, with a clear message that it will be an error in 8.0? That would give time for people to discover it in rare code paths, get changes pushed to third-party libraries, etc, before it becomes an unavoidable error. [1] https://wiki.php.net/rfc/deprecate-bareword-strings -- Rowan Collins [IMSoP]
  106730
August 28, 2019 14:22 matthewmatthew@gmail.com (Matthew Brown)
Looking at our notice logs, I estimate (fairly roughly) that it would
require about a week's worth of my time to fix these issues in vimeo.com’s
700K LOC codebase (the undefined variables are confined to our views).

IMO it's akin to taking the training wheels off the language – I think the
PHP ecosystem is mature enough to deal with the change.

On Wed, 28 Aug 2019 at 05:34, Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. > > I've prepared an RFC with some suggested classifications, though there's > room for bikeshedding here... > > https://wiki.php.net/rfc/engine_warnings > > Regards, > Nikita >
  106737
August 28, 2019 14:56 rowan.collins@gmail.com (Rowan Collins)
On 28 August 2019 15:22:22 BST, Matthew Brown <matthewmatthew@gmail.com> wrote:
>Looking at our notice logs, I estimate (fairly roughly) that it would >require about a week's worth of my time to fix these issues
I honestly thought you were posting that as an argument against. A week of resource (plus the accompanying QA impact etc) is a significant investment for many organisations. That's why it has the potential to delay adoption of a new version, and why a long lead-in via deprecation or opt-in is necessary. Regards, -- Rowan Collins [IMSoP]
  106738
August 28, 2019 15:05 ocramius@gmail.com (Marco Pivetta)
On Wed, Aug 28, 2019 at 4:56 PM Rowan Collins collins@gmail.com>
wrote:

> On 28 August 2019 15:22:22 BST, Matthew Brown <matthewmatthew@gmail.com> > wrote: > >Looking at our notice logs, I estimate (fairly roughly) that it would > >require about a week's worth of my time to fix these issues > > I honestly thought you were posting that as an argument against. A week of > resource (plus the accompanying QA impact etc) is a significant investment > for many organisations. That's why it has the potential to delay adoption > of a new version, and why a long lead-in via deprecation or opt-in is > necessary. >
A week for 700KLOC is *impressively low*. Many organisations spend more time on *deciding* whether to upgrade a patch version of a dependency, and the tooling that vimeo has provided to detect these issues is technically impressive, and very much usable by other orgs too. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/
  106749
August 28, 2019 16:38 rowan.collins@gmail.com (Rowan Collins)
On 28 August 2019 16:05:13 BST, Marco Pivetta <ocramius@gmail.com> wrote:
>A week for 700KLOC is *impressively low*. >Many organisations spend more time on *deciding* whether to upgrade a >patch >version of a dependency, and the tooling that vimeo has provided to >detect >these issues is technically impressive, and very much usable by other >orgs >too.
I literally have no idea what to take from that response. Some organisations are slow, some have cool workflows, so let's break all the things? Regards, -- Rowan Collins [IMSoP]
  106750
August 28, 2019 16:45 ocramius@gmail.com (Marco Pivetta)
On Wed, Aug 28, 2019, 18:38 Rowan Collins collins@gmail.com> wrote:

> On 28 August 2019 16:05:13 BST, Marco Pivetta <ocramius@gmail.com> wrote: > >A week for 700KLOC is *impressively low*. > >Many organisations spend more time on *deciding* whether to upgrade a > >patch > >version of a dependency, and the tooling that vimeo has provided to > >detect > >these issues is technically impressive, and very much usable by other > >orgs > >too. > > > I literally have no idea what to take from that response. Some > organisations are slow, some have cool workflows, so let's break all the > things? > > Regards, > > -- > Rowan Collins > [IMSoP] >
The point is that "some organisations do X" is always used as an excuse for turning language design mistakes into BC boundaries.
>
  106753
August 28, 2019 17:00 rowan.collins@gmail.com (Rowan Collins)
On 28 August 2019 17:45:50 BST, Marco Pivetta <ocramius@gmail.com> wrote:
>The point is that "some organisations do X" is always used as an excuse >for >turning language design mistakes into BC boundaries.
No. Things that break compatibility are compatibility breaks. It doesn't matter if they were mistakes or fashions, if code will break, it will break. We can't change that by arguing about workflows and tools. Our job is to decide if and how to make those breaks. So, firstly, we need to agree that their is value to this particular break. I think there probably is, but people may have different opinions. Secondly, we need to think of a sensible way to introduce it. Is it responsible to put a note in an upgrading page and hope everyone spots it? Is there a way we can flag it more loudly? What is the best time frame to roll it out? Is there a way those who want to get it earlier can do so? Does that sound reasonable? Regards, -- Rowan Collins [IMSoP]
  106751
August 28, 2019 16:53 matthewmatthew@gmail.com (Matthew Brown)
It's not breaking all the things - it's breaking code that should have been
broken already, but somehow wasn't.

On Wed, 28 Aug 2019 at 12:38, Rowan Collins collins@gmail.com> wrote:

> On 28 August 2019 16:05:13 BST, Marco Pivetta <ocramius@gmail.com> wrote: > >A week for 700KLOC is *impressively low*. > >Many organisations spend more time on *deciding* whether to upgrade a > >patch > >version of a dependency, and the tooling that vimeo has provided to > >detect > >these issues is technically impressive, and very much usable by other > >orgs > >too. > > > I literally have no idea what to take from that response. Some > organisations are slow, some have cool workflows, so let's break all the > things? > > Regards, > > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
  106756
August 28, 2019 17:24 rowan.collins@gmail.com (Rowan Collins)
On 28 August 2019 17:53:55 BST, Matthew Brown <matthewmatthew@gmail.com> wrote:
>It's not breaking all the things - it's breaking code that should have >been broken already, but somehow wasn't.
It's still breaking it though. If you realise that a house is built badly and could be destroyed by a well-aimed kick, you could just give it a kick and say "ah well, not my fault"; or you could warn the owners, offer help in fixing it, and understand that they might be too busy to do it right away. I don't see why it needs to be such a big deal to ask if this is something we actually need to kick, right now. Regards, -- Rowan Collins [IMSoP]
  106757
August 28, 2019 17:45 matthewmatthew@gmail.com (Matthew Brown)
Kicking a house is a poor analogy IMO - most people don’t upgrade a major
language version without first verifying that their code still works in the
new version.

And the PHP ecosystem is strong – it's possible to find out today if your
code is likely to break (on undefined variables) with both static analysis
tools and runtime error handlers.


On Wed, 28 Aug 2019 at 13:24, Rowan Collins collins@gmail.com> wrote:

> On 28 August 2019 17:53:55 BST, Matthew Brown <matthewmatthew@gmail.com> > wrote: > >It's not breaking all the things - it's breaking code that should have > >been broken already, but somehow wasn't. > > > It's still breaking it though. > > If you realise that a house is built badly and could be destroyed by a > well-aimed kick, you could just give it a kick and say "ah well, not my > fault"; or you could warn the owners, offer help in fixing it, and > understand that they might be too busy to do it right away. > > I don't see why it needs to be such a big deal to ask if this is something > we actually need to kick, right now. > > Regards, > > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
  106762
August 28, 2019 18:41 rowan.collins@gmail.com (Rowan Collins)
On 28 August 2019 18:45:18 BST, Matthew Brown <matthewmatthew@gmail.com> wrote:
>Kicking a house is a poor analogy IMO - most people don’t upgrade a >major >language version without first verifying that their code still works in >the >new version.
Probably. Most analogies fall down pretty quickly. I just feel like some of the messages on this thread about technical debt are taking great glee in kicking other people's code, rather than offering to help fix it. Let's talk about how to make this change successful. Let's talk about what tools there are, and what their strengths and limitations are. Let's talk about making people's lives easier now, not punishing them for past mistakes. Regards, -- Rowan Tommins [IMSoP]
  106740
August 28, 2019 15:32 matthewmatthew@gmail.com (Matthew Brown)
It's essentially tech debt, and the language has allowed its users to
accrue a ton of it.

The longer that's allowed (deprecations/warnings prolong the issue in my
opinion) the harder it will be to fix the issues.

On Wed, 28 Aug 2019 at 10:56, Rowan Collins collins@gmail.com> wrote:

> On 28 August 2019 15:22:22 BST, Matthew Brown <matthewmatthew@gmail.com> > wrote: > >Looking at our notice logs, I estimate (fairly roughly) that it would > >require about a week's worth of my time to fix these issues > > I honestly thought you were posting that as an argument against. A week of > resource (plus the accompanying QA impact etc) is a significant investment > for many organisations. That's why it has the potential to delay adoption > of a new version, and why a long lead-in via deprecation or opt-in is > necessary. > > Regards, > > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
  106744
August 28, 2019 16:05 mails@thomasbley.de (Thomas Bley)
Normally every code base has old and new code, some is actively maintained, some is probably third-party maintained, some is unmaintained. Business normally not calculates costs for upgrading, securing, GDPRing old code, so bigger changes always leave some people behind.
I would prefer to write new code with sth like declare(strict_variables=1); or declare(SomeNamespace\Foo:strict_variables=1); That way, people can write new code in a better way, include new libraries and upgrade old code piece by piece without any big pressure.

Regards
Thomas

> Matthew Brown <matthewmatthew@gmail.com> hat am 28. August 2019 um 17:32 geschrieben: > > > It's essentially tech debt, and the language has allowed its users to > accrue a ton of it. > > The longer that's allowed (deprecations/warnings prolong the issue in my > opinion) the harder it will be to fix the issues. > > On Wed, 28 Aug 2019 at 10:56, Rowan Collins collins@gmail.com> wrote: > > On 28 August 2019 15:22:22 BST, Matthew Brown <matthewmatthew@gmail.com> > > wrote: > > >Looking at our notice logs, I estimate (fairly roughly) that it would > > >require about a week's worth of my time to fix these issues > > I honestly thought you were posting that as an argument against. A week of > > resource (plus the accompanying QA impact etc) is a significant investment > > for many organisations. That's why it has the potential to delay adoption > > of a new version, and why a long lead-in via deprecation or opt-in is > > necessary. > > Regards, > > -- > > Rowan Collins > > [IMSoP] > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > >
  106747
August 28, 2019 16:21 matthewmatthew@gmail.com (Matthew Brown)
FWIW: all the runtime notices in our codebase come from internally-created code.

Requiring declare(strict_variables=1) to get this (better) behaviour punishes future users of PHP for our past mistakes.

> On Aug 28, 2019, at 12:05 PM, Thomas Bley <mails@thomasbley.de> wrote: > > Normally every code base has old and new code, some is actively maintained, some is probably third-party maintained, some is unmaintained. Business normally not calculates costs for upgrading, securing, GDPRing old code, so bigger changes always leave some people behind. > I would prefer to write new code with sth like declare(strict_variables=1); or declare(SomeNamespace\Foo:strict_variables=1); That way, people can write new code in a better way, include new libraries and upgrade old code piece by piece without any big pressure. > > Regards > Thomas > >> Matthew Brown <matthewmatthew@gmail.com> hat am 28. August 2019 um 17:32 geschrieben: >> >> >> It's essentially tech debt, and the language has allowed its users to >> accrue a ton of it. >> >> The longer that's allowed (deprecations/warnings prolong the issue in my >> opinion) the harder it will be to fix the issues. >> >>> On Wed, 28 Aug 2019 at 10:56, Rowan Collins collins@gmail.com> wrote: >>> On 28 August 2019 15:22:22 BST, Matthew Brown <matthewmatthew@gmail.com> >>> wrote: >>>> Looking at our notice logs, I estimate (fairly roughly) that it would >>>> require about a week's worth of my time to fix these issues >>> I honestly thought you were posting that as an argument against. A week of >>> resource (plus the accompanying QA impact etc) is a significant investment >>> for many organisations. That's why it has the potential to delay adoption >>> of a new version, and why a long lead-in via deprecation or opt-in is >>> necessary. >>> Regards, >>> -- >>> Rowan Collins >>> [IMSoP] >>> -- >>> PHP Internals - PHP Runtime Development Mailing List >>> To unsubscribe, visit: http://www.php.net/unsub.php >>>
  106826
August 31, 2019 03:23 mails@thomasbley.de (Thomas Bley)
That's a good point, maybe a compromise is this:

> Matthew Brown <matthewmatthew@gmail.com> hat am 28. August 2019 um 18:21 geschrieben:
> 
> 
> FWIW: all the runtime notices in our codebase come from internally-created code.
> 
> Requiring declare(strict_variables=1) to get this (better) behaviour punishes future users of PHP for our past mistakes.
> > On Aug 28, 2019, at 12:05 PM, Thomas Bley <mails@thomasbley.de> wrote:
> > 
> > Normally every code base has old and new code, some is actively maintained, some is probably third-party maintained, some is unmaintained. Business normally not calculates costs for upgrading, securing, GDPRing old code, so bigger changes always leave some people behind.
> > I would prefer to write new code with sth like declare(strict_variables=1); or declare(SomeNamespace\Foo:strict_variables=1); That way, people can write new code in a better way, include new libraries and upgrade old code piece by piece without any big pressure.
> > 
> > Regards
> > Thomas
> > > Matthew Brown <matthewmatthew@gmail.com> hat am 28. August 2019 um 17:32 geschrieben:
> > > 
> > > 
> > > It's essentially tech debt, and the language has allowed its users to
> > > accrue a ton of it.
> > > 
> > > The longer that's allowed (deprecations/warnings prolong the issue in my
> > > opinion) the harder it will be to fix the issues.
> > > > On Wed, 28 Aug 2019 at 10:56, Rowan Collins collins@gmail.com> wrote:
> > > > On 28 August 2019 15:22:22 BST, Matthew Brown <matthewmatthew@gmail.com>
> > > > wrote:
> > > > > Looking at our notice logs, I estimate (fairly roughly) that it would
> > > > > require about a week's worth of my time to fix these issues
> > > > I honestly thought you were posting that as an argument against. A week of
> > > > resource (plus the accompanying QA impact etc) is a significant investment
> > > > for many organisations. That's why it has the potential to delay adoption
> > > > of a new version, and why a long lead-in via deprecation or opt-in is
> > > > necessary.
> > > > Regards,
> > > > --
> > > > Rowan Collins
> > > > [IMSoP]
> > > > --
> > > > PHP Internals - PHP Runtime Development Mailing List
> > > > To unsubscribe, visit: http://www.php.net/unsub.php
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
  106828
September 1, 2019 19:06 andreas@dqxtech.net (Andreas Hennings)
I think we should distinguish two separate problems in the discussion:

1. Undeclared local variables in function scope. Some poeple here
think this "lazy" way of coding is actually more productive.

Fixing such places would be straightforward.. except that it may
require patching some legacy 3rd party code.

2. Undeclared values, or values of unexpected type, in variables
coming from elsewhere:
- variables used in file scope, e.g. in template files, which are
declared in a different file.
- any global variables.
- values in nested arrays, which might have been set in some other
place before they get passed to the current function.

Typically these cases are hard to fix and troubleshoot.
Especially, even if you think you fixed it, there can be some dynamic
conditions that are really hard to test.
E.g. if the username begins with a capital letter, the variable will
be undefined, or a specific array value will be an object instead of a
string..

Ideally such systems should be avoided, or they will need a lot of
try/catch to deal with such problems in the future.
But a lot of legacy code was not written with sufficient sanity
checks, and accepts the occasional or regular notice.

Perhaps is about time for this level of breakage in PHP8. I just want
us to be aware of it.

On Sat, 31 Aug 2019 at 05:23, Thomas Bley <mails@thomasbley.de> wrote:
> > That's a good point, maybe a compromise is this: > > > That way new users can always use I am not sure about all the possible implications of this specific syntax, but I think it would fit into the "editions" idea from the other thread, if I am not misunderstanding Nikic.
> > Regards > Thomas > > > Matthew Brown <matthewmatthew@gmail.com> hat am 28. August 2019 um 18:21 geschrieben: > > > > > > FWIW: all the runtime notices in our codebase come from internally-created code. > > > > Requiring declare(strict_variables=1) to get this (better) behaviour punishes future users of PHP for our past mistakes. > > > On Aug 28, 2019, at 12:05 PM, Thomas Bley <mails@thomasbley.de> wrote: > > > > > > Normally every code base has old and new code, some is actively maintained, some is probably third-party maintained, some is unmaintained. Business normally not calculates costs for upgrading, securing, GDPRing old code, so bigger changes always leave some people behind.
yes..
> > > I would prefer to write new code with sth like declare(strict_variables=1); or declare(SomeNamespace\Foo:strict_variables=1); That way, people can write new code in a better way, include new libraries and upgrade old code piece by piece without any big pressure. > > > > > > Regards > > > Thomas > > > > Matthew Brown <matthewmatthew@gmail.com> hat am 28. August 2019 um 17:32 geschrieben: > > > > > > > > > > > > It's essentially tech debt, and the language has allowed its users to > > > > accrue a ton of it. > > > > > > > > The longer that's allowed (deprecations/warnings prolong the issue in my > > > > opinion) the harder it will be to fix the issues. > > > > > On Wed, 28 Aug 2019 at 10:56, Rowan Collins collins@gmail.com> wrote: > > > > > On 28 August 2019 15:22:22 BST, Matthew Brown <matthewmatthew@gmail.com> > > > > > wrote: > > > > > > Looking at our notice logs, I estimate (fairly roughly) that it would > > > > > > require about a week's worth of my time to fix these issues > > > > > I honestly thought you were posting that as an argument against. A week of > > > > > resource (plus the accompanying QA impact etc) is a significant investment > > > > > for many organisations. That's why it has the potential to delay adoption > > > > > of a new version, and why a long lead-in via deprecation or opt-in is > > > > > necessary. > > > > > Regards, > > > > > -- > > > > > Rowan Collins > > > > > [IMSoP] > > > > > -- > > > > > PHP Internals - PHP Runtime Development Mailing List > > > > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
  106752
August 28, 2019 16:55 zeev@php.net (Zeev Suraski)
On Wed, Aug 28, 2019 at 5:22 PM Matthew Brown <matthewmatthew@gmail.com>
wrote:

> Looking at our notice logs, I estimate (fairly roughly) that it would > require about a week's worth of my time to fix these issues in vimeo.com’s > 700K LOC codebase (the undefined variables are confined to our views). >
Can you elaborate a bit about how you generally deal with notices in vimeo.com - are you generally aiming to be notice-free? Or is that log collecting a huge amount of messages? Zeev
  106755
August 28, 2019 17:20 matthewmatthew@gmail.com (Matthew Brown)
We log 1 in every 1000 notices, and yes - being notice-free is a goal –
though not one with any particular timeline at the moment, because we can
just ignore the problem. I look forward to not being able to ignore the
problem.

On Wed, 28 Aug 2019 at 12:55, Zeev Suraski <zeev@php.net> wrote:

> > > On Wed, Aug 28, 2019 at 5:22 PM Matthew Brown <matthewmatthew@gmail.com> > wrote: > >> Looking at our notice logs, I estimate (fairly roughly) that it would >> require about a week's worth of my time to fix these issues in vimeo.com >> ’s >> 700K LOC codebase (the undefined variables are confined to our views). >> > > Can you elaborate a bit about how you generally deal with notices in > vimeo.com - are you generally aiming to be notice-free? Or is that log > collecting a huge amount of messages? > > Zeev >
  106761
August 28, 2019 18:31 zeev@php.net (Zeev Suraski)
On Wed, Aug 28, 2019 at 8:20 PM Matthew Brown <matthewmatthew@gmail.com>
wrote:

> We log 1 in every 1000 notices, and yes - being notice-free is a goal – > though not one with any particular timeline at the moment, because we can > just ignore the problem. I look forward to not being able to ignore the > problem.
When was this goal set? Was there effort that went into it? My point is this: In a codebase where being notice-free isn't a goal - and/or where code patterns that rely on the documented behavior of how PHP variables are initialized as well as behave in read scenarios (with or without the silence operator) - I think you're going to find a lot of such instances, probably more so than in a company that made an informed decision to not allow it and gradually work to remove existing code that uses it. For many, this is not considered technical debt - but rather - using the language *as intended*. Using the language in a way that is sanctioned and considered valid - alongside other ways which are also considered valid (e.g. a notice-free codebase). While I understand what you're saying when you say that you look forward to not being able to ignore the problem, it sounds like a fairly weak argument for forcing everyone else - many of whom don't consider this to be a problem at all - to change their code. Instead, if this bothers you, make an informed decision to change - there's enough tooling to do that today with reasonable effort. Or support the ability to flip a switch that will granularly force you to fix these particular issues. Forcing all users to work in a certain way, because some of the users who want to work that way can't bring themselves to do it - doesn't sound very sensible IMHO. I was hoping that the glaring obviousness of how other languages tackled similar issues (Perl, JS) would go a longer way. It should. Zeev
  106763
August 28, 2019 18:42 chasepeeler@gmail.com (Chase Peeler)
On Wed, Aug 28, 2019 at 2:32 PM Zeev Suraski <zeev@php.net> wrote:

> On Wed, Aug 28, 2019 at 8:20 PM Matthew Brown <matthewmatthew@gmail.com> > wrote: > > > We log 1 in every 1000 notices, and yes - being notice-free is a goal – > > though not one with any particular timeline at the moment, because we can > > just ignore the problem. I look forward to not being able to ignore the > > problem. > > > When was this goal set? Was there effort that went into it? > > My point is this: > > In a codebase where being notice-free isn't a goal - and/or where code > patterns that rely on the documented behavior of how PHP variables are > initialized as well as behave in read scenarios (with or without the > silence operator) - I think you're going to find a lot of such instances, > probably more so than in a company that made an informed decision to not > allow it and gradually work to remove existing code that uses it. For > many, this is not considered technical debt - but rather - using the > language *as intended*. Using the language in a way that is sanctioned and > considered valid - alongside other ways which are also considered valid > (e.g. a notice-free codebase). >
For the record, I don't view undeclared variable notices as technical debt either. I've engaged in that discussion at other points because I think this is a bad move even if it is considered technical debt. My personal opinion is that I like the flexibility of the language in this matter. I initialize my variables most of the time anyway, but, I don't think every other PHP developer should be forced to do that just because I like to do it.
> > While I understand what you're saying when you say that you look forward to > not being able to ignore the problem, it sounds like a fairly weak argument > for forcing everyone else - many of whom don't consider this to be a > problem at all - to change their code. Instead, if this bothers you, make > an informed decision to change - there's enough tooling to do that today > with reasonable effort. Or support the ability to flip a switch that will > granularly force you to fix these particular issues. Forcing all users to > work in a certain way, because some of the users who want to work that way > can't bring themselves to do it - doesn't sound very sensible IMHO. > > My feelings exactly. What benefits are we getting by FORCING everyone to
follow this policy that individual users/companies/development teams can't already gain by just making it a policy and using 3rd party tools to enforce it? What HARM continues to exist in the language if undeclared variables only generate a notice - given the fact that how PHP handles undeclared variables is will documented and, in my opinion, actually a feature of the language?
> I was hoping that the glaring obviousness of how other languages tackled > similar issues (Perl, JS) would go a longer way. It should. > > Zeev >
-- Chase Peeler chasepeeler@gmail.com
  106765
August 28, 2019 19:28 matthewmatthew@gmail.com (Matthew Brown)
Javascript has treated undefined variables as a catchable exceptions since
(I think?) forever. Perl is the only other language I know that allows them..

I've written code in a lot of different languages. Many of those languages
(most notably Standard ML) forced me to think about how exactly data flowed
through my program. PHP, on the other hand, doesn't demand anything like as
much work. This means its developers often don't improve much either, which
ultimately this harms the language's reputation as former PHP developers
discover their bad habits don't translate well to other languages.

With this change we can make it harder for people to write bad code, which
I think will result in existing PHP users becoming better developers.

On Wed, 28 Aug 2019 at 14:32, Zeev Suraski <zeev@php.net> wrote:

> > > On Wed, Aug 28, 2019 at 8:20 PM Matthew Brown <matthewmatthew@gmail.com> > wrote: > >> We log 1 in every 1000 notices, and yes - being notice-free is a goal – >> though not one with any particular timeline at the moment, because we can >> just ignore the problem. I look forward to not being able to ignore the >> problem. > > > When was this goal set? Was there effort that went into it? > > My point is this: > > In a codebase where being notice-free isn't a goal - and/or where code > patterns that rely on the documented behavior of how PHP variables are > initialized as well as behave in read scenarios (with or without the > silence operator) - I think you're going to find a lot of such instances, > probably more so than in a company that made an informed decision to not > allow it and gradually work to remove existing code that uses it. For > many, this is not considered technical debt - but rather - using the > language *as intended*. Using the language in a way that is sanctioned and > considered valid - alongside other ways which are also considered valid > (e.g. a notice-free codebase). > > While I understand what you're saying when you say that you look forward > to not being able to ignore the problem, it sounds like a fairly weak > argument for forcing everyone else - many of whom don't consider this to be > a problem at all - to change their code. Instead, if this bothers you, > make an informed decision to change - there's enough tooling to do that > today with reasonable effort. Or support the ability to flip a switch that > will granularly force you to fix these particular issues. Forcing all > users to work in a certain way, because some of the users who want to work > that way can't bring themselves to do it - doesn't sound very sensible IMHO. > > I was hoping that the glaring obviousness of how other languages tackled > similar issues (Perl, JS) would go a longer way. It should. > > Zeev >
  106771
August 28, 2019 20:01 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> Javascript has treated undefined variables as a catchable exceptions since > (I think?) forever.
Which seems to be why I open a random Javascript file in our codebase and see this: var wikibase = wikibase || {}; wikibase.queryService = wikibase.queryService || {}; wikibase.queryService.ui = wikibase.queryService.ui || {}; wikibase.queryService.ui.toolbar = wikibase.queryService.toolbar || {}; wikibase.queryService.ui.toolbar.Actionbar = ... (not my code but I've seen it a lot) IMHO, this is language getting in a way and people writing boilerplate to avoid "service" that is not actually needed.
> much work. This means its developers often don't improve much either, which
I don't think PHP should be a language that "builds character" by forcing people to do more work than it's necessary for them, in order for them to "improve". I think it should be as easy as possible, and if somebody wants to learn how the bits move, one can always pick up a good book or go to a Coursera course, etc. -- Stas Malyshev smalyshev@gmail.com
  106775
August 28, 2019 21:12 matthewmatthew@gmail.com (Matthew Brown)
If we want PHP to be as easy as possible then $nullref->bar(), $foo->someUndefined(), new UndefinedClass etc shouldn’t be exceptions either - they can just be notices. 

> On Aug 28, 2019, at 4:01 PM, Stanislav Malyshev <smalyshev@gmail.com> wrote: > > Hi! > >> Javascript has treated undefined variables as a catchable exceptions since >> (I think?) forever. > > Which seems to be why I open a random Javascript file in our codebase > and see this: > > var wikibase = wikibase || {}; > wikibase.queryService = wikibase.queryService || {}; > wikibase.queryService.ui = wikibase.queryService.ui || {}; > wikibase.queryService.ui.toolbar = wikibase.queryService.toolbar || {}; > > wikibase.queryService.ui.toolbar.Actionbar = ... > > (not my code but I've seen it a lot) > IMHO, this is language getting in a way and people writing boilerplate > to avoid "service" that is not actually needed. > >> much work. This means its developers often don't improve much either, which > > I don't think PHP should be a language that "builds character" by > forcing people to do more work than it's necessary for them, in order > for them to "improve". I think it should be as easy as possible, and if > somebody wants to learn how the bits move, one can always pick up a good > book or go to a Coursera course, etc. > > -- > Stas Malyshev > smalyshev@gmail.com
  106776
August 28, 2019 21:21 truth@proposaltech.com (Todd Ruth)
> If we want PHP to be as easy as possible then $nullref->bar(), $foo->someUndefined(), > new UndefinedClass etc shouldn’t be exceptions either - they can just be notices.
That's very different. Note that this code doesn't even generate a notice: $x = null; var_dump($x+1); I'm joining the thread to point out another way to avoid the notice in hopes that this way doesn't get deprecated or somesuch: $temp =& $never_defined; // No notice :) $temp++; // Happily becomes 1 if $never_defined wasn't defined unset($temp); // so we don't unintentionally make more changes with $temp later Our code predates "??" and we use the above boilerplate in many, many places, but it isn't boilerplate enough to easily search and replace. - Todd
> On Aug 28, 2019, at 4:01 PM, Stanislav Malyshev <smalyshev@gmail.com> wrote: > > Hi! > >> Javascript has treated undefined variables as a catchable exceptions since >> (I think?) forever. > > Which seems to be why I open a random Javascript file in our codebase > and see this: > > var wikibase = wikibase || {}; > wikibase.queryService = wikibase.queryService || {}; > wikibase.queryService.ui = wikibase.queryService.ui || {}; > wikibase.queryService.ui.toolbar = wikibase.queryService.toolbar || {}; > > wikibase.queryService.ui.toolbar.Actionbar = ... > > (not my code but I've seen it a lot) > IMHO, this is language getting in a way and people writing boilerplate > to avoid "service" that is not actually needed. > >> much work. This means its developers often don't improve much either, which > > I don't think PHP should be a language that "builds character" by > forcing people to do more work than it's necessary for them, in order > for them to "improve". I think it should be as easy as possible, and if > somebody wants to learn how the bits move, one can always pick up a good > book or go to a Coursera course, etc. > > -- > Stas Malyshev > smalyshev@gmail.com
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
  106777
August 28, 2019 22:06 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> If we want PHP to be as easy as possible then $nullref->bar(), > $foo->someUndefined(), new UndefinedClass etc shouldn’t be exceptions > either - they can just be notices.
I don't see how it follows. Calling unknown method does not have natural default - if I tell you "would you please do abracadabra" you can't just do something random and consider it done - you should tell me "what do you mean by that? Please explain what you want me to do". However, if I tell you "here's an apple, add it to your pocket", then there's a natural way of knowing how many apples is in your pocket for every state of your pocket before - if your pocket was empty, it now has one apple, if it had apples before, now it has one more. I don't need to explain you what to do when your pocket is empty and when it's not separately - you can guess intuitively what should happen in each case and you'd be 100% right always. That's the natural difference between $foo++ and foo() - in the former case, you know what should happen in any case (including when $foo is initialized to a non-numeric value - *then* you error out), in the latter, if foo() is not defined, there's no natural way to go but to error out. There's a crucial difference here because variables are containers, not actors. Dealing with an empty container has natural semantics (in some cases at least), dealing with non-existing actor does not. -- Stas Malyshev smalyshev@gmail.com
  106778
August 28, 2019 22:37 matthewmatthew@gmail.com (Matthew Brown)
This is where I think PHP may have broken us a little.

I just asked a few non-PHP developers here what they expect "(function () {
$a++; })()" to do, and they agreed it would be some sort of error. Got the
same answer for "(function () { $a->bar = 5; })() ".

Indeed, anyone who's used another C-like language (JS, TS, Java, C# etc) is
used to these things being errors, so it can be disorientating to see them
treated as anything else by PHP (it was disorientating for me, at least).

On Wed, 28 Aug 2019 at 18:06, Stanislav Malyshev <smalyshev@gmail.com>
wrote:

> Hi! > > > If we want PHP to be as easy as possible then $nullref->bar(), > > $foo->someUndefined(), new UndefinedClass etc shouldn’t be exceptions > > either - they can just be notices. > > I don't see how it follows. Calling unknown method does not have natural > default - if I tell you "would you please do abracadabra" you can't just > do something random and consider it done - you should tell me "what do > you mean by that? Please explain what you want me to do". > However, if I tell you "here's an apple, add it to your pocket", then > there's a natural way of knowing how many apples is in your pocket for > every state of your pocket before - if your pocket was empty, it now has > one apple, if it had apples before, now it has one more. I don't need to > explain you what to do when your pocket is empty and when it's not > separately - you can guess intuitively what should happen in each case > and you'd be 100% right always. > > That's the natural difference between $foo++ and foo() - in the former > case, you know what should happen in any case (including when $foo is > initialized to a non-numeric value - *then* you error out), in the > latter, if foo() is not defined, there's no natural way to go but to > error out. There's a crucial difference here because variables are > containers, not actors. Dealing with an empty container has natural > semantics (in some cases at least), dealing with non-existing actor does > not. > -- > Stas Malyshev > smalyshev@gmail.com >
  106779
August 28, 2019 22:52 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> This is where I think PHP may have broken us a little.
I think it's in no way "broken" to be able to easily match expectations, like $foo++ always do what you meant without clunky boilerplate. Also, if you think PHP is the only language I program in daily (and I mean every day, except some weekends and vacations maybe) you're wrong :) I have something to compare to, so what I say some things are easier in PHP that's because I actually compared.
> I just asked a few non-PHP developers here what they expect "(function > () { $a++; })()" to do, and they agreed it would be some sort of error. > Got the same answer for "(function () { $a->bar = 5; })() ".
I see absolutely no reason for it. Maybe if you're a Java programmer who never saw non-statically-typed non-B&D language - but that's not a virtue we should be striving to emulate. If we have a tool that already does things better and some people don't even know such tools are possible, we should educate them, not break our tools so it would be more comfortable fit to their experience.
> Indeed, anyone who's used another C-like language (JS, TS, Java, C# etc) > is used to these things being errors, so it can be disorientating to see
I don't think having things just work instead of usual boilerplate that you have to declare everything upfront and repeat even obvious things numerous times is "disorienting" in any way. If you check how languages that are alive evolve (like Java or C++, C is mostly fossilized these days), even strict ones, you see they support more and more intuitive approaches - like auto variables for example - which make things easier. Because human should spend time thinking, not figuring out how to satisfy a dumb compiler. That's the direction we should be moving to. Not adding more errors and boilerplate in clear cases like $foo++. -- Stas Malyshev smalyshev@gmail.com
  106780
August 28, 2019 23:23 matthewmatthew@gmail.com (Matthew Brown)
$foo++ becoming 1 when $foo is undefined is not intuitive to me.

To take a very trivial example, that behaviour causes “for ($i = 0; $i < 10; $I++) {}” to loop indefinitely.

> On Aug 28, 2019, at 6:52 PM, Stanislav Malyshev <smalyshev@gmail.com> wrote: > > Hi! > >> This is where I think PHP may have broken us a little. > > I think it's in no way "broken" to be able to easily match expectations, > like $foo++ always do what you meant without clunky boilerplate. > Also, if you think PHP is the only language I program in daily (and I > mean every day, except some weekends and vacations maybe) you're wrong > :) I have something to compare to, so what I say some things are easier > in PHP that's because I actually compared. > >> I just asked a few non-PHP developers here what they expect "(function >> () { $a++; })()" to do, and they agreed it would be some sort of error. >> Got the same answer for "(function () { $a->bar = 5; })() ". > > I see absolutely no reason for it. Maybe if you're a Java programmer who > never saw non-statically-typed non-B&D language - but that's not a > virtue we should be striving to emulate. If we have a tool that already > does things better and some people don't even know such tools are > possible, we should educate them, not break our tools so it would be > more comfortable fit to their experience. > >> Indeed, anyone who's used another C-like language (JS, TS, Java, C# etc) >> is used to these things being errors, so it can be disorientating to see > > I don't think having things just work instead of usual boilerplate that > you have to declare everything upfront and repeat even obvious things > numerous times is "disorienting" in any way. If you check how languages > that are alive evolve (like Java or C++, C is mostly fossilized these > days), even strict ones, you see they support more and more intuitive > approaches - like auto variables for example - which make things easier. > Because human should spend time thinking, not figuring out how to > satisfy a dumb compiler. That's the direction we should be moving to. > Not adding more errors and boilerplate in clear cases like $foo++. > > -- > Stas Malyshev > smalyshev@gmail.com
  106781
August 28, 2019 23:33 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

On 8/28/19 4:23 PM, Matthew Brown wrote:
> $foo++ becoming 1 when $foo is undefined is not intuitive to me.
I guess we have different intuition.
> To take a very trivial example, that behaviour causes “for ($i = 0; > $i < 10; $I++) {}” to loop indefinitely. This is rather shallow issue, which any modern IDE would highlight for
you in about 0.5 seconds. No need to change the language for that. Frankly, I have hard time remembering when any of such typos ever get past IDE check since I started using IDEs. And, of course, it's completely obvious issue - you could as well forget to write $i++ at all, or write $j++ and have $j defined somewhere... there's a lot of artificial scenarios one could think of. No reason to change rules of the whole language because of it. -- Stas Malyshev smalyshev@gmail.com
  106782
August 28, 2019 23:43 hisamsonolu@gmail.com (Olumide Samson)
On Thu, Aug 29, 2019, 12:33 AM Stanislav Malyshev <smalyshev@gmail.com>
wrote:

> Hi! > > On 8/28/19 4:23 PM, Matthew Brown wrote: > > $foo++ becoming 1 when $foo is undefined is not intuitive to me. > > I guess we have different intuition. > > > To take a very trivial example, that behaviour causes “for ($i = 0; > > $i < 10; $I++) {}” to loop indefinitely. > This is rather shallow issue, which any modern IDE would highlight for > you in about 0.5 seconds. No need to change the language for that. > Frankly, I have hard time remembering when any of such typos ever get > past IDE check since I started using IDEs. > And, of course, it's completely obvious issue - you could as well forget > to write $i++ at all, or write $j++ and have $j defined somewhere... > there's a lot of artificial scenarios one could think of. No reason to > change rules of the whole language because of it. >
Can you point me to an IDE that runs on the server? I think you are mixing static analysis error with dynamic runtime analysis. IDE can't point to an error it doesn't know about(which I didn't code using IDE but use notepad, where I didn't run full test before publishing to production). I don't think it makes sense to allow the language be a home of "anything goes, no innovation". A language without specification.
  106787
August 29, 2019 05:51 zeev@php.net (Zeev Suraski)
On Wed, Aug 28, 2019 at 10:28 PM Matthew Brown <matthewmatthew@gmail.com>
wrote:

> Javascript has treated undefined variables as a catchable exceptions since > (I think?) forever. Perl is the only other language I know that allows them. >
That isn't the point (I alluded to the fact that JS dealt with something *similar* but not quite the same in my first mention of it). The point is that when they wanted to make behavior around variables strict*er* than what it was originally, they didn't simply change it - they added an opt-in strict mode. I've written code in a lot of different languages. Many of those languages
> (most notably Standard ML) forced me to think about how exactly data flowed > through my program. PHP, on the other hand, doesn't demand anything like as > much work. This means its developers often don't improve much either, which > ultimately this harms the language's reputation as former PHP developers > discover their bad habits don't translate well to other languages. > > With this change we can make it harder for people to write bad code, which > I think will result in existing PHP users becoming better developers. >
With this change we're taking away from people - including very informed developers - the ability to use it as intended (one form of it that is). There's a reason there's a wide selection of languages available, and that different people have different language preferences. Personally, I can't stand ML - and I find myself a lot more productive in other languages. But I'm not going to campaign to change ML into something different because it doesn't fit my programming/thinking style. Granted - PHP is orders of magnitude more popular and widely used than ML, and we need to figure out ways to make this huge audience content - including many who aren't happy with its behavior (whether it's because they made an uninformed decision choosing it, or because it wasn't their choice at all, or because they actually do like the language and would be happy to use it if only it had X, Y and Z). But it shouldn't be at the expense of others. Exactly like Perl and JS did it when they decided to offer a stricter execution model. Zeev
  106788
August 29, 2019 06:22 drealecs@gmail.com (=?UTF-8?Q?Alexandru_P=C4=83tr=C4=83nescu?=)
Zeev,

When you write code, in a "productive" way that you mention, it's perfectly
fine if you write it for you and for now.

But most often, we write code for the future generations of developers that
could be less skilled, for the future you that might have less context.
Also, code will evolve in time and bugs will eventually apear. In my
opinion and maybe you can agree, some of these bugs could be avoided if
variable definition before reading would be enforced.
Yes, it costs us more time to do it and productivity might be decreased by
1-2%.

For most of the developers and businesses using PHP, that is a trade they
want to enforce but can't or does not know how to do it.

I am for a default with more things enforced and maybe only allowed them
based on declares, not the other way around.

Regards,
Alex


On Thu, Aug 29, 2019, 08:52 Zeev Suraski <zeev@php.net> wrote:

> On Wed, Aug 28, 2019 at 10:28 PM Matthew Brown <matthewmatthew@gmail.com> > wrote: > > > Javascript has treated undefined variables as a catchable exceptions > since > > (I think?) forever. Perl is the only other language I know that allows > them. > > > > That isn't the point (I alluded to the fact that JS dealt with something > *similar* but not quite the same in my first mention of it). The point is > that when they wanted to make behavior around variables strict*er* than > what it was originally, they didn't simply change it - they added an opt-in > strict mode. > > I've written code in a lot of different languages. Many of those languages > > (most notably Standard ML) forced me to think about how exactly data > flowed > > through my program. PHP, on the other hand, doesn't demand anything like > as > > much work. This means its developers often don't improve much either, > which > > ultimately this harms the language's reputation as former PHP developers > > discover their bad habits don't translate well to other languages. > > > > With this change we can make it harder for people to write bad code, > which > > I think will result in existing PHP users becoming better developers. > > > > With this change we're taking away from people - including very informed > developers - the ability to use it as intended (one form of it that is). > There's a reason there's a wide selection of languages available, and that > different people have different language preferences. Personally, I can't > stand ML - and I find myself a lot more productive in other languages. But > I'm not going to campaign to change ML into something different because it > doesn't fit my programming/thinking style. > > Granted - PHP is orders of magnitude more popular and widely used than ML, > and we need to figure out ways to make this huge audience content - > including many who aren't happy with its behavior (whether it's because > they made an uninformed decision choosing it, or because it wasn't their > choice at all, or because they actually do like the language and would be > happy to use it if only it had X, Y and Z). But it shouldn't be at the > expense of others. Exactly like Perl and JS did it when they decided to > offer a stricter execution model. > > Zeev >
  106789
August 29, 2019 07:28 cschneid@cschneid.com (Christian Schneider)
Am 29.08.2019 um 08:22 schrieb Alexandru Pătrănescu <drealecs@gmail.com>:
> When you write code, in a "productive" way that you mention, it's perfectly > fine if you write it for you and for now. > > But most often, we write code for the future generations of developers that > could be less skilled, for the future you that might have less context. > Also, code will evolve in time and bugs will eventually apear. In my > opinion and maybe you can agree, some of these bugs could be avoided if > variable definition before reading would be enforced.
.... and that's why Zeev suggests a strict mode for people who want it that way. Side-note: Which brings us back to the discussion about the downsides of language modes but as similar topics keep on popping up (although by the same people) you are slowly convincing me that going down that road is the best compromise.
> For most of the developers and businesses using PHP, that is a trade they > want to enforce but can't or does not know how to do it.
That "most developers" is highly subjective depending on who you ask. And yes, you can easily turn undefined variables into exceptions right now (even globally), just use set_error_handler(function($errno, $errstr) { if (preg_match('/^Undefined variable/', $errstr)) throw new Exception($errstr); return false; }, E_NOTICE);
> I am for a default with more things enforced and maybe only allowed them > based on declares, not the other way around.
Breaking code first and making migration harder instead of offering a clean migration path where developers opt-in to a new mode. - Chris
  106791
August 29, 2019 07:58 phpmailinglists@gmail.com (Peter Bowyer)
On Thu, 29 Aug 2019 at 08:28, Christian Schneider <cschneid@cschneid.com>
wrote:

> Side-note: Which brings us back to the discussion about the downsides of > language modes but as similar topics keep on popping up (although by the > same people) you are slowly convincing me that going down that road is the > best compromise. >
Is there any technical reason PHP can't go the transpiler route? Let everyone experiment with their own preferred changes, and pull the best ideas, once proven, into core PHP? Peter
  106764
August 28, 2019 19:25 nikita.ppv@gmail.com (Nikita Popov)
On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. > > I've prepared an RFC with some suggested classifications, though there's > room for bikeshedding here... > > https://wiki.php.net/rfc/engine_warnings > > Regards, > Nikita >
It seems quite clear to me that the question of the "undefined variable" error is contentious. As such, I have decided to split it off into a separate section in the proposal, that will be voted separately from the rest. I will offer the choice of throwing an Error exception (as originally proposed), throwing a warning or keeping the existing notice. Reading this discussion has been disappointing and somewhat disillusioning. I can understand and appreciate the concern for legacy code. But seeing the use of undefined variables espoused as a legitimate programming style, that just makes me sad. Regards, Nikita
  106785
August 29, 2019 05:40 zeev@php.net (Zeev Suraski)
On Wed, Aug 28, 2019 at 10:26 PM Nikita Popov ppv@gmail.com> wrote:

> On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> > wrote: > > Reading this discussion has been disappointing and somewhat disillusioning. > I can understand and appreciate the concern for legacy code. But seeing the > use of undefined variables espoused as a legitimate programming style, that > just makes me sad. >
Nikita, It's really awkward that anybody would be under the illusion that the way the language always behaved, consistently and well-documented pretty much from the its inception, is somehow a bug that everybody agrees on that's just waiting for someone to come over and fix it. Do you really think that if there was widespread consensus that this wasn't a legitimate programming style, we'd have to wait for 20 years for folks to propose to change/remove it? This isn't short tags - this is fundamental language behavior, that indeed isn't even documented anywhere as a 'bad thing you must avoid'. There are commonly used code templates that rely on it, and do it in a way many would find perfectly reasonable. Many do, and always did consider it as a legitimate programming style. Many others do not - which is why we added capabilities ages ago (from the get go, for all practical purposes) that allow users to employ a much stricter programming style by enabling notices. We never, ever, at any point, considered this behavior to be 'legacy'. It's a language feature, that you can choose whether you want to use or not (and perhaps we can get better at that). The fact that PHP isn't supposed to be a strict language is repeatedly confused with exclusive concern for 'legacy code' as of late. Yes, the complete disregard for backwards compatibility that appears to be the most widely accepted POV on internals is disconcerting - but much more importantly - just because one doesn't like a certain fundamental part of the language, doesn't make the use of it 'legacy'. If anything, it perhaps means that said person who chose the language made the wrong choice (there are plenty of other choices to choose from), and they're now campaigning to change it to fit the image of what they think it *should be* that they have in mind. With that said - I think it does make sense to try and come up with ways to cater to those who prefer a stricter language, and in this particular case - something that's a bit more aggressive than notices. But if there's something sad about this, it's the insistence to always frame the discussion as a zero sum game - instead of trying to find solutions that cater to a wider audiences. It's time to accept that the composition of PHP users is a lot wider than what's represented on internals, and it's certainly not everyone's opinion that the current language is in dire need of being rescued. PHP can be improved for those who find it lacking, without harming those who are in fact happy with the way it currently is. We should start looking for such solutions, instead of each just trying to 'win for their own camp', putting things to a vote hoping to subjugate the other. Zeev
  106793
August 29, 2019 11:33 internals@lists.php.net ("Aegir Leet via internals")
I'm sorry, but if you seriously believe doing something that generates a 
notice (or warning, or error, ...) is not a bug - you're delusional. 
That is the very definition of a bug and notices/warnings/errors etc. 
are the mechanism the language uses to report these bugs to the 
developer. If doing X has been generating a notice for 20 years, then 
doing X is wrong and a bug, period. Why would there even be a notice if 
the language itself doesn't consider what you're doing to be buggy? What 
is the purpose of notices then? I really don't understand how anyone 
could contest this.

On 29.08.19 07:40, Zeev Suraski wrote:
> > It's really awkward that anybody would be under the illusion that the way > the language always behaved, consistently and well-documented pretty much > from the its inception, is somehow a bug that everybody agrees on that's > just waiting for someone to come over and fix it.
  106795
August 29, 2019 12:43 claude.pache@gmail.com (Claude Pache)
> Le 29 août 2019 à 13:33, Aegir Leet via internals <internals@lists.php.net> a écrit : > > I'm sorry, but if you seriously believe doing something that generates a > notice (or warning, or error, ...) is not a bug - you're delusional.
No, what you think is not at all how notices were designed. From the manual (https://www.php.net/errorfunc.constants <https://www.php.net/errorfunc.constants>): E_NOTICE — Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script. One can discuss whether unitialised variables should trigger a notice or a warning. But let us respect the semantics of the language features. —Claude
  106797
August 29, 2019 13:02 internals@lists.php.net ("Aegir Leet via internals")
I know what the manual says about notices. But I don't agree with interpreting "could happen in the normal course of running a script" as "it's perfectly fine if this part of your code triggers a notice consistently and every time it goes down this particular code path". Rather, I've always interpreted this as "under certain, rare, unforeseen circumstances, your code could generate a notice here, probably because of something that is outside of your control".

That's how I've always treated them at least.

Regardless of the exact semantics, don't you think a program that generates a constant stream of notices is a bit strange? That sounds like something everyone would naturally want to avoid. You don't drive your car with the check engine light permanently on and say "this is fine", right?

On 29.08.19 14:43, Claude Pache wrote:


Le 29 août 2019 à 13:33, Aegir Leet via internals <internals@lists.php.net<mailto:internals@lists.php.net>> a écrit :

I'm sorry, but if you seriously believe doing something that generates a
notice (or warning, or error, ...) is not a bug - you're delusional.

No, what you think is not at all how notices were designed. From the manual (https://www.php.net/errorfunc.constants):

E_NOTICE  — Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.

One can discuss whether unitialised variables should trigger a notice or a warning. But let us respect the semantics of the language features.

—Claude
  106798
August 29, 2019 14:22 zeev@php.net (Zeev Suraski)
On Thu, Aug 29, 2019 at 4:02 PM Aegir Leet via internals <
internals@lists.php.net> wrote:

> I know what the manual says about notices. But I don't agree with > interpreting "could happen in the normal course of running a script" as > "it's perfectly fine if this part of your code triggers a notice > consistently and every time it goes down this particular code path". > Rather, I've always interpreted this as "under certain, rare, unforeseen > circumstances, your code could generate a notice here, probably because of > something that is outside of your control". > > That's how I've always treated them at least. >
And that's entirely within your right to do so - but what the manual says is accurate. Calling me delusional in my interpretation of it is somewhat awkward (to put it mildly), I have a pretty good idea of why we added the different error levels - I wrote much of it myself. The whole point of having notices as something that's separate from warnings is that they have different semantics, and that semantics is captured very accurately in the manual. They are used to mark issues which may be problems, but may also be perfectly fine (unlike warnings, which generally speaking mean that something bad happened, but not bad enough to halt execution). Notices were meant to help you implement a more strict style of coding, and they may help you catch certain types of bugs, but you can have perfectly working, bug-free code that generates notices. Regardless of the exact semantics, don't you think a program that generates
> a constant stream of notices is a bit strange? That sounds like something > everyone would naturally want to avoid. You don't drive your car with the > check engine light permanently on and say "this is fine", right?
Except you can purposely turn off this 'check engine' light, never to see it again if you choose to. And that it's really not at all similar to 'check engine', but a lot closer to 'check cleaning fluid', or even 'clean windshield' (if cars had a dashboard light for that). Even that is not a good analogy - as folks often actually purposely write code that generates notices (which would be purposely hidden, either by error_reporting setting or using @) that is 100% bug-free and working as intended. So no, there's nothing strange about it if you buy into that approach. If you don't (and I know you don't) - that's absolutely fine - it's up to you. Zeev
  106800
August 29, 2019 15:50 chasepeeler@gmail.com (Chase Peeler)
On Thu, Aug 29, 2019 at 10:22 AM Zeev Suraski <zeev@php.net> wrote:

> On Thu, Aug 29, 2019 at 4:02 PM Aegir Leet via internals < > internals@lists.php.net> wrote: > > > I know what the manual says about notices. But I don't agree with > > interpreting "could happen in the normal course of running a script" as > > "it's perfectly fine if this part of your code triggers a notice > > consistently and every time it goes down this particular code path". > > Rather, I've always interpreted this as "under certain, rare, unforeseen > > circumstances, your code could generate a notice here, probably because > of > > something that is outside of your control". > > > > That's how I've always treated them at least. > > > > And that's entirely within your right to do so - but what the manual says > is accurate. Calling me delusional in my interpretation of it is somewhat > awkward (to put it mildly), I have a pretty good idea of why we added the > different error levels - I wrote much of it myself. > > The whole point of having notices as something that's separate from > warnings is that they have different semantics, and that semantics is > captured very accurately in the manual. They are used to mark issues which > may be problems, but may also be perfectly fine (unlike warnings, which > generally speaking mean that something bad happened, but not bad enough to > halt execution). Notices were meant to help you implement a more strict > style of coding, and they may help you catch certain types of bugs, but you > can have perfectly working, bug-free code that generates notices. > > Regardless of the exact semantics, don't you think a program that generates > > a constant stream of notices is a bit strange? That sounds like something > > everyone would naturally want to avoid. You don't drive your car with the > > check engine light permanently on and say "this is fine", right? > > > Except you can purposely turn off this 'check engine' light, never to see > it again if you choose to. And that it's really not at all similar to > 'check engine', but a lot closer to 'check cleaning fluid', or even 'clean > windshield' (if cars had a dashboard light for that). Even that is not a > good analogy - as folks often actually purposely write code that generates > notices (which would be purposely hidden, either by error_reporting setting > or using @) that is 100% bug-free and working as intended. So no, there's > nothing strange about it if you buy into that approach. If you don't (and > I know you don't) - that's absolutely fine - it's up to you. > > Zeev > I just wanted to bring up a few other points. First, as I think Stanislav
has done a good job of pointing out, the flexibility of PHP is one of its greatest features. The nice thing about a flexible and forgiving language is that you can always put additional things in place on top of it to make it more strict and rigid if you want. Once you force a language to be strict and rigid, however, it's much harder, if not impossible, to add back in flexibility. A lot of my emails on this thread have been focused on the burden to developers caused by the BC break. While I still think that is an important consideration, it distracted me from my initial view which was we shouldn't do this because it's just a bad idea. I understand all of the arguments for enforcing variable initialization. I agree with most of them as well. However, I think there are a myriad of ways that individuals and teams can do that enforcement without forcing it on every single developer whether they want it or not. A lot of comparisons have been made to other languages. I do a lot of work with javascript and I have a good amount of experience with c# as well. I've used many other languages at times (c, c++, java, perl, ruby, etc.) as well. In c#, you don't have to initialize your variables - you have to declare them. Some types, like ints, are automatically initialized to 0 unless explicitly initialized to something else. PHP doesn't require you to declare variables. So, while c# might require "int i; i++;" you can achieve the same thing in PHP with "$i++;" - neither one requires an explicit initialization. A few people have referred to the fact that I have instances of undeclared variables as technical debt. As I said earlier, I've engaged in these discussions because I don't think just calling something technical debt should be justification for a change. The fact that a large number of developers might have technical debt in a certain area should be considered when weighing the pros and cons of a breaking change. That being said, I do NOT consider such code to be technical debt or bad code that needs to be fixed. The only way it becomes either of those if with the implementation of this RFC. It's a bit disingenuous to tell developers they have to make large changes, and when they push back, tell them it's their fault for accruing so much technical debt - when it's the RFC itself that actually causes the technical debt to begin with! *I will no longer engage in conversations on this topic that relate to how you think my company should conduct business or prioritize development. * Finally, since people seem hell bent on turning PHP into a language that operates like all the others, instead of letting it keep its unique qualities that make it great and different, I asked a c# developer I know about how Microsoft deals with breaking changes. Here was his response: "I’ve never heard of a breaking change when new versions of C# are released. There are occasionally breaking changes when upgrading to a new version of .NET, but they always (as far as I’m aware) have a way to prevent the change from breaking anything by adding a parameter the app’s configuration." -- Chase Peeler chasepeeler@gmail.com
  106801
August 29, 2019 16:13 matthewmatthew@gmail.com (Matthew Brown)
I don’t think it’s helpful to compare C#’s BC policies to PHP’s. C# is used today mostly as its architect intended at its founding. PHP, having transitioned from a templating system to a fully-fledged language, is used quite differently.

> On Aug 29, 2019, at 11:50 AM, Chase Peeler <chasepeeler@gmail.com> wrote: > >> On Thu, Aug 29, 2019 at 10:22 AM Zeev Suraski <zeev@php.net> wrote: >> >> On Thu, Aug 29, 2019 at 4:02 PM Aegir Leet via internals < >> internals@lists.php.net> wrote: >> >>> I know what the manual says about notices. But I don't agree with >>> interpreting "could happen in the normal course of running a script" as >>> "it's perfectly fine if this part of your code triggers a notice >>> consistently and every time it goes down this particular code path". >>> Rather, I've always interpreted this as "under certain, rare, unforeseen >>> circumstances, your code could generate a notice here, probably because >> of >>> something that is outside of your control". >>> >>> That's how I've always treated them at least. >>> >> >> And that's entirely within your right to do so - but what the manual says >> is accurate. Calling me delusional in my interpretation of it is somewhat >> awkward (to put it mildly), I have a pretty good idea of why we added the >> different error levels - I wrote much of it myself. >> >> The whole point of having notices as something that's separate from >> warnings is that they have different semantics, and that semantics is >> captured very accurately in the manual. They are used to mark issues which >> may be problems, but may also be perfectly fine (unlike warnings, which >> generally speaking mean that something bad happened, but not bad enough to >> halt execution). Notices were meant to help you implement a more strict >> style of coding, and they may help you catch certain types of bugs, but you >> can have perfectly working, bug-free code that generates notices. >> >> Regardless of the exact semantics, don't you think a program that generates >>> a constant stream of notices is a bit strange? That sounds like something >>> everyone would naturally want to avoid. You don't drive your car with the >>> check engine light permanently on and say "this is fine", right? >> >> >> Except you can purposely turn off this 'check engine' light, never to see >> it again if you choose to. And that it's really not at all similar to >> 'check engine', but a lot closer to 'check cleaning fluid', or even 'clean >> windshield' (if cars had a dashboard light for that). Even that is not a >> good analogy - as folks often actually purposely write code that generates >> notices (which would be purposely hidden, either by error_reporting setting >> or using @) that is 100% bug-free and working as intended. So no, there's >> nothing strange about it if you buy into that approach. If you don't (and >> I know you don't) - that's absolutely fine - it's up to you. >> >> Zeev >> > I just wanted to bring up a few other points. First, as I think Stanislav > has done a good job of pointing out, the flexibility of PHP is one of its > greatest features. The nice thing about a flexible and forgiving language > is that you can always put additional things in place on top of it to make > it more strict and rigid if you want. Once you force a language to be > strict and rigid, however, it's much harder, if not impossible, to add back > in flexibility. > > A lot of my emails on this thread have been focused on the burden to > developers caused by the BC break. While I still think that is an important > consideration, it distracted me from my initial view which was we shouldn't > do this because it's just a bad idea. I understand all of the arguments for > enforcing variable initialization. I agree with most of them as well. > However, I think there are a myriad of ways that individuals and teams can > do that enforcement without forcing it on every single developer whether > they want it or not. > > A lot of comparisons have been made to other languages. I do a lot of work > with javascript and I have a good amount of experience with c# as well. > I've used many other languages at times (c, c++, java, perl, ruby, etc.) as > well. In c#, you don't have to initialize your variables - you have to > declare them. Some types, like ints, are automatically initialized to 0 > unless explicitly initialized to something else. PHP doesn't require you to > declare variables. So, while c# might require "int i; i++;" you can achieve > the same thing in PHP with "$i++;" - neither one requires an explicit > initialization. > > A few people have referred to the fact that I have instances of undeclared > variables as technical debt. As I said earlier, I've engaged in these > discussions because I don't think just calling something technical debt > should be justification for a change. The fact that a large number of > developers might have technical debt in a certain area should be considered > when weighing the pros and cons of a breaking change. That being said, I do > NOT consider such code to be technical debt or bad code that needs to be > fixed. The only way it becomes either of those if with the implementation > of this RFC. It's a bit disingenuous to tell developers they have to make > large changes, and when they push back, tell them it's their fault for > accruing so much technical debt - when it's the RFC itself that actually > causes the technical debt to begin with! *I will no longer engage in > conversations on this topic that relate to how you think my company should > conduct business or prioritize development. * > > Finally, since people seem hell bent on turning PHP into a language that > operates like all the others, instead of letting it keep its unique > qualities that make it great and different, I asked a c# developer I know > about how Microsoft deals with breaking changes. Here was his response: > "I’ve never heard of a breaking change when new versions of C# are > released. There are occasionally breaking changes when upgrading to a new > version of .NET, but they always (as far as I’m aware) have a way to > prevent the change from breaking anything by adding a parameter the app’s > configuration." > > -- > Chase Peeler > chasepeeler@gmail.com
  106804
August 29, 2019 17:11 claude.pache@gmail.com (Claude Pache)
> Le 29 août 2019 à 18:13, Matthew Brown <matthewmatthew@gmail.com> a écrit : > > I don’t think it’s helpful to compare C#’s BC policies to PHP’s. C# is used today mostly as its architect intended at its founding. PHP, having transitioned from a templating system to a fully-fledged language, is used quite differently.
Today, PHP is a fully-fledged language *and* a templating system. —Claude
  106802
August 29, 2019 16:25 aegir@aegir.sexy (Aegir Leet)
Before reading the responses to this thread, I had honestly never
encountered a PHP developer who thought using uninitialized variables
was fine. I knew it worked, but I always considered this to basically be
the PHP equivalent of undefined behavior in C. And I don't think anyone
would get mad if a new GCC version broke the way they were abusing UB.

To me and to every developer I've ever known, the only difference
between a notice and a warning is the severity of the error. But they're
both considered errors - mistakes you made in your code that you need to
fix. I'm fairly certain this is how most developers treat them in the
real world.

Either way, if you want a less strict language, that language already
exists: It's the current version of PHP and you and everyone else who
likes the way it works can keep using it.
Meanwhile, I think most people currently doing serious PHP work would
*love* some more strictness and I don't think keeping your old code
running on a brand new version of the language is a good enough reason
to keep this feature out of 8.0. What's the point of even having major
releases if every potential BC break gets shot down by the same 3 people
on this mailing list?

As for the check engine light analogy, I guess instead of saying "this
is fine", you just smash your entire dashboard with a hammer to make the
problem go away. Because that's what using @ or error_reporting does.

I hope this RFC passes, but I don't see any point in discussing it
further here, so I'll go back to lurking now.

On 29.08.2019 16:22, Zeev Suraski wrote:
> > > On Thu, Aug 29, 2019 at 4:02 PM Aegir Leet via internals > <internals@lists.php.net <mailto:internals@lists.php.net>> wrote: > > I know what the manual says about notices. But I don't agree with > interpreting "could happen in the normal course of running a > script" as "it's perfectly fine if this part of your code triggers > a notice consistently and every time it goes down this particular > code path". Rather, I've always interpreted this as "under > certain, rare, unforeseen circumstances, your code could generate > a notice here, probably because of something that is outside of > your control". > > That's how I've always treated them at least. > > > And that's entirely within your right to do so - but what the manual > says is accurate.  Calling me delusional in my interpretation of it is > somewhat awkward (to put it mildly), I have a pretty good idea of why > we added the different error levels - I wrote much of it myself. > > The whole point of having notices as something that's separate from > warnings is that they have different semantics, and that semantics is > captured very accurately in the manual.  They are used to mark issues > which may be problems, but may also be perfectly fine (unlike > warnings, which generally speaking mean that something bad happened, > but not bad enough to halt execution).  Notices were meant to help you > implement a more strict style of coding, and they may help you catch > certain types of bugs, but you can have perfectly working, bug-free > code that generates notices. > > Regardless of the exact semantics, don't you think a program that > generates a constant stream of notices is a bit strange? That > sounds like something everyone would naturally want to avoid. You > don't drive your car with the check engine light permanently on > and say "this is fine", right? > > > Except you can purposely turn off this 'check engine' light, never to > see it again if you choose to.  And that it's really not at all > similar to 'check engine', but a lot closer to 'check cleaning fluid', > or even 'clean windshield' (if cars had a dashboard light for that).  > Even that is not a good analogy - as folks often actually purposely > write code that generates notices (which would be purposely hidden, > either by error_reporting setting or using @) that is 100% bug-free > and working as intended.  So no, there's nothing strange about it if > you buy into that approach.  If you don't (and I know you don't) - > that's absolutely fine - it's up to you. > > Zeev >
  106803
August 29, 2019 16:41 truth@proposaltech.com (Todd Ruth)
> From: Aegir Leet <aegir@aegir.sexy> > Either way, if you want a less strict language, that language already > exists: It's the current version of PHP and you and everyone else who > likes the way it works can keep using it.
For approximately 3 years. Please remember "end of life". We'd still be using php5 today if it weren't for "end of life". I interpret the above paragraph as a request to split between p++ and php classic. I'd be fine with that and use php classic, but I believe the idea of splitting failed by a very wide margin. - Todd
  106805
August 29, 2019 17:15 claude.pache@gmail.com (Claude Pache)
> Le 29 août 2019 à 18:25, Aegir Leet <aegir@aegir.sexy> a écrit : > > Either way, if you want a less strict language, that language already > exists: It's the current version of PHP and you and everyone else who > likes the way it works can keep using it. > Meanwhile, I think most people currently doing serious PHP work would > *love* some more strictness and I don't think keeping your old code > running on a brand new version of the language is a good enough reason > to keep this feature out of 8.0.
Strictness is undoubtedly a good thing — as a tool, not as a dogma. But BC break is not necessary for more strictness. As of today, you can write a custom error-handler that converts all non-handled warnings into program crashes (after having sent a fiery bug report to the developer). —Claude
  106806
August 29, 2019 17:24 cschneid@cschneid.com (Christian Schneider)
Am 29.08.2019 um 18:25 schrieb Aegir Leet <aegir@aegir.sexy>:
> Before reading the responses to this thread, I had honestly never > encountered a PHP developer who thought using uninitialized variables > was fine.
Now you have. Nice to meet you.
> I knew it worked, but I always considered this to basically be > the PHP equivalent of undefined behavior in C. And I don't think anyone > would get mad if a new GCC version broke the way they were abusing UB.
That's where you are mixing things up: It is well-defined behaviour, even if you personally don't like it. A better analogy is static variables in C. It is common (and not considered bad) practice to not explicitly set a variable to 0 as that is the default value. Example: https://github.com/git/git/blob/6d5b26420848ec3bc7eae46a7ffa54f20276249d/delta-islands.c#L26 - Chris
  106807
August 29, 2019 19:29 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

>> encountered a PHP developer who thought using uninitialized variables >> was fine. > > Now you have. Nice to meet you.
And there are more of us. You learn something new every day!
>> I knew it worked, but I always considered this to basically be >> the PHP equivalent of undefined behavior in C. And I don't think anyone
It's not. It's very well defined behavior, that is not going to break - unless it is broken intentionally in a zeal for adding more strictness for the sake of strictness. So, another thing to learn. I love learning new things, and love helping others do so! -- Stas Malyshev smalyshev@gmail.com
  106833
September 2, 2019 17:01 pollita@php.net (Sara Golemon)
On Thu, Aug 29, 2019 at 2:29 PM Stanislav Malyshev <smalyshev@gmail.com>
wrote:

> >> I knew it worked, but I always considered this to basically be > >> the PHP equivalent of undefined behavior in C. And I don't think anyone > > It's not. It's very well defined behavior, that is not going to break - > unless it is broken intentionally in a zeal for adding more strictness > for the sake of strictness. So, another thing to learn. I love learning > new things, and love helping others do so! > > It is well defined. It's also, in my PERSONAL opinion, gross AF. That doesn't make me right or better or anything other than opinionated.
Other opinions: * I'd quite like PHP to be a little less gross in places like this. * I think Nikita's hitlist here is a step in the right direction, however... * I DON'T think the cost to BC is justified in all cases. For example, an exception for read of undefined vars is traumatic BC. * I think declare(strict_types=1); already solved a very similar problem and could easily be applied to future issue like this. So how about we suck it up, put on our big girl panties, and just embrace declares (including namespace scoped declares and/or a modern version of ..htaccess) -Sara
  106834
September 2, 2019 18:02 arvids.godjuks@gmail.com (Arvids Godjuks)
On Mon, Sep 2, 2019, 19:02 Sara Golemon <pollita@php.net> wrote:

> On Thu, Aug 29, 2019 at 2:29 PM Stanislav Malyshev <smalyshev@gmail.com> > wrote: > > > >> I knew it worked, but I always considered this to basically be > > >> the PHP equivalent of undefined behavior in C. And I don't think > anyone > > > > It's not. It's very well defined behavior, that is not going to break - > > unless it is broken intentionally in a zeal for adding more strictness > > for the sake of strictness. So, another thing to learn. I love learning > > new things, and love helping others do so! > > > > It is well defined. It's also, in my PERSONAL opinion, gross AF. That > doesn't make me right or better or anything other than opinionated. > > Other opinions: > * I'd quite like PHP to be a little less gross in places like this. > * I think Nikita's hitlist here is a step in the right direction, > however... > * I DON'T think the cost to BC is justified in all cases. For example, an > exception for read of undefined vars is traumatic BC. > * I think declare(strict_types=1); already solved a very similar problem > and could easily be applied to future issue like this. > > So how about we suck it up, put on our big girl panties, and just embrace > declares (including namespace scoped declares and/or a modern version of > .htaccess) > > -Sara >
Hi Sara, I do agree with most of it, especially about the big girl panties part, but I do disagree with the declares part. There should be one general use declare I think - declare(strict=1) - and it should be the mode where PHP is going as a language into the future and contain the strict types, stricter operators, the full suite of error level rework (include everything Nikita has added in this RFC and probably work on next iteration later), have other stuff cleaned up too? Here's the rationale: Projects these days tend to be sizeable and growing all the time - they require strictness to be maintainable by multiple people. We have seen a rise of more strict and less feature-rich languages that are becoming a day to day instruments for many things (Go anyone?) and the average skill of the workforce has gone down somewhat a lot these past 10-15 years. So tightening the screws is somewhat a necessity these days and leaving PHP with its idiosyncrasies as it is right now in the weak mode is not a good idea for the future. People have changed, development has changed, tools have changed, how we write PHP code has changed DRAMATICALLY and PHP community has been keeping up with past 5 years of PHP development faster than PHP is evolving itself. I mean take NodeJS and JavaScript - their dev cycles are running at breakneck speeds and you basically have to re-learn things on a yearly basis to stay up to date. But it is a mess because the ecosystem is young. In PHP our ecosystem is mature, we have very good libraries and frameworks that have clear release cycles and have reasonable upgrade paths and do keep up with PHP itself - the adoption rates are probably at their highest right now. I say it's time to capitalize on this momentum and settle into a rhythm of improving the language and its ecosystem by streamlining and building for the next 20 years of it's lifecycle. With JIT coming up, a lot of things will start to become possible and there are going to be a lot of things that you want to make more explicit in the code to make sure JIT can take advantage of and optimise. So, back to the strict mode idea: why not introduce that mode in PHP 8 (fold strict_types into it and have a depreciation notice for strict_types so people switch to declare(strict_mode=1) ), continue developing stuff for that strict mode during the life of 8 versions and state everywhere that this is preferred and future proof mode, in PHP 9 starts deprecating things in non-strict mode pushing people to fix things like undefined variables, index access notices, have more strict operators. An in PHP 10 basically sunset the bad parts of the non-strict mode getting it closer up to the stricter version in terms of the WTF parts of the language, but still leave the fully dynamic and strict modes. Provided, ofc, that it is feasible, though I would completely sunset non-strict mode at that point and leave only one mode. This essentially gives about a 10-year timeline of messaging, depreciation and warnings to everyone. And at that point, if someone still did not do anything to fix up things - well, I'm sorry, but it's your problem then to figure out. I have done a few major 5 to 7 upgrades, one of them was an especially bad case of PHP 5.1 to 7.1 cause it relied on PHP 4 behaviours that were deprecated with PHP 5.0 and 5.1 and fatal error in 7 - it is not as bad as many people think.
>
  106767
August 28, 2019 19:30 phofstetter@sensational.ch (Philip Hofstetter)
Hi,

On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> wrote:

> > I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. >
As a user dealing with a big legacy code-base that's still being in heavy use and active development, while I appreciate this RFC in general, let me please voice my concerns about promoting "Undefined index: %s" from E_NOTICE to E_WARNING without also doing other changes. The point is that in many cases, PHP still tends to just emit an E_WARNING for otherwise pretty exceptional cases, like being unable to open a file, or failing network operations. Now normally, you will of course check return values, but if you mess it up, the risk of bad things happening is too big, so right now, it's sensible to treat E_WARNING as fatal in production. E_NOTICEs on the other hand are extremely uncritical (minus the undefined variable case you've highlighted), so it's sensible to ignore those in production and it's tempting to do so even in development and, I freely admit, that's totally the case in the code-base I'm dealing with and I would assume others would also have it configured that way. Code designed to avoid "Undefined index: %s" is very boilerplaty to write and in various code-bases (including ours), accessing undefined indexes in arrays is mostly inconsequential. So this leaves me (and I assume others) in kind of a pickle, because it feels that right now it's still too risky to not treat E_WARNING as fatal in production and on the other hand, this RFC is going to turn completely harmless undefined index access into an E_WARNING. Even if you don't care about my particular code-base (which I would totally understand), please consider that this is quite the BC breakage in general and in our case, it will probably force us to run with a patched PHP engine as we are unable to clean the code up in any kind of reasonable time frame. Again - that's my problem. I know. But I still would like to voice this concern. Of course, even when passing this RFC in full, there are options you could provide for people in our kind of situation: * If all functions that currently emit an E_WARNING in cases where they should actually throw could be made to throw, then it would be safe to run production without treating E_WARNING as fatal. I'm afraid that too is a big BC break, but at least it's breaking code running into otherwise serious issues rather than code doing something mostly benign. * If this can't be done, which I totally understand, then please consider a way for a error handler to distinguish between various errors, notices and warnings without having to string match on error messages. That feels incredibly brittle and also ties the PHP language into ossified error messages that can never be changed without also causing potential BC issues. Still. I wholeheartedly thank you all for your recent efforts to clean up the language and bring it forward to the current state of things. But please consider the huge swaths of existing code which sometimes cannot be practically changed. I do not have any kind of voting rights, so in the end my opinion doesn't matter, but if I had the ability to vote, I would have to vote "no" over this unless some kind of escape hatch is provided. Thank you Philip
  106809
August 30, 2019 04:24 theodorejb@outlook.com (Theodore Brown)
On Wed, Aug 28, 2019 at 4:33 AM Nikita Popov ppv@gmail.com> wrote:

> I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. > > I've prepared an RFC with some suggested classifications, though there's > room for bikeshedding here... > > https://wiki.php.net/rfc/engine_warnings
Nikita, Thank you for your effort in putting together this RFC and explaining the rationale for each change. From my perspective, converting more error conditions from a notice/warning to an exception as proposed will be a welcome step forward for the language. I've frequently used PHP to write one-time scripts for migrating data between services, or scripting changes to thousands of items via an API. The lack of exceptions for things like undefined variables and using a scalar value as an array has bitten me on multiple occasions. There have even been times when simple mistakes like a typo in a variable name have led to data loss, since instead of causing the script to halt it just output a notice and continued running with bad data. In my experience, PHP's historical lax treatment of errors, far from making it faster and easier to write scripts, *actually makes it take longer* since I have to add extra assertions and boilerplate custom error handling code in order to ensure that scripts don't keep running in a broken state when one of these errors occurs. So in summary, I think the proposed RFC is a solid step forward which will help prevent expensive mistakes and make it simpler to write robust code. With appreciation, Theodore
  106928
September 10, 2019 13:31 nikita.ppv@gmail.com (Nikita Popov)
On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. > > I've prepared an RFC with some suggested classifications, though there's > room for bikeshedding here... > > https://wiki.php.net/rfc/engine_warnings > > Regards, > Nikita >
Heads up: This RFC may go to vote tomorrow. Nikita
  106929
September 10, 2019 22:04 bjorn.x.larsson@telia.com (=?UTF-8?Q?Bj=c3=b6rn_Larsson?=)
Den 2019-09-10 kl. 15:31, skrev Nikita Popov:

> On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> wrote: > >> Hi internals, >> >> I think it's time to take a look at our existing warnings & notices in the >> engine, and think about whether their current classification is still >> appropriate. Error conditions like "undefined variable" only generating a >> notice is really quite mind-boggling. >> >> I've prepared an RFC with some suggested classifications, though there's >> room for bikeshedding here... >> >> https://wiki.php.net/rfc/engine_warnings >> >> Regards, >> Nikita >> > Heads up: This RFC may go to vote tomorrow. > > Nikita
Hi, I recall an issue brought up about treatment of logfiles in production environment where PHP warning messages show up. Now, this RFC reclassifies some notices to warnings and some warnings to errors. Now suppose one have as a strategy to correct warnings & errors in logfiles, given that this RFC will lead to new items showing up in logfiles. Is it then worth mentioning in the RFC how this will affect handling to correct warnings & errors in logfiles? E.g. face the changes and fix  it or write some clever error handler to manage it or just try to suppress the new items. Anyway, I'm in favour of this RFC since it gives a more consistent classification of notices, warnings & errors. r//Björn L
  106931
September 12, 2019 07:40 claude.pache@gmail.com (Claude Pache)
> Le 10 sept. 2019 à 15:31, Nikita Popov ppv@gmail.com> a écrit : > > On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> wrote: > >> Hi internals, >> >> I think it's time to take a look at our existing warnings & notices in the >> engine, and think about whether their current classification is still >> appropriate. Error conditions like "undefined variable" only generating a >> notice is really quite mind-boggling. >> >> I've prepared an RFC with some suggested classifications, though there's >> room for bikeshedding here... >> >> https://wiki.php.net/rfc/engine_warnings >> >> Regards, >> Nikita >> > > Heads up: This RFC may go to vote tomorrow. > > Nikita
I have objections to those two reclassifications: * Undefined offset: %d — Notice → Warning * Undefined index: %d — Notice → Warning From experience, having to dutifully initialise each and every key in an array is burdensome. I understand the rationale of enforcing that in some coding standard; but whether those particular missing index should be considered as unexpected (therefore deserving a Warning) is mostly a question of coding style. This is in principle a similar issue as using uninitialised variables, which, as noted in this thread, is a perfectly accepted coding pattern in some languages (the issue being distinct from *undeclared* variables). I say “in principle”, because a perfectly reasonable coding style may choose to enforce initialisation of variables, but not of array keys. PHP has the advantage of supporting various coding styles. We should give the opportunity to the users to say declaratively (and precisely) what, in their coding style, is considered as acceptable, e.g. declare( uninitialized_variables: error uninitilalized_index: none ); of course, possibly at a package-level declare. That would, for example, enable people to place legacy code in lax mode and chose a stricter mode for new code, even letting the precise notion of strictness vary with fashion without having to review working code written two years ago. That said, as long as those issues are handled as errors (as in: set_error_handler()) rather than exceptions, one may write a proper error handler that does the distinction (I do that). However, an error handler has the disadvantage of being global, making difficult the integration of code written with differing coding standards. —Claude
  106932
September 12, 2019 08:17 php-lists@koalephant.com (Stephen Reay)
> On 12 Sep 2019, at 14:40, Claude Pache pache@gmail.com> wrote: > >> Le 10 sept. 2019 à 15:31, Nikita Popov ppv@gmail.com> a écrit : >> >> On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> wrote: >> >>> Hi internals, >>> >>> I think it's time to take a look at our existing warnings & notices in the >>> engine, and think about whether their current classification is still >>> appropriate. Error conditions like "undefined variable" only generating a >>> notice is really quite mind-boggling. >>> >>> I've prepared an RFC with some suggested classifications, though there's >>> room for bikeshedding here... >>> >>> https://wiki.php.net/rfc/engine_warnings >>> >>> Regards, >>> Nikita >>> >> >> Heads up: This RFC may go to vote tomorrow. >> >> Nikita > > > I have objections to those two reclassifications: > > * Undefined offset: %d — Notice → Warning > * Undefined index: %d — Notice → Warning > > > From experience, having to dutifully initialise each and every key in an array is burdensome. I understand the rationale of enforcing that in some coding standard; but whether those particular missing index should be considered as unexpected (therefore deserving a Warning) is mostly a question of coding style. > > This is in principle a similar issue as using uninitialised variables, which, as noted in this thread, is a perfectly accepted coding pattern in some languages (the issue being distinct from *undeclared* variables). I say “in principle”, because a perfectly reasonable coding style may choose to enforce initialisation of variables, but not of array keys. > > PHP has the advantage of supporting various coding styles. We should give the opportunity to the users to say declaratively (and precisely) what, in their coding style, is considered as acceptable, e.g. > > declare( > uninitialized_variables: error > uninitilalized_index: none > ); > > of course, possibly at a package-level declare. That would, for example, enable people to place legacy code in lax mode and chose a stricter mode for new code, even letting the precise notion of strictness vary with fashion without having to review working code written two years ago. > > That said, as long as those issues are handled as errors (as in: set_error_handler()) rather than exceptions, one may write a proper error handler that does the distinction (I do that). However, an error handler has the disadvantage of being global, making difficult the integration of code written with differing coding standards. > > —Claude > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
I’ve seen a number of people that have concerns about PHP throwing actual errors (as opposed to notices) because they try to use a variable/offset that doesn’t exist, and of course there is often a proposal to have a declare statement or something similar, to allow their “code style” to run without errors. So, my proposal to the situation is to introduce a single declare that solves that problem, once and for all. declare(sloppy=1); This would suppress any errors about undefined variables, array offsets, would reverse the “bare words" change when encountering an undefined constant, etc. Heck, for good measure this mode could even re-implement register_globals and magic_quotes, because why not? If you want to write sloppy code, that is entirely your prerogative, but please just own it for what it is, and stop pretending that it’s some herculean task to either define variables/offsets first; or check if they’re defined; or use an appropriate method to access them that specifically allows for undefined variables/offsets (i.e. the ?? and ??= operators)
  106933
September 12, 2019 08:21 benjamin.morel@gmail.com (Benjamin Morel)
> > declare(sloppy=1);
I like this idea. Strict by default, sloppy by (code-level) config.
  106935
September 12, 2019 09:41 claude.pache@gmail.com (Claude Pache)
> Le 12 sept. 2019 à 10:17, Stephen Reay <php-lists@koalephant.com> a écrit : > > > > I’ve seen a number of people that have concerns about PHP throwing actual errors (as opposed to notices) because they try to use a variable/offset that doesn’t exist, and of course there is often a proposal to have a declare statement or something similar, to allow their “code style” to run without errors. > > > So, my proposal to the situation is to introduce a single declare that solves that problem, once and for all. > > > declare(sloppy=1); > > > This would suppress any errors about undefined variables, array offsets, would reverse the “bare words" change when encountering an undefined constant, etc. Heck, for good measure this mode could even re-implement register_globals and magic_quotes, because why not? > > > > If you want to write sloppy code, that is entirely your prerogative, but please just own it for what it is, and stop pretending that it’s some herculean task to either define variables/offsets first; or check if they’re defined; or use an appropriate method to access them that specifically allows for undefined variables/offsets (i.e. the ?? and ??= operators) > >
Declare(sloppy=yeah) is not granular enough. To all: please, do understand that everything is not black or white; this remark is not directed specifically to that particular issue, this is an attitude I see regularly on that mailing list. There is no such thing as “one true strict coding standard” and “one legacy lax coding standard”. For instance: * As time passes, we learn by experience what features were plain blunders (magic_quotes?), what features should have been more strict for the sake of catching bugs without imposing too much burden on users, what features could have been more strict, although that would impose to write lot of boiler code, etc. This process does not belong exclusively to some past dark age of sloppy and unsecure coding practices. * The degree of wanted strictness vary depending on occasions. For example when I’m writing a throw-away script, some notices are okay to indicate possible problems, but I’m not going to write boilerplate code (or, worse, put a @ in front of everything) just for the sake of silencing them. (But I *certainly* do not want stupid things like mistyped constants converted to string literals.) On the other hand, when I’m writing a critical part of an application, I am careful to write down everything precisely, and having to write explicitly and once for all that, yes, this precise variable must have that default value, is a minimal part of the time passed to write, re-read and review the code. —Claude
  106936
September 12, 2019 10:32 benjamin.morel@gmail.com (Benjamin Morel)
> > For example when I’m writing a throw-away script, some notices are okay to > indicate possible problems
Maybe it's just me, but even in throw-away scripts, *I've lost much more time because of warnings/notices going unnoticed, than I've saved thanks to PHP's forgiving nature*. Hence even in the shittiest of my scripts, I usually end up registering an error handler to throw an exception even for the smallest notice. At least, I always get an exception right in my face when something's unexpected, so I can fix it and move on, and avoid surprises later on. Sure, in a quick script, I do see some value in being able to write stuff like: @ $array['non_existing_key']++; It's still sloppy though: what you're really doing is muting a notice and incrementing null. Instead, I feel like there should be a stronger support from the language to specifically handle this kind of use cases, rather than using them as a justification for not *severely *hardening error reporting. I don't think there are that many such *potentially *legitimate use cases, so maybe we could just list the use cases and think about a more elegant solution to solve them? In other words, if that was only me, the whole notice/warning stuff would go, and PHP would only have exceptions. Undefined variables would throw, undefined array keys would throw, and use cases like the above would have stronger language support to avoid boilerplate code full of if(isset()). — Benjamin On Thu, 12 Sep 2019 at 11:42, Claude Pache pache@gmail.com> wrote:
> > > > Le 12 sept. 2019 à 10:17, Stephen Reay <php-lists@koalephant.com> a > écrit : > > > > > > > > I’ve seen a number of people that have concerns about PHP throwing > actual errors (as opposed to notices) because they try to use a > variable/offset that doesn’t exist, and of course there is often a proposal > to have a declare statement or something similar, to allow their “code > style” to run without errors. > > > > > > So, my proposal to the situation is to introduce a single declare that > solves that problem, once and for all. > > > > > > declare(sloppy=1); > > > > > > This would suppress any errors about undefined variables, array offsets, > would reverse the “bare words" change when encountering an undefined > constant, etc. Heck, for good measure this mode could even re-implement > register_globals and magic_quotes, because why not? > > > > > > > > If you want to write sloppy code, that is entirely your prerogative, but > please just own it for what it is, and stop pretending that it’s some > herculean task to either define variables/offsets first; or check if > they’re defined; or use an appropriate method to access them that > specifically allows for undefined variables/offsets (i.e. the ?? and ??= > operators) > > > > > > Declare(sloppy=yeah) is not granular enough. To all: please, do understand > that everything is not black or white; this remark is not directed > specifically to that particular issue, this is an attitude I see regularly > on that mailing list. > > There is no such thing as “one true strict coding standard” and “one > legacy lax coding standard”. For instance: > > * As time passes, we learn by experience what features were plain blunders > (magic_quotes?), what features should have been more strict for the sake of > catching bugs without imposing too much burden on users, what features > could have been more strict, although that would impose to write lot of > boiler code, etc. This process does not belong exclusively to some past > dark age of sloppy and unsecure coding practices. > > * The degree of wanted strictness vary depending on occasions. For example > when I’m writing a throw-away script, some notices are okay to indicate > possible problems, but I’m not going to write boilerplate code (or, worse, > put a @ in front of everything) just for the sake of silencing them. (But I > *certainly* do not want stupid things like mistyped constants converted to > string literals.) On the other hand, when I’m writing a critical part of an > application, I am careful to write down everything precisely, and having to > write explicitly and once for all that, yes, this precise variable must > have that default value, is a minimal part of the time passed to write, > re-read and review the code. > > —Claude > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
  106938
September 12, 2019 11:32 arvids.godjuks@gmail.com (Arvids Godjuks)
чт, 12 сент. 2019 г. в 12:32, Benjamin Morel morel@gmail.com>:

> > > > For example when I’m writing a throw-away script, some notices are okay > to > > indicate possible problems > > > Maybe it's just me, but even in throw-away scripts, *I've lost much more > time because of warnings/notices going unnoticed, than I've saved thanks to > PHP's forgiving nature*. > Hence even in the shittiest of my scripts, I usually end up registering an > error handler to throw an exception even for the smallest notice. At least, > I always get an exception right in my face when something's unexpected, so > I can fix it and move on, and avoid surprises later on. > > Sure, in a quick script, I do see some value in being able to write stuff > like: > > @ $array['non_existing_key']++; > > It's still sloppy though: what you're really doing is muting a notice and > incrementing null. > Instead, I feel like there should be a stronger support from the language > to specifically handle this kind of use cases, rather than using them as a > justification for not *severely *hardening error reporting. > I don't think there are that many such *potentially *legitimate use cases, > so maybe we could just list the use cases and think about a more elegant > solution to solve them? > > In other words, if that was only me, the whole notice/warning stuff would > go, and PHP would only have exceptions. > Undefined variables would throw, undefined array keys would throw, and use > cases like the above would have stronger language support to avoid > boilerplate code full of if(isset()). > > — Benjamin >
Every single workplace I worked in past 5 years always had 0 tolerance policy for all notices, warnings and E_STRICT. Since I started PHP in 2005, I have always worked with a 0 warning/notice/strict tolerance policy, in every workplace I have ever worked. All those were fixed as bugs, heck even management pointed out those from logging aggregation and made bugs to be fixed. At this point, if I see that the company does not do this, I skip it. Usually, it is a sign of way more stuff being wrong, but this alone is already enough to have reservations about the advertised position. The world has moved on how software is developed since the early 2000's when this was okay. These days, at least in my dev circle, it is not okay to have notices/warnings in your code.
  106939
September 12, 2019 12:02 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 12 Sep 2019 at 12:32, Arvids Godjuks godjuks@gmail.com>
wrote:

> Every single workplace I worked in past 5 years always had 0 tolerance > policy for all notices, warnings and E_STRICT. >
Well, that's fine then, you don't need this change. It will make zero difference to you whether something is classified as Notice or Warning. Regards, -- Rowan Tommins [IMSoP]
  106942
September 12, 2019 13:29 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 12 Sep 2019 at 11:32, Benjamin Morel morel@gmail.com>
wrote:

> I don't think there are that many such *potentially *legitimate use cases, > so maybe we could just list the use cases and think about a more elegant > solution to solve them? >
Yes, please. If we can focus less on vague anecdotes and opinions *on both sides*, we can look at *making the language more pleasant to use*. For instance, for undefined array keys, what if we had an operator for "initialise and retrieve", such as $foo[? 'bar']. Then we could simplify ugly code like this: if ( ! isset($foo[$key1]) { $foo[$key1] = []; } if ( ! isset($foo[$key1][$key2]) { $foo[$key1][$key2] = 0; } $foo[$key1][$key2]++; With something safe but succinct like this: $foo[? $key1][? $key2]++; Unlike the error suppression @ operator, this is not saying "I know I'm doing something wrong, do it anyway"; it's saying "I want to do this specific thing, I just want to do it in fewer lines of code". The more helpers like this we have, the more I'd be amenable to *eventually* raising things to Error - although I still think that should be done over a longer period of time than a single release cycle. Regards, -- Rowan Tommins [IMSoP]
  106943
September 12, 2019 13:33 ocramius@gmail.com (Marco Pivetta)
Hey Rowan,
<http://ocramius.github.com/>


On Thu, Sep 12, 2019 at 3:30 PM Rowan Tommins collins@gmail.com>
wrote:

> For instance, for undefined array keys, what if we had an operator for > "initialise and retrieve", such as $foo[? 'bar']. Then we could simplify > ugly code like this: > > if ( ! isset($foo[$key1]) { > $foo[$key1] = []; > } > if ( ! isset($foo[$key1][$key2]) { > $foo[$key1][$key2] = 0; > } > $foo[$key1][$key2]++; > > > With something safe but succinct like this: > > $foo[? $key1][? $key2]++; >
$foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/
  106945
September 12, 2019 13:55 claude.pache@gmail.com (Claude Pache)
> Le 12 sept. 2019 à 15:33, Marco Pivetta <ocramius@gmail.com> a écrit : > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > Marco Pivetta
That violates blatantly DRY (twice the exact same lengthy expression `$foo[$key1][$key2]`), so it is not a satisfactory solution. —Claude
  106948
September 12, 2019 14:02 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 12, 2019 at 9:55 AM Claude Pache pache@gmail.com> wrote:

> > > > Le 12 sept. 2019 à 15:33, Marco Pivetta <ocramius@gmail.com> a écrit : > > > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > > > Marco Pivetta > > That violates blatantly DRY (twice the exact same lengthy expression > `$foo[$key1][$key2]`), so it is not a satisfactory solution. > > And that's why PHP is so awesome. You don't have to do all these stupid tricks just to do something simple like increment a counter. But, it looks
like we're going to throw that out of the window because some people think that since they like doing it like the way above, everyone should have to.
> —Claude > >
-- Chase Peeler chasepeeler@gmail.com
  106950
September 12, 2019 14:06 arvids.godjuks@gmail.com (Arvids Godjuks)
чт, 12 сент. 2019 г. в 16:02, Chase Peeler <chasepeeler@gmail.com>:

> On Thu, Sep 12, 2019 at 9:55 AM Claude Pache pache@gmail.com> > wrote: > > > > > > > > Le 12 sept. 2019 à 15:33, Marco Pivetta <ocramius@gmail.com> a écrit : > > > > > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > > > > > Marco Pivetta > > > > That violates blatantly DRY (twice the exact same lengthy expression > > `$foo[$key1][$key2]`), so it is not a satisfactory solution. > > > > And that's why PHP is so awesome. You don't have to do all these stupid > tricks just to do something simple like increment a counter. But, it looks > like we're going to throw that out of the window because some people think > that since they like doing it like the way above, everyone should have to.. > > > —Claude > > > > > > -- > Chase Peeler > chasepeeler@gmail.com >
Easy, because experience shows that leads to bugs and lots of them. Security issues even. If you want to write predictable code - you have to init your variables/arrays. And check for existence/null. If fixed at least a few dozen bugs in my system I took over in the last few months specifically because of undefined variables or indexes. It works for small stuff, but when you have a codebase with 100+k LOC and more, you have to go strict or it starts to cost a lot of money and personnel to keep things running along. -- Arvīds Godjuks +371 26 851 664 arvids.godjuks@gmail.com Skype: psihius Telegram: @psihius https://t.me/psihius
  106953
September 12, 2019 14:11 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 12, 2019 at 10:06 AM Arvids Godjuks godjuks@gmail.com>
wrote:

> > > чт, 12 сент. 2019 г. в 16:02, Chase Peeler <chasepeeler@gmail.com>: > >> On Thu, Sep 12, 2019 at 9:55 AM Claude Pache pache@gmail.com> >> wrote: >> >> > >> > >> > > Le 12 sept. 2019 à 15:33, Marco Pivetta <ocramius@gmail.com> a écrit >> : >> > > >> > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; >> > > >> > > Marco Pivetta >> > >> > That violates blatantly DRY (twice the exact same lengthy expression >> > `$foo[$key1][$key2]`), so it is not a satisfactory solution. >> > >> > And that's why PHP is so awesome. You don't have to do all these stupid >> tricks just to do something simple like increment a counter. But, it looks >> like we're going to throw that out of the window because some people think >> that since they like doing it like the way above, everyone should have to. >> >> > —Claude >> > >> > >> >> -- >> Chase Peeler >> chasepeeler@gmail.com >> > > Easy, because experience shows that leads to bugs and lots of them. > Security issues even. > If you want to write predictable code - you have to init your > variables/arrays. And check for existence/null. If fixed at least a few > dozen bugs in my system I took over in the last few months specifically > because of undefined variables or indexes. > > Never once have I advocated not initializing variables or arrays. I'm just saying that we shouldn't force such behavior. Many of us can figure out
when we need the extra boilerplate and when we don't. Don't force us to have to deal with the additional burden in every single case because someone else can't.
> It works for small stuff, but when you have a codebase with 100+k LOC and > more, you have to go strict or it starts to cost a lot of money and > personnel to keep things running along. > > -- > Arvīds Godjuks > > +371 26 851 664 > arvids.godjuks@gmail.com > Skype: psihius > Telegram: @psihius https://t.me/psihius >
-- Chase Peeler chasepeeler@gmail.com
  106952
September 12, 2019 14:10 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 12 Sep 2019 at 14:55, Claude Pache pache@gmail.com> wrote:

> Le 12 sept. 2019 à 15:33, Marco Pivetta <ocramius@gmail.com> a écrit : > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > Marco Pivetta > > > That violates blatantly DRY (twice the exact same lengthy expression > `$foo[$key1][$key2]`), so it is not a satisfactory solution. >
Agreed; it's certainly neater than all the isset() checks, but it's definitely a bit ugly. To clarify my point, the reason why people write this: $foo[$key1][$key2]++; Is not because they're lazy, it's because *it expresses their intent*. The ?key syntax was one suggestion for how to express the intent safely in that particular scenario. Another way might be that the array is initialised a different way; completely off the top of my head, something like this: $foo = new Dictionary>; That could express the intent of "this variable is going to be used as an accumulator with these dimensions". The "if isset" lines, in my opinion, don't express any intent, and they don't protect against any real errors; they're just noise to work around a short-coming in the language. Regards, -- Rowan Tommins [IMSoP]
  106957
September 12, 2019 14:13 nikita.ppv@gmail.com (Nikita Popov)
On Thu, Sep 12, 2019 at 4:11 PM Rowan Tommins collins@gmail.com>
wrote:

> On Thu, 12 Sep 2019 at 14:55, Claude Pache pache@gmail.com> wrote: > > > Le 12 sept. 2019 à 15:33, Marco Pivetta <ocramius@gmail.com> a écrit : > > > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > > > Marco Pivetta > > > > > > That violates blatantly DRY (twice the exact same lengthy expression > > `$foo[$key1][$key2]`), so it is not a satisfactory solution. > > > > > Agreed; it's certainly neater than all the isset() checks, but it's > definitely a bit ugly. > > To clarify my point, the reason why people write this: > > $foo[$key1][$key2]++; > > Is not because they're lazy, it's because *it expresses their intent*. > > The ?key syntax was one suggestion for how to express the intent safely in > that particular scenario. Another way might be that the array is > initialised a different way; completely off the top of my head, something > like this: > > $foo = new Dictionary>; > > That could express the intent of "this variable is going to be used as an > accumulator with these dimensions". > > The "if isset" lines, in my opinion, don't express any intent, and they > don't protect against any real errors; they're just noise to work around a > short-coming in the language.
FTR this is basically what Python does via defaultdict: https://docs.python.org/3/library/collections.html#collections.defaultdict I think it is the "cleanest" solution to this problem overall. Though it does need a separate structure, rather than our favorite PHP array. Nikita
  107020
September 12, 2019 20:59 rowan.collins@gmail.com (Rowan Tommins)
On 12/09/2019 15:13, Nikita Popov wrote:
> FTR this is basically what Python does via defaultdict: > https://docs.python.org/3/library/collections.html#collections.defaultdict
Thanks, I'm glad I wasn't completely daft thinking there might be some way to express it. :)
> I think it is the "cleanest" solution to this problem overall. Though > it does need a separate structure, rather than our favorite PHP array.
Indeed it does, and I think that's the better route to making PHP a stricter language: before we take away the existing features, add the new ones that let you express things better. PHP's array type, and its type system in general, allow a lot of very expressive algorithms which are hard to do with more rigid type systems. Modern languages like C# bring back that expressiveness using things like generics, a rich library of built-in collections and interfaces, and so on; they don't just say "sorry, you can't do that". Regards, -- Rowan Tommins (né Collins) [IMSoP]
  107025
September 12, 2019 21:51 smalyshev@gmail.com (Stanislav Malyshev)
Hi!

> FTR this is basically what Python does via defaultdict: > https://docs.python.org/3/library/collections.html#collections.defaultdict > > I think it is the "cleanest" solution to this problem overall. Though it > does need a separate structure, rather than our favorite PHP array.
This is one of the most annoying quirks of python - that you have to use special package to do simplest tasks like counting anything by key or write annoying boilerplate code that reminds python that counting starts with 0. Now strictness zealots want to bring that into PHP. If I was a person to do that, I'd definitely write a long "python sadness" text and that would feature there prominently, but I don't have time to do that so I just note that now, that it is very sad that the annoying quirks of python are brought into php apparently because more strict is always better. -- Stas Malyshev smalyshev@gmail.com
  106958
September 12, 2019 14:16 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 12, 2019 at 10:11 AM Rowan Tommins collins@gmail.com>
wrote:

> On Thu, 12 Sep 2019 at 14:55, Claude Pache pache@gmail.com> wrote: > > > Le 12 sept. 2019 à 15:33, Marco Pivetta <ocramius@gmail.com> a écrit : > > > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > > > Marco Pivetta > > > > > > That violates blatantly DRY (twice the exact same lengthy expression > > `$foo[$key1][$key2]`), so it is not a satisfactory solution. > > > > > Agreed; it's certainly neater than all the isset() checks, but it's > definitely a bit ugly. > > To clarify my point, the reason why people write this: > > $foo[$key1][$key2]++; > > Is not because they're lazy, it's because *it expresses their intent*. > > The ?key syntax was one suggestion for how to express the intent safely in > that particular scenario. Another way might be that the array is > initialised a different way; completely off the top of my head, something > like this: > > $foo = new Dictionary>; > > That could express the intent of "this variable is going to be used as an > accumulator with these dimensions". > > The "if isset" lines, in my opinion, don't express any intent, and they > don't protect against any real errors; they're just noise to work around a > short-coming in the language. > > But, if you're dealing with a counter, then, the intent is that you are going to start counting at 0 and increase it. In that case, if the variable
hasn't be initialized, or, the array key doesn't exist, it makes sense to assume it's 0. If you need to do something else besides assuming it's 0 and counting from there, then put in the extra code to check for that. I can do this already: if(!isset($i)){ return false; } $i++; So, why should I start having to do if(!isset($i)){ $i = 0; } $i++; when $i++; works just fine.
> Regards, > -- > Rowan Tommins > [IMSoP] >
-- Chase Peeler chasepeeler@gmail.com
  106962
September 12, 2019 14:43 robert@korulczyk.pl (Robert Korulczyk)
> But, if you're dealing with a counter, then, the intent is that you are > going to start counting at 0 and increase it.
This is not that clear as you may think. Several questions may come to mind when you will see incrementation of non-existing variable/key. Is it a bug and this should be initialized with a different value than 0? Maybe a mistake on copy&paste? Maybe a typo? One additional line will make your code much more obvious and easier to read and understand: $i ??= 0; $i++; Your code is not only for compiler/parser, but also for humans. Expressing your intentions clearly is important - the less ambiguity the better. Regards, Robert Korulczyk
  106964
September 12, 2019 14:49 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 12, 2019 at 10:43 AM Robert Korulczyk <robert@korulczyk.pl>
wrote:

> > But, if you're dealing with a counter, then, the intent is that you are > > going to start counting at 0 and increase it. > > This is not that clear as you may think. Several questions may come to > mind when you will see incrementation of non-existing variable/key. Is it a > bug > and this should be initialized with a different value than 0? Maybe a > mistake on copy&paste? Maybe a typo? > > One additional line will make your code much more obvious and easier to > read and understand: > > $i ??= 0; > $i++; >
And I'm totally in favor of writing code that way. What I'm not in favor of is breaking all of the existing code that doesn't do it that way and works perfectly fine because some people want to FORCE everyone to write it that way.
> Your code is not only for compiler/parser, but also for humans. Expressing > your intentions clearly is important - the less ambiguity the better. > > Regards, > Robert Korulczyk >
-- Chase Peeler chasepeeler@gmail.com
  107018
September 12, 2019 20:45 rowan.collins@gmail.com (Rowan Tommins)
On 12/09/2019 15:43, Robert Korulczyk wrote:
> One additional line will make your code much more obvious and easier to read and understand: > > $i ??= 0; > $i++;
I don't find this code at all obvious: foreach ( $something as $foo ) {     $i ??= 0;     $i++; } I mean, huh? What's that zero doing there, is it resetting the variable every loop? Now, in that simple case, you can and probably should initialise the counter before the loop: $i=0; foreach ( $something as $foo ) {     $i++; } But that's not the example I gave earlier! The example I gave earlier was a multi-dimensional array: $foo = []; foreach ( $something as $key1 ) {     foreach ( $somethingElse as $key2 ) {           $foo[$key1][$key2]++;     } } Even using ??= the initialise-everything-before-use version looks like this: $foo = []; foreach ( $something as $key1 ) {     foreach ( $somethingElse as $key2 ) {           $foo[$key1] ??= [];           $foo[$key1][$key2] ??= 0;           $foo[$key1][$key2]++;     } } Again, the values are confusing: the end result will never contain an empty array at the first level, and will never contain a 0 at the second level. Those two lines aren't aiding the readability of that algorithm in any way; I have to read past them to find the actual business of the loop, which is counting something, using the ++ operator. What's more, they're not preventing any bugs either! If I accidentally reuse $foo from a previous loop, the extra lines won't reinitialise anything for me; if I initialise it to empty, the two loops are functionally identical. So that's where I came up with two suggestions to actually add to the language, rather than just taking away: - a more granular way to express that this code is not actually error-prone, combining the 3 lines back into one - or, a way to express the intent of the code more clearly, such as declaring the shape of an array Regards, -- Rowan Tommins (né Collins) [IMSoP]
  107049
September 13, 2019 08:01 robert@korulczyk.pl (Robert Korulczyk)
W dniu 12.09.2019 o 22:45, Rowan Tommins pisze:
> On 12/09/2019 15:43, Robert Korulczyk wrote: >> One additional line will make your code much more obvious and easier to read and understand: >> >> $i ??= 0; >> $i++; > > > I don't find this code at all obvious: > > foreach ( $something as $foo ) { >     $i ??= 0; >     $i++; > }
That is because it does not make sense. You should initialize $i before loop, since it does not need a loop at all (and you probably don't need ??= here): $i ??= 0; foreach ( $something as $foo ) { $i++; }
> Even using ??= the initialise-everything-before-use version looks like this: > > $foo = []; > foreach ( $something as $key1 ) { >     foreach ( $somethingElse as $key2 ) { >           $foo[$key1] ??= []; >           $foo[$key1][$key2] ??= 0; >           $foo[$key1][$key2]++; >     } > }
Actually you need only one additional line: $foo = []; foreach ( $something as $key1 ) { foreach ( $somethingElse as $key2 ) { $foo[$key1][$key2] ??= 0; $foo[$key1][$key2]++; } }
> Again, the values are confusing: the end result will never contain an empty array at the first level, and will never contain a 0 at the second level.
It does not look confusing. You have two lines, for two intents - start counting from zero and increment counter on every loop iteration. If one additional line is to much for making your code less ambiguous and more bug-free, then I won't even try to change your mind. Regards, Robert Korulczyk
  107057
September 13, 2019 08:39 rowan.collins@gmail.com (Rowan Tommins)
On 13/09/2019 09:01, Robert Korulczyk wrote:
> Actually you need only one additional line: > > $foo = []; > foreach ( $something as $key1 ) { > foreach ( $somethingElse as $key2 ) { > $foo[$key1][$key2] ??= 0; > $foo[$key1][$key2]++; > } > }
Why? If "assume $key2 exists as a key and is an integer" is so bad that PHP should halt my program, why should "assume $key1 exists and is an array" be perfectly OK?
> It does not look confusing. You have two lines, for two intents - start counting from zero and increment counter on every loop iteration.
There is no intent to start counting at zero; the counter will never be lower than 1. If we really wanted to express the intent, we would have to write something like this: $foo[$key1] ??= []; if ( ! isset($foo[$key1][$key2]) ) {    $foo[$key1][$key2] = 1; } else {    $foo[$key1][$key2]++; }
> If one additional line is to much for making your code less ambiguous and more bug-free, then I won't even try to change your mind.
Please can you show me a bug that adding this line has avoided? I don't doubt that the same warning saves bugs in other scenarios, but in this scenario, the logic is unambiguous, and any additions are just to suppress unnecessary errors. To reiterate, my motivation here is to discuss features that help write these scenarios with less boilerplate, and separate them from other scenarios where there's a real bug risk which should raise an error. Regards, -- Rowan Tommins (né Collins) [IMSoP]
  107062
September 13, 2019 09:02 robert@korulczyk.pl (Robert Korulczyk)
> Why? If "assume $key2 exists as a key and is an integer" is so bad that PHP should halt my program, why should "assume $key1 exists and is an array" > be perfectly OK?
Warning is triggered by reading non-existing key, not assigning value to it. In `$foo[$key1][$key2] ??= 0` you never try to read non-existing key.
> Please can you show me a bug that adding this line has avoided? I don't doubt that the same warning saves bugs in other scenarios, but in this > scenario, the logic is unambiguous, and any additions are just to suppress unnecessary errors.
Well, then let's say that it is "lesser evil" - one additional line is better than ignoring reading uninitialized values. And IMO it is not a "problem" that would justify introducing special syntax for saving one line in such niche case. Regards, Robert Korulczyk
  107066
September 13, 2019 09:21 rowan.collins@gmail.com (Rowan Tommins)
On 13/09/2019 10:02, Robert Korulczyk wrote:
>> Why? If "assume $key2 exists as a key and is an integer" is so bad that PHP should halt my program, why should "assume $key1 exists and is an array" >> be perfectly OK? > Warning is triggered by reading non-existing key, not assigning value to it. In `$foo[$key1][$key2] ??= 0` you never try to read non-existing key.
$foo[$key1] has to be read to determine if it's already an array, and if it has the key $key2, in the same way that in $foo[$key1]++, $foo[$key1] has to be read to determine if it's already an integer and what it's value is. If we're talking about being strict, we shouldn't limit ourselves to what happens to give a warning today, we should be consistent in our reasoning. So if the reasoning is that accessing uninitialised array keys is dangerous, I should not be able to mention $foo[$key1][$key2] if $foo[$key1] doesn't yet exist. Regards, -- Rowan Tommins (né Collins) [IMSoP]
  107071
September 13, 2019 09:40 robert@korulczyk.pl (Robert Korulczyk)
> $foo[$key1] has to be read to determine if it's already an array, and if it has the key $key2, in the same way that in $foo[$key1]++, $foo[$key1] has > to be read to determine if it's already an integer and what it's value is.
$foo[$key1] needs to be read only to obtain previous value, type is irrelevant (obviously you will get error if types does not allow for such operation, but it has nothing to do with accessing uninitialized variables/keys). You can't increment $foo[$key1] without knowing current value of $foo[$key1] - you need to read it first. But you don't need to know previous value (or its type) to overwrite it (it does not matter what is $foo[$key1] value if you do `$foo[$key1] = 1` - it works similar to `$foo = 1`); Regards, Robert Korulczyk
  106954
September 12, 2019 14:12 benjamin.morel@gmail.com (Benjamin Morel)
>> $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > That violates blatantly DRY (twice the exact same lengthy expression `$foo[$key1][$key2]`), so it is not a satisfactory solution.
$foo[$key1][$key2]??++ 😃 More seriously, yes as Marco suggested, yes we can already do it, and as Claude pointed out, yes that's verbose. What I had in mind with language support is some kind of code-level (per line or block) switch that would allow uninitialized array keys to behave in a certain way, *depending on the context* : we actually have not one, but two good examples of this above, provided that $key1 and $key2 do not exist: - with [], an unitialized key would be initialized with an empty array (already does that) - with ++, an unitialized key would be initialized with 0 Without the proper code-level switch, we could safely have both cases above throw an exception. — Benjamin
  106949
September 12, 2019 14:02 arvids.godjuks@gmail.com (Arvids Godjuks)
чт, 12 сент. 2019 г. в 15:33, Marco Pivetta <ocramius@gmail.com>:

> Hey Rowan, > <http://ocramius.github.com/> > > > On Thu, Sep 12, 2019 at 3:30 PM Rowan Tommins collins@gmail.com> > wrote: > > > For instance, for undefined array keys, what if we had an operator for > > "initialise and retrieve", such as $foo[? 'bar']. Then we could simplify > > ugly code like this: > > > > if ( ! isset($foo[$key1]) { > > $foo[$key1] = []; > > } > > if ( ! isset($foo[$key1][$key2]) { > > $foo[$key1][$key2] = 0; > > } > > $foo[$key1][$key2]++; > > > > > > With something safe but succinct like this: > > > > $foo[? $key1][? $key2]++; > > > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > Marco Pivetta > > http://twitter.com/Ocramius > > http://ocramius.github.com/ >
This message contains a healthy dose of sarcasm. Hi Marko and Rowan :) *Me reviewing the PR with that code* *Clicks "Changes required" [ Please rewrite this statement into easy readable format with an if ] * Clicks send * Think what you must, but 6 months when you come back to code like this you have to stop, look at it hard and figure out what the hell actually happens there. Breaks reading flow. One thing I like PHP for is a distinct lack of huge amounts of syntax sugar. Take Ruby - it's a hell to read the code. Even Vagrantfile has tons of results about what syntax for arrays to use and things breaking because you end up mixing stuff and you get at least 4 different answers to the same question and it looks like all are correct. Confusing as hell :) What I'm trying to say is some of us choose PHP for it's "there is one syntax - use it". If people want syntax sugar - there are other languages that fit that much better. Leave us, peasants, in our peasant non-syntax sugar world alone :D But many of us would also like the language engine to tighten up some of its extremely relaxed parts that do not fit in modern development environments and the lowest bar of the code quality rise a bit. Otherwise, the gap between high-end development and newbies is going to be even bigger than it is now. I hire people, that's part of my job. One of the criteria is the approach to errors/warning/notices. Imagine how that goes. -- Arvīds Godjuks +371 26 851 664 arvids.godjuks@gmail.com Skype: psihius Telegram: @psihius https://t.me/psihius
  106951
September 12, 2019 14:07 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 12, 2019 at 10:02 AM Arvids Godjuks godjuks@gmail.com>
wrote:

> чт, 12 сент. 2019 г. в 15:33, Marco Pivetta <ocramius@gmail.com>: > > > Hey Rowan, > > <http://ocramius.github.com/> > > > > > > On Thu, Sep 12, 2019 at 3:30 PM Rowan Tommins collins@gmail.com> > > wrote: > > > > > For instance, for undefined array keys, what if we had an operator for > > > "initialise and retrieve", such as $foo[? 'bar']. Then we could > simplify > > > ugly code like this: > > > > > > if ( ! isset($foo[$key1]) { > > > $foo[$key1] = []; > > > } > > > if ( ! isset($foo[$key1][$key2]) { > > > $foo[$key1][$key2] = 0; > > > } > > > $foo[$key1][$key2]++; > > > > > > > > > With something safe but succinct like this: > > > > > > $foo[? $key1][? $key2]++; > > > > > > > $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > > > > Marco Pivetta > > > > http://twitter.com/Ocramius > > > > http://ocramius.github.com/ > > > > This message contains a healthy dose of sarcasm. > > Hi Marko and Rowan :) > > *Me reviewing the PR with that code* > *Clicks "Changes required" > [ Please rewrite this statement into easy readable format with an if ] > * Clicks send * > > Think what you must, but 6 months when you come back to code like this you > have to stop, look at it hard and figure out what the hell actually happens > there. > Breaks reading flow. > > One thing I like PHP for is a distinct lack of huge amounts of syntax > sugar. > Take Ruby - it's a hell to read the code. Even Vagrantfile has tons of > results about what syntax for arrays to use and things breaking because you > end up mixing stuff and you get at least 4 different answers to the same > question and it looks like all are correct. Confusing as hell :) > > What I'm trying to say is some of us choose PHP for it's "there is one > syntax - use it". If people want syntax sugar - there are other languages > that fit that much better. Leave us, peasants, in our peasant non-syntax > sugar world alone :D > > Exactly. One common theme I've been seeing is "We already force our developers to initialize variables, so, whats the big deal if you have to?"
or "We already force a no-notice environment, so what's the big deal if you have to?" If you're already doing it, then why do you feel the need to force others to? You've proven that it can be done in the current system. I'm making my prediction now - if this RFC passes, the adoption rate for PHP 8 is going to be HORRIBLE.
> But many of us would also like the language engine to tighten up some of > its extremely relaxed parts that do not fit in modern development > environments and the lowest bar of the code quality rise a bit. Otherwise, > the gap between high-end development and newbies is going to be even bigger > than it is now. > I hire people, that's part of my job. One of the criteria is the approach > to errors/warning/notices. Imagine how that goes. > > -- > Arvīds Godjuks > > +371 26 851 664 > arvids.godjuks@gmail.com > Skype: psihius > Telegram: @psihius https://t.me/psihius >
-- Chase Peeler chasepeeler@gmail.com
  106956
September 12, 2019 14:13 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 12 Sep 2019 at 15:02, Arvids Godjuks godjuks@gmail.com>
wrote:

> > This message contains a healthy dose of sarcasm. >
I think we need less sarcasm on this thread, and more empathy. I'm doing my best to discuss a real scenario, and how to improve the language for it, and move away from oh-so-hilarious parodies of each other's positions. Regards, -- Rowan Tommins [IMSoP]
  106960
September 12, 2019 14:25 ocramius@gmail.com (Marco Pivetta)
<http://ocramius.github.com/>


On Thu, Sep 12, 2019 at 4:02 PM Arvids Godjuks godjuks@gmail.com>
wrote:

> > > чт, 12 сент. 2019 г. в 15:33, Marco Pivetta <ocramius@gmail.com>: > >> Hey Rowan, >> <http://ocramius.github.com/> >> >> >> On Thu, Sep 12, 2019 at 3:30 PM Rowan Tommins collins@gmail.com> >> wrote: >> >> > For instance, for undefined array keys, what if we had an operator for >> > "initialise and retrieve", such as $foo[? 'bar']. Then we could simplify >> > ugly code like this: >> > >> > if ( ! isset($foo[$key1]) { >> > $foo[$key1] = []; >> > } >> > if ( ! isset($foo[$key1][$key2]) { >> > $foo[$key1][$key2] = 0; >> > } >> > $foo[$key1][$key2]++; >> > >> > >> > With something safe but succinct like this: >> > >> > $foo[? $key1][? $key2]++; >> > >> >> $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; >> >> >> > This message contains a healthy dose of sarcasm. > > No sarcasm intended: question is about the verbosity and length of a
*proper* (correct = no warnings/notices/errors, matches type expectations) checked solution, and I provided a simple one-liner that is both readable and correct. You can make what you want out of this, but there was most certainly no sarcasm. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/
  106961
September 12, 2019 14:27 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 12, 2019 at 10:20 AM Reindl Harald (privat) <harry@rhsoft.net>
wrote:

> see screenshot, you are the only guy on planet earth whose fukcing first > line is part of the quote above >
If you're going to reply to me off list, please at least be polite. -- Chase Peeler chasepeeler@gmail.com
  107027
September 12, 2019 21:56 andreas@dqxtech.net (Andreas Hennings)
In the past I suggested operators like
??++
??+=
for this purpose.

But the [? $key] is even better, because it makes it explicit which array
keys we expect to already exist and which we don't.

$var[$k0][? $k1][? $k2]++;

This is great but the second "?" is redundant isn't it?




Marco Pivetta <ocramius@gmail.com> schrieb am Do., 12. Sep. 2019, 16:26:

> <http://ocramius.github.com/> > > > On Thu, Sep 12, 2019 at 4:02 PM Arvids Godjuks godjuks@gmail.com> > wrote: > > > > > > > чт, 12 сент. 2019 г. в 15:33, Marco Pivetta <ocramius@gmail.com>: > > > >> Hey Rowan, > >> <http://ocramius.github.com/> > >> > >> > >> On Thu, Sep 12, 2019 at 3:30 PM Rowan Tommins collins@gmail.com> > >> wrote: > >> > >> > For instance, for undefined array keys, what if we had an operator for > >> > "initialise and retrieve", such as $foo[? 'bar']. Then we could > simplify > >> > ugly code like this: > >> > > >> > if ( ! isset($foo[$key1]) { > >> > $foo[$key1] = []; > >> > } > >> > if ( ! isset($foo[$key1][$key2]) { > >> > $foo[$key1][$key2] = 0; > >> > } > >> > $foo[$key1][$key2]++; > >> > > >> > > >> > With something safe but succinct like this: > >> > > >> > $foo[? $key1][? $key2]++; > >> > > >> > >> $foo[$key1][$key2] = ($foo[$key1][$key2] ?? 0) + 1; > >> > >> > >> > > This message contains a healthy dose of sarcasm. > > > > > No sarcasm intended: question is about the verbosity and length of a > *proper* (correct = no warnings/notices/errors, matches type expectations) > checked solution, and I provided a simple one-liner that is both readable > and correct. > > You can make what you want out of this, but there was most certainly no > sarcasm. > > Marco Pivetta > > http://twitter.com/Ocramius > > http://ocramius.github.com/ >
  107034
September 12, 2019 23:29 arnold.adaniels.nl@gmail.com (Arnold Daniels)
l want to point out that way in which notices and warnings are triggered
when concerning operators, is also inconsistent.
Sometimes a check is done by the function of the operator (or a deeper
function). Other times the operator will simply cast the operand and the
casting produces a notice, warning or error.

As an example; The concatenation operator will implicitly cast anything to
a string. Explicitly casting it has no effect

    [ ] . 'abc'; // Notice:  Array to string conversion
    (string)[ ] . 'abc'; // Notice:  Array to string conversion

But arithmetic operators will do a check. Explicitly casting will remove
any warning or error

    [ ] * 10; // Fatal error:  Unsupported operand types
    (int)[ ] * 10; // 0
    "22 bikes" * 10; // Notice:  A non well formed numeric value encountered
    (int)"22 bikes" * 10; // 220

To some extent, the inconsistent error levels come from a different
approach. Even more, there is a big difference between types that can are
cast silently to a non-sensical value and types where any type of warning
or error is given, for seemingly no apparent reason.

Changing the warning levels without addressing this issue doesn't make a
whole lot of sense.

- Arnold
In the past I suggested operators like
??++
??+=
for this purpose.

But the [? $key] is even better, because it makes it explicit which array
keys we expect to already exist and which we don't.

$var[$k0][? $k1][? $k2]++;

This is great but the second "?" is redundant isn't it?
Tekst uit oorspronkelijke berichten weergeven
  107050
September 13, 2019 08:04 rowan.collins@gmail.com (Rowan Tommins)
On 12/09/2019 22:56, Andreas Hennings wrote:
> $var[$k0][? $k1][? $k2]++; > > This is great but the second "?" is redundant isn't it?
If the rule is "you cannot read a non-existent array element without ?" then no: $var[$k0][? $k1] allows you to read that element, and from context treat it as an array; but that array won't have a key $k2, so you also need to say that reading *that* was deliberate, and from context treat it as an integer. Regards, -- Rowan Tommins (né Collins) [IMSoP]
  107056
September 13, 2019 08:30 brendt@stitcher.io (Brent)
Hello all

I've noticed a trend in many threads here on the internals list where an RFC is being discussed, but one way or another we always end up with the same offtopic conversation about how PHP should evolve. While I think this is a good conversation to have, I don't think it's beneficial for the RFC process to have the same discussion happening over and over again, effectively having the RFC discussion hijacked by another one. I can only imagine it must be quite difficult for the people working on these RFCs to filter out ontopic from offtopic content.

Here are a few examples:

- Reclassifying engine warnings (https://externals.io/message/106713)
- Short open tags (https://externals.io/message/106384)
- Namespaced scope declares (https://externals.io/message/101323)
- Call-site send by ref (https://externals.io/message/101254)
- PHP 7.4 deprecations (https://externals.io/message/106012)

Maybe someone has a good suggestion on how people can voice their opinion on the future of PHP, without polluting several RFC discussions.

Kinds regards
Brent
  107058
September 13, 2019 08:49 petercowburn@gmail.com (Peter Cowburn)
On Fri, 13 Sep 2019 at 09:30, Brent <brendt@stitcher.io> wrote:

> Hello all > > I've noticed a trend in many threads here on the internals list where an > RFC is being discussed, but one way or another we always end up with the > same offtopic conversation about how PHP should evolve. While I think this > is a good conversation to have, I don't think it's beneficial for the RFC > process to have the same discussion happening over and over again, > effectively having the RFC discussion hijacked by another one. I can only > imagine it must be quite difficult for the people working on these RFCs to > filter out ontopic from offtopic content. > > Here are a few examples: > > - Reclassifying engine warnings (https://externals.io/message/106713) > - Short open tags (https://externals.io/message/106384) > - Namespaced scope declares (https://externals.io/message/101323) > - Call-site send by ref (https://externals.io/message/101254) > - PHP 7.4 deprecations (https://externals.io/message/106012) > > Maybe someone has a good suggestion on how people can voice their opinion > on the future of PHP, without polluting several RFC discussions. >
Start a new thread (or threads) instead of replying to RFC threads. 🤔
> Kinds regards > Brent >
  107032
September 12, 2019 22:44 mike@newclarity.net (Mike Schinkel)
> One thing I like PHP for is a distinct lack of huge amounts of syntax > sugar. Take Ruby - it's a hell to read the code.
I think it is unfair to reference Ruby's capabilities as a counter-example for syntax sugar. The Ruby language allows developers to create what are effectively new language constructs and it is possible in Ruby to write code that cannot be recognized anyone that has not written the language extensions being used. PHP does not have that capability, thankfully, and I do not think any proposed syntax sugar has any chance of adding those meta-language capabilities into PHP. Syntax sugar is a good thing when it reduces the need to write boilerplate code for a commonly occurring pattern, especially when the boilerplate code is tedious and potentially error prone because of typos or logic. And it is naturally occurring in language evolution, i.e. newer languages often provide "syntax sugar" for features that are more verbose in earlier languages. Personally I am not sure I like the proposed syntax, but I am definitely fond of the idea to eliminate the boilerplate code that would be otherwise needed to build a robust solution. #fwiw -Mike P.S. I wrote a blog post in defense of syntactic sugar a while ago. If you are interested in all the arguments in support of syntactic sugar, here is the post: https://mikeschinkel.me/2019/in-defense-of-syntactic-sugar/ <https://mikeschinkel.me/2019/in-defense-of-syntactic-sugar/>
> Even Vagrantfile has tons of > results about what syntax for arrays to use and things breaking because you > end up mixing stuff and you get at least 4 different answers to the same > question and it looks like all are correct. Confusing as hell :) > > What I'm trying to say is some of us choose PHP for it's "there is one > syntax - use it". If people want syntax sugar - there are other languages > that fit that much better. Leave us, peasants, in our peasant non-syntax > sugar world alone :D > > But many of us would also like the language engine to tighten up some of > its extremely relaxed parts that do not fit in modern development > environments and the lowest bar of the code quality rise a bit. Otherwise, > the gap between high-end development and newbies is going to be even bigger > than it is now. > I hire people, that's part of my job. One of the criteria is the approach > to errors/warning/notices. Imagine how that goes. > > -- > Arvīds Godjuks > > +371 26 851 664 > arvids.godjuks@gmail.com > Skype: psihius > Telegram: @psihius https://t.me/psihius
  106944
September 12, 2019 13:50 chasepeeler@gmail.com (Chase Peeler)
On Thu, Sep 12, 2019 at 5:41 AM Claude Pache pache@gmail.com> wrote:

> > > > Le 12 sept. 2019 à 10:17, Stephen Reay <php-lists@koalephant.com> a > écrit : > > > > > > > > I’ve seen a number of people that have concerns about PHP throwing > actual errors (as opposed to notices) because they try to use a > variable/offset that doesn’t exist, and of course there is often a proposal > to have a declare statement or something similar, to allow their “code > style” to run without errors. > > > > > > So, my proposal to the situation is to introduce a single declare that > solves that problem, once and for all. > > > > > > declare(sloppy=1); > > > > > > This would suppress any errors about undefined variables, array offsets, > would reverse the “bare words" change when encountering an undefined > constant, etc. Heck, for good measure this mode could even re-implement > register_globals and magic_quotes, because why not? > >
This still forces people to opt-in to something that has been supported for 20+ years, and there isn't even a consensus on it being "sloppy" to begin with.
>
> > > > > If you want to write sloppy code, that is entirely your prerogative, but > please just own it for what it is, and stop pretending that it’s some > herculean task to either define variables/offsets first; or check if > they’re defined; or use an appropriate method to access them that > specifically allows for undefined variables/offsets (i.e. the ?? and ??= > operators) > > > > > > Declare(sloppy=yeah) is not granular enough. To all: please, do understand > that everything is not black or white; this remark is not directed > specifically to that particular issue, this is an attitude I see regularly > on that mailing list. > > There is no such thing as “one true strict coding standard” and “one > legacy lax coding standard”. For instance: > > * As time passes, we learn by experience what features were plain blunders > (magic_quotes?), what features should have been more strict for the sake of > catching bugs without imposing too much burden on users, what features > could have been more strict, although that would impose to write lot of > boiler code, etc. This process does not belong exclusively to some past > dark age of sloppy and unsecure coding practices. > > * The degree of wanted strictness vary depending on occasions. For example > when I’m writing a throw-away script, some notices are okay to indicate > possible problems, but I’m not going to write boilerplate code (or, worse, > put a @ in front of everything) just for the sake of silencing them. (But I > *certainly* do not want stupid things like mistyped constants converted to > string literals.) On the other hand, when I’m writing a critical part of an > application, I am careful to write down everything precisely, and having to > write explicitly and once for all that, yes, this precise variable must > have that default value, is a minimal part of the time passed to write, > re-read and review the code. > > What??? You mean it's possible to write strict code even when the engine doesn't force you to? But I got the feeling that wasn't possible and we
needed to force EVERYONE to code this way.
> —Claude > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Chase Peeler chasepeeler@gmail.com
  106934
September 12, 2019 09:27 nikita.ppv@gmail.com (Nikita Popov)
On Thu, Sep 12, 2019 at 9:40 AM Claude Pache pache@gmail.com> wrote:

> > Le 10 sept. 2019 à 15:31, Nikita Popov ppv@gmail.com> a écrit : > > > > On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov ppv@gmail.com> > wrote: > > > >> Hi internals, > >> > >> I think it's time to take a look at our existing warnings & notices in > the > >> engine, and think about whether their current classification is still > >> appropriate. Error conditions like "undefined variable" only generating > a > >> notice is really quite mind-boggling. > >> > >> I've prepared an RFC with some suggested classifications, though there's > >> room for bikeshedding here... > >> > >> https://wiki.php.net/rfc/engine_warnings > >> > >> Regards, > >> Nikita > >> > > > > Heads up: This RFC may go to vote tomorrow. > > > > Nikita > > > I have objections to those two reclassifications: > > * Undefined offset: %d — Notice → Warning > * Undefined index: %d — Notice → Warning > > > From experience, having to dutifully initialise each and every key in an > array is burdensome. I understand the rationale of enforcing that in some > coding standard; but whether those particular missing index should be > considered as unexpected (therefore deserving a Warning) is mostly a > question of coding style. > > This is in principle a similar issue as using uninitialised variables, > which, as noted in this thread, is a perfectly accepted coding pattern in > some languages (the issue being distinct from *undeclared* variables). I > say “in principle”, because a perfectly reasonable coding style may choose > to enforce initialisation of variables, but not of array keys. > > PHP has the advantage of supporting various coding styles. We should give > the opportunity to the users to say declaratively (and precisely) what, in > their coding style, is considered as acceptable, e.g. > > declare( > uninitialized_variables: error > uninitilalized_index: none > ); > > of course, possibly at a package-level declare. That would, for example, > enable people to place legacy code in lax mode and chose a stricter mode > for new code, even letting the precise notion of strictness vary with > fashion without having to review working code written two years ago. > > That said, as long as those issues are handled as errors (as in: > set_error_handler()) rather than exceptions, one may write a proper error > handler that does the distinction (I do that). However, an error handler > has the disadvantage of being global, making difficult the integration of > code written with differing coding standards. > > —Claude >
Hi Claude, I have split off the question of undefined array keys into a separate section, which will be voted separately. I generally agree that ignoring undefined array key notices can be a legitimate coding style choice (while I would very much disagree that the same is true for undefined variables) -- though ultimately I think it is best to handle this with a custom error handler (which can check whether the error originated from your own codebase), rather than through a blanket suppression of notices. In line with that thinking I don't think it matters overly much whether it's a notice or warning for the purposes of suppression. But I also don't feel particularly strongly about having this case as a warning either, especially with the error_reporting=E_ALL default in PHP 8. Nikita
  107083
September 13, 2019 23:42 webdevxp.com@gmail.com (Kosit Supanyo)
Hi internals

This maybe a little bit late but I would like to propose alternative to
this RFC.

What if we add `strict_errors` declare to make every function/method in
files that declared `strict_errors` throw ErrorException on Notice/Warning.

Example:

File: Test.php
https://github.com/webdevxp/php-src.
What I've done was just adding new ZEND_ACC_STRICT_ERRORS flag to top level
function and modified `php_error_cb` to check if there is a caller with
`strict_errors` defined. (by simply checking `EG(current_execute_data)` and
its all `prev_execute_data`)

I think this approach might satify both 'strict camp' and 'bc camp'.

P.S. I myself agree with this RFC and would vote YES if I can vote. And I'm
grateful for Nikita's (and others) contributions that make PHP awesome
today.

Cheers :)

On Wed, Aug 28, 2019 at 4:33 PM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > I think it's time to take a look at our existing warnings & notices in the > engine, and think about whether their current classification is still > appropriate. Error conditions like "undefined variable" only generating a > notice is really quite mind-boggling. > > I've prepared an RFC with some suggested classifications, though there's > room for bikeshedding here... > > https://wiki.php.net/rfc/engine_warnings > > Regards, > Nikita >
  107095
September 14, 2019 21:18 oludonsexy@gmail.com (Olumide Samson)
https://jaxenter.com/php-tiobe-sept-2019-162096.html
I think this is one of those things we get from voting no...

I might be wrong anyways :-?

On Sat, Sep 14, 2019, 12:43 AM Kosit Supanyo com@gmail.com> wrote:

> Hi internals > > This maybe a little bit late but I would like to propose alternative to > this RFC. > > What if we add `strict_errors` declare to make every function/method in > files that declared `strict_errors` throw ErrorException on Notice/Warning. > > Example: > > File: Test.php > declare(strict_errors=1); // does not support block declare like > 'strict_type' > > class Test { > public function __construct() > { > echo $a; // ErrorException will be thrown from here > } > } > > File: main.php > require 'Test.php'; > $test = new Test(); // Fatal error: Uncaught ErrorException: Undefined > variable: a > > But if `set_error_handler()` is in use nothing will happen. > > File: main.php > require 'Test.php'; > set_error_handler(function () { > > }); > $test = new Test(); // silent > > I've just made a naive implementation to demonstrate this approach at > https://github.com/webdevxp/php-src. > What I've done was just adding new ZEND_ACC_STRICT_ERRORS flag to top level > function and modified `php_error_cb` to check if there is a caller with > `strict_errors` defined. (by simply checking `EG(current_execute_data)` and > its all `prev_execute_data`) > > I think this approach might satify both 'strict camp' and 'bc camp'. > > P.S. I myself agree with this RFC and would vote YES if I can vote. And I'm > grateful for Nikita's (and others) contributions that make PHP awesome > today. > > Cheers :) > > On Wed, Aug 28, 2019 at 4:33 PM Nikita Popov ppv@gmail.com> wrote: > > > Hi internals, > > > > I think it's time to take a look at our existing warnings & notices in > the > > engine, and think about whether their current classification is still > > appropriate. Error conditions like "undefined variable" only generating a > > notice is really quite mind-boggling. > > > > I've prepared an RFC with some suggested classifications, though there's > > room for bikeshedding here... > > > > https://wiki.php.net/rfc/engine_warnings > > > > Regards, > > Nikita > > >
  107128
September 15, 2019 23:10 marandall@php.net (Mark Randall)
On 28/08/2019 10:33, Nikita Popov wrote:

I am 100% behind the exception proposals, however I did want to discuss 
the warnings.

I am personally of the belief that there should be a distinction made 
between notices / warnings issued by the engine, and those issued by 
extensions, including standard.

I am one of a large number of developers that enforces a "No notice or 
warning" requirement on their codebases. To this end I use a global 
error handler that converts ANY notice or error to an \Error exception 
(within our specific code, so excluding anything in /vendor and the likes).

This does however, effect function calls as well, and it's less ideal to 
have function calls throwing Error, something derived from Exception 
would make more sense. The issue is which is which.

If this does pass, I was wondering if there would be any appetite for 
re-using the E_CORE_XXX error error codes specifically to refer to ALL 
engine warnings, not just those at startup.

Alternatively, the passing of a bitflag to indicate they came from the 
engine while still preserving the original bit, although that may be 
more of a BC break due to requiring bitwise mask comparison in existing 
handlers.

Either way, this this would allow easily differentiating engine warnings 
that will become more prominent in this RFC, with those contained in 
PHP_FUNCTION scope.



--
Mark Randall