Page MenuHomePhorge

Remove use of deprecated E_STRICT PHP constant
ClosedPublic

Authored by aklapper on Feb 17 2025, 11:49.

Details

Summary

The E_STRICT PHP constant is deprecated since PHP 8.4 per https://www.php.net/manual/en/migration84.deprecated.php.
Per https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant, the E_STRICT constant was still in use in-between PHP 7.0 and 7.4 for PHP's mysqli extension and PHP's htmlentities() function.

The E_STRICT notice was removed from PHP's mysqli extension in https://github.com/php/php-src/commit/e895e962867123aff6ea703ff41670b7eb5c47f1 for PHP 7.4.0.
Since rP23a49eb403c9ea6c58f4ae2f22416e90a9d24c14, Phorge requires 7.2.25.
Phorge does not call PHP's htmlentities() function.

E_STRICT is a part of E_ALL since PHP 5.4.0 per https://github.com/php/php-src/blob/php-5.4.0/NEWS#L69, thus there is no gain in keeping it.

Closes T15989

Test Plan

None.

Diff Detail

Repository
rP Phorge
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Phorge neither uses PHP's mysqli extension nor calls PHP's htmlentities() function.

Are you sure about that? Phorge supports either the old mysql extension or mysqli - and mysql was deprecated in PHP 5.5, and removed in PHP 7.0. Notably, Phorge checks for the existence of mysqli in PhabricatorDatabaseRef, PhabricatorExtensionSetupCheck and PhabricatorPHPConfigSetupCheck.

Yeah I was also pretty sure Phab used mysqli? I have had to have it on all my installations, and the Phorge documentation still cites it. https://we.phorge.it/book/contrib/article/database/

Though for the scope of the concern here that shouldn't matter, as per the quoted details the mysqli extension was only using E_STRICT between a range of PHP versions now in the rearview mirror, the removal of it was approved and merged at the end of August 2019, so continued use of the mysqli extension won't trip Phorge up for this deprecation.

I cannot remember how I attempted (and failed) to check a few weeks ago... Thank you both for jumping in and correcting!

Phorge supports either the old mysql extension or mysqli - and mysql was deprecated in PHP 5.5, and removed in PHP 7.0.

That sounds like technical debt to remove so I filed T16024

After upgrading to PHP 8.4 this issue blocks me now from doing development work as arc diff fails:

Screenshot From 2025-05-09 09-15-08.png (710×1 px, 136 KB)

And Phorge fails to render at all in both Firefox and Chromium (Phorge renders after applying this very patch):
Screenshot From 2025-05-09 09-00-07.png (973×1 px, 112 KB)

avivey subscribed.

I'd still not expect it to actually break anything - the docs say this const is "deprecated" not "removed", so I'd expect a warning and everything to keep working.
maybe something in the lint pipeline is dumping the warning on stdout instead of stderr.

This revision is now accepted and ready to land.Fri, May 9, 07:47

I'd still not expect it to actually break anything - the docs say this const is "deprecated" not "removed", so I'd expect a warning and everything to keep working.

I had/have the same theoretical expectation here. :-/

Just for my curiosity, can you please also follow the tip from the screenshot (before the patch), so, using --trace?

Just for my curiosity, can you please also follow the tip from the screenshot (before the patch), so, using --trace?

Sure. Probably this very comment should be moved to a separate ticket? I'll leave judgment to you (plural). :)

So after temporarily applying in Arcanist

