On 24-2-2024 2:37, Gina P. Banyard wrote:
Hello internals,

I've been having this mild annoyance with exit()/die() since I wrote a CLI
script using a boolean $hasErrors variable to know if the script failed or not
and to indicate if the script failed via a non-zero status code by doing:
exit($hasErrors);

However, it turns this doesn't work, because exit() will cast everything
that is not an integer to a string, something that I find surprising but
also weird as it will not type error on resources or array but rather print
the warning to the CLI.

Anyway, yesterday I decided to put on my mad scientist lab coat and make this
a reality, I have a W.I.P. PR here:
https://github.com/php/php-src/pull/13483

I hear you, but what about exit; ?!
Do not worry exit; is still supported!
It only requires a _tiny_ bit of dark magic to achieve this!
exit; would just be interpreted as a fetch to a constant,
so when attempting to access the undefined exit/die case-insensitive constant
we just need to exit as if we were calling the function!

Having exit and die be functions gives us access to some interesting
functionality, such as defining exit() in a namespace, or removing it via the
disable_functions INI setting (the latter allowing us to define a custom global
exit() which could be useful for testing that a function actually calls exit).

We can also pass it like any other callable and reflect on it with reflection.

Finally, this removes the T_EXIT token and ZEND_EXIT opcode freeing one slot.

The W.I.P. PR implement every possible restriction:
  - not being able to declare an exit()/die() function
  - not being able to disable them
  - not being able to define a constant named exit/die

Maybe it would be wise to deprecate using exit as a statement to be able to get
rid of the undefined constant magic handling.

Anyhoot, before I spend more time on this and write a proper RFC, do people
think this is a good idea or not?


Best regards,

Gina P. Banyard


Hi Gina,

I'm not sure a pet-peeve is a good motivation for creating an (I expect large) breaking change.

The upgrade path, I suppose, would be updating calls to `die`/`exit` to always have parentheses ? Or alternatively changing those calls to new throw expressions ?

While that shouldn't be that huge a problem for real codebases (and would be auto-fixable for adding the parentheses), the bigger problem I see is the huge amount of teaching materials, tutorials and blog posts using the versions without parentheses which will now all be invalidated. I think the pain and confusion that will cause for a change like this, will linger for years and years.

Smile,
Juliette

Reply via email to