Hacker News new | ask | show | jobs
by cousin_it 4748 days ago
> how would you update them automatically if you decided to change the way htmlspecialchars() works?

I see two possible cases, the choice between which can be made by the converter developers or by the user (maybe via command-line flags to the converter):

1) If the new functionality is intended to be a drop-in replacement (e.g. it fixes a security bug), no change is necessary.

2) If we want existing programs to keep using the old functionality, you could automatically translate all cases like this (assuming we're translating from PHP7 to PHP8):

    echo $h('<script>');  // PHP7 code
to this:

    echo php7_varcall($h, '<script>');  // PHP8 code
To clarify, php7_varcall() is a function in PHP8. When it receives 'htmlspecialchars' as an argument, it calls the function php7_htmlspecialchars() which is a faithful rewrite of PHP7's htmlspecialchars() in PHP8.

> If a function that used to return FALSE on failure is updated to throw an exception instead, an automated tool would have to wrap every function call with a try-catch block, with potentially unexpected side effects.

In general, any php7_builtin() should be implementable in PHP8 somehow. If that's not possible, I'd say there's a gross design error somewhere.

> If a function that used to take strings in the system charset by default is updated to take UTF-8 all the time, you'll have to throw in some code for charset conversion before every occurrence of that function, but some servers might not have mbstring/iconv installed and turn that into a fatal error.

In general, if the implementation of php7_builtin() in PHP8 relies on some library, then that library should be included in the "compatibility library" required to run all converted code.

1 comments

So your solution is to add more functions, like php7_htmlspecialchars(), php7_htmlentities(), etc. whenever a function needs to be deprecated, just like PHP historically added functions like mysql_escape_string(), mysql_real_escape_string(), etc.? I don't think that will help the language and its ecosystem at all. I can almost see the tutorials in my mind: "If you upgrade to PHP 8 and your function call suddenly starts spewing errors, just use php7_function and your problem is solved!" Then 3 years later: "just use php8_function!"

Anyway, my point was that static analysis, which an upgrade script needs to perform, has serious limitations when it comes to dynamic features. Callable variables are a good example of this. What if there are 100 places in your codebase where a variable is callable, but only one of them is ever going to contain a deprecated function? Static analysis can't tell which one it is, because at runtime, the variables might come from anywhere: user input, a database, a command-line argument, or the phase of the moon. The only bulletproof solution is to convert them all to php7_varcall(), even the 99 variables that don't need upgrading. But then your code just becomes unreadable, and therefore even more unmaintainable than before.

Functions like php7_htmlspecialchars() wouldn't live in the standard library, they would live in the "compatibility library" instead. That might help discourage new users from using them and mentioning them in tutorials.

I agree with your point that bulletproof conversion will make reflection-heavy code less readable. But still, if we can make a bulletproof converter that works on 100% of old code and leaves simple code relatively unchanged, doesn't that open up some nice options for everyone?

- Users who don't care about code quality, and just want their old code to work, will be happy because they will have a push-button upgrade solution.

- Users who care about code quality will also be happy, because they can run the converter and have a complete working program right away. Afterwards they can modernize it piece by piece, at their own pace, having a complete working program at each step. Without the converter they'd be stuck doing a full rewrite.

- Language implementors will be happy because they can keep the language clean as it evolves. Imagine how awesome Java could be today if they took this route.