diff --git a/src/utils/utils.php b/src/utils/utils.php
index 16042300..a1966b13 100644
--- a/src/utils/utils.php
+++ b/src/utils/utils.php
@@ -1312,6 +1312,9 @@ function phutil_microseconds_since($timestamp) {
  * @return  mixed     Decoded list/dictionary.
  */
 function phutil_json_decode($string) {
+error_log(print_r("===============================================>>==\n",true));
+error_log(print_r($string."\n",true));
+error_log(print_r("===============================================<<==\n",true));
   $result = @json_decode($string, true);
 
   if (!is_array($result)) {

to understand which parts of the verbose CLI output of ../arcanist/bin/arc diff --trace --update D25955 is supposed to be (valid) JSON, I get at some point in the output:

[...]
<<< [33] (+1,690) <lint> 11,490 us
>>> [34] (+1,691) <lint> XHPAST Lint <paths = 1>
<<< [34] (+1,691) <lint> 652 us
>>> [35] (+1,692) <lint> Phutil Library Linter <paths = 1>
>>> [36] (+1,695) <exec> $ php -f /var/www/html/phorge/arcanist/src/moduleutils/../../support/lib/extract-symbols.php -- --ugly --builtins -- 
<<< [36] (+1,864) <exec> 169,357 us
===============================================>>==


Deprecated: Constant E_STRICT is deprecated in /var/www/html/phorge/arcanist/support/init/init-script.php on line 18
{"have":{"class":{"InternalIterator":null,"Exception":null,"ErrorException":null,"Error":null,"CompileError":null,"ParseError":null,"TypeError":null,"ArgumentCountError":null,"ValueError":null,"ArithmeticError":null,"DivisionByZeroError":null,"UnhandledMatchError":null,"RequestParseBodyException":null,"Closure":null,"Generator":null,"ClosedGeneratorException":null,"WeakReference":null,"WeakMap":null,"Attribute":null,"ReturnTypeWillChange":null,"AllowDynamicProperties":null,"SensitiveParameter":null,"SensitiveParameterValue":null,"Override":null,"Deprecated":null,"Fiber":null,"FiberError":null,"stdClass":null,"DateTime":null,"DateTimeImmutable":null,"DateTimeZone":null,"DateInterval":null,"DatePeriod":null,"DateError":null,"DateObjectError":null,"DateRangeError":null,"DateException":null,"DateInvalidTimeZoneException":null,"DateInval[...]

which obviously isn't valid JSON due to prefixing the output with that Deprecated warning.

That is the only spot where this happens among all the calls to phutil_json_decode being executed when doing arc diff.

The stacktrace at the very end of the output is:

[2025-05-09 09:19:15] EXCEPTION: (PhutilAggregateException) Some linters failed:
    - PhutilJSONParserException: Parse error on line 1 at column 0: Expected one of: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[' at [<arcanist>/src/lint/engine/ArcanistLintEngine.php:264]
arcanist(head=master, ref.master=80906355979a), phorge(head=T15689, ref.master=8d688f59d123, ref.T15689=292fcc912441)
  #0 <#2> PhutilJSONParser::parse(string) called at [<arcanist>/src/utils/utils.php:1321]
  #1 <#2> phutil_json_decode(string) called at [<arcanist>/src/moduleutils/PhutilLibraryMapBuilder.php:256]
  #2 <#2> PhutilLibraryMapBuilder::newBuiltinMap() called at [<arcanist>/src/lint/linter/ArcanistPhutilLibraryLinter.php:73]
  #3 <#2> ArcanistPhutilLibraryLinter::willLintPaths(array) called at [<arcanist>/src/lint/engine/ArcanistLintEngine.php:576]
  #4 <#2> ArcanistLintEngine::executeLinterOnPaths(ArcanistPhutilLibraryLinter, array) called at [<arcanist>/src/lint/engine/ArcanistLintEngine.php:537]
  #5 <#2> ArcanistLintEngine::executeLintersOnChunk(array, array) called at [<arcanist>/src/lint/engine/ArcanistLintEngine.php:475]
  #6 <#2> ArcanistLintEngine::executeLinters(array) called at [<arcanist>/src/lint/engine/ArcanistLintEngine.php:206]
  #7 ArcanistLintEngine::run() called at [<arcanist>/src/workflow/ArcanistLintWorkflow.php:219]
  #8 ArcanistLintWorkflow::run() called at [<arcanist>/src/workflow/ArcanistDiffWorkflow.php:1170]
  #9 ArcanistDiffWorkflow::runLint() called at [<arcanist>/src/workflow/ArcanistDiffWorkflow.php:1132]
  #10 ArcanistDiffWorkflow::runLintUnit() called at [<arcanist>/src/workflow/ArcanistDiffWorkflow.php:363]
  #11 ArcanistDiffWorkflow::run() called at [<arcanist>/scripts/arcanist.php:427]
<<< [1] (+2,317) <exec> 2,317,121 us