drush
drush copied to clipboard
PHP 8.1 issue on drush 8
I have an old installation of Drupal 7 and the server was recently upgraded to php 8.1 I am trying to get drush 8.4.10 working on it however I get the following:
PHP Fatal error: Uncaught TypeError: array_keys(): Argument #1 ($array) must be of type array, bool given in phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc:850 Stack trace: #0 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(850): array_keys(false) #1 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(521): annotationcommand_adapter_alter_option_description_fields(Array, Object(Consolidation\AnnotatedCommand\Parser\CommandInfo), '') #2 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(298): annotationcommand_adapter_get_commands_for_commandhandler(Object(Drush\Commands\core\StatusCommands), 'phar:///root/dr...') #3 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(109): annotationcommand_adapter_get_commands(Array) #4 phar:///root/drush8/drush.phar/includes/command.inc(1132): annotationcommand_adapter_commands() #5 phar:///root/drush8/drush.phar/includes/command.inc(1430): drush_get_commands() #6 phar:///root/drush8/drush.phar/includes/preflight.inc(599): drush_parse_command() #7 phar:///root/drush8/drush.phar/includes/preflight.inc(65): drush_preflight_command_dispatch() #8 phar:///root/drush8/drush.phar/includes/startup.inc(465): drush_main() #9 phar:///root/drush8/drush.phar/includes/startup.inc(369): drush_run_main(false, '/', 'Phar detected. ...') #10 phar:///root/drush8/drush.phar/drush(114): drush_startup(Array) #11 /root/drush8/drush.phar(14): require('phar:///root/dr...') #12 {main} thrown in phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc on line 850 Drush command terminated abnormally due to an unrecoverable error. [error] Error: Uncaught TypeError: array_keys(): Argument #1 ($array) must be of type array, bool given in phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc:850 Stack trace: #0 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(850): array_keys(false) #1 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(521): annotationcommand_adapter_alter_option_description_fields(Array, Object(Consolidation\AnnotatedCommand\Parser\CommandInfo), '') #2 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(298): annotationcommand_adapter_get_commands_for_commandhandler(Object(Drush\Commands\core\StatusCommands), 'phar:///root/dr...') #3 phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc(109): annotationcommand_adapter_get_commands(Array) #4 phar:///root/drush8/drush.phar/includes/command.inc(1132): annotationcommand_adapter_commands() #5 phar:///root/drush8/drush.phar/includes/command.inc(1430): drush_get_commands() #6 phar:///root/drush8/drush.phar/includes/preflight.inc(599): drush_parse_command() #7 phar:///root/drush8/drush.phar/includes/preflight.inc(65): drush_preflight_command_dispatch() #8 phar:///root/drush8/drush.phar/includes/startup.inc(465): drush_main() #9 phar:///root/drush8/drush.phar/includes/startup.inc(369): drush_run_main(false, '/', 'Phar detected. ...') #10 phar:///root/drush8/drush.phar/drush(114): drush_startup(Array) #11 /root/drush8/drush.phar(14): require('phar:///root/dr...') #12 {main} thrown in phar:///root/drush8/drush.phar/includes/annotationcommand_adapter.inc, line 850
Suggestions?
Is there any solution to this issue?
Looks like this would probably be resolved with a conditional somewhere around includes/annotationcommand_adapter.inc
. PRs welcome.
In PHP 8.1, both array_keys() and foreach were modded to check the expression being passed as the $array parameter to verify that it's an array (or other iterable expression, in the case of foreach). If it's not, it throws a fatal.
Let's assume that we have a function called do_this() which returns an array of values on success, or FALSE on failure (as do many baked-in PHP functions).
$myArray = do_this();
$keys = array_keys($myArray);
foreach ($keys as $k)
{
do_something_else($k);
}
In previous versions of PHP, if the expression passed to array_keys() was not an array, it would return FALSE. If the expression passed to foreach was not an array, it would treat it as an empty array and skip to the end of the loop.
So in the example above, if $myArray ended up being FALSE, $keys would also be FALSE, and the body of the foreach loop would never be executed.
But I guess that was too convenient.
The workaround I've used so far is to call is_array() on anything I'm about to send to array_keys().
if (is_array($myArray))
{
$keys = array_keys($myArray);
foreach ($keys as $k)
{
do_something_else($k);
}
}
This approach prevents both array_keys() and foreach from accidentally receiving a non-array parameter.
If you're root on the test box, you might also want to try upgrading it to Drupal 10. It requires PHP 8.1 or better (I think they recommend 8.1.6) and may eliminate some of these issues for you.
https://www.drupal.org/docs/system-requirements/php-requirements
Or you may end up in worse shape. I don't have the Drupal stamp on my nerd card, so...
Best of luck!
This is fixed in #5341 and #5196, should this be closed as a duplicate?
Closing as duplicate as suggested.