Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drush cr causes "cannot redeclare" if function is defined in settings.php of Drupal #6214

Open
dandjo opened this issue Jan 21, 2025 · 6 comments

Comments

@dandjo
Copy link

dandjo commented Jan 21, 2025

Describe the bug

When defining a custom function in settings.php drush cr causes the following error:

Fatal error: Cannot redeclare my_custom_func() (previously declared in /var/drupal/settings.php:9) in /var/drupal/settings.php on line 9

To Reproduce

Do something like follows in the settings.php in a Drupal project.

function my_custom_func() {
  echo 'Hello world!';
}

Expected behavior

A cache rebuild is triggered.

Actual behavior

Script breaks and exits with code 1.

drush cr --debug
 [preflight] Config paths: /var/www/vendor/drush/drush/drush.yml
 [preflight] Alias paths: /var/www/html/drush/sites,/var/www/drush/sites
 [preflight] Commandfile search paths: /var/www/vendor/drush/drush/src
 [debug] Bootstrap further to find cr [0.95 sec, 4.86 MB]
 [debug] Trying to bootstrap as far as we can [0.95 sec, 4.86 MB]
 [info] Drush bootstrap phase: bootstrapDrupalRoot() [0.95 sec, 4.86 MB]
 [info] Change working directory to /var/www/html [0.95 sec, 4.86 MB]
 [info] Initialized Drupal 11.1.1 root directory at /var/www/html [0.95 sec, 4.86 MB]
 [info] Drush bootstrap phase: bootstrapDrupalSite() [0.96 sec, 5.13 MB]
 [debug] Could not find a Drush config file at sites/default/drush.yml. [0.96 sec, 5.26 MB]
 [info] Initialized Drupal site tm.localhost at sites/default [0.96 sec, 5.26 MB]
 [info] Drush bootstrap phase: bootstrapDrupalConfiguration() [0.96 sec, 5.26 MB]
 [info] Drush bootstrap phase: bootstrapDrupalDatabase() [0.98 sec, 5.66 MB]
 [info] Successfully connected to the Drupal database. [0.98 sec, 5.67 MB]
 [info] Drush bootstrap phase: bootstrapDrupalFull() [0.98 sec, 5.67 MB]
 [debug] Start bootstrap of the Drupal Kernel. [0.98 sec, 5.67 MB]
 [debug] Finished bootstrap of the Drupal Kernel. [1.04 sec, 11.7 MB]
 [debug] Loading drupal module drush commands & etc. [1.04 sec, 11.71 MB]
 [debug] Found drush.services.yml for token Drush commands [1.04 sec, 11.84 MB]
 [debug] Found drush.services.yml for trash Drush commands [1.04 sec, 11.84 MB]
 [debug] Add a commandfile class: Drupal\config_split\Commands\ConfigSplitCommands [1.08 sec, 14.51 MB]
 [debug] Add a commandfile class: Drupal\easy_email\Drush\Commands\PurgeCommands [1.08 sec, 14.53 MB]
 [debug] Add a commandfile class: Drupal\scheduler\Commands\SchedulerCommands [1.08 sec, 14.54 MB]
 [debug] Add a commandfile class: Drupal\token\Drush\Commands\TokenCommands [1.08 sec, 14.54 MB]
 [debug] Add a commandfile class: Drupal\trash\Commands\TrashCommands [1.08 sec, 14.54 MB]
 [debug] Add a commandfile class: Drupal\pathauto\Commands\PathautoCommands [1.08 sec, 14.55 MB]
 [debug] Done with bootstrap max in Application::bootstrapAndFind(): trying to find cr again. [1.14 sec, 18.95 MB]
 [info] Starting bootstrap to site [1.15 sec, 18.96 MB]
 [info] Drush bootstrap phase 2 [1.15 sec, 18.96 MB]
 [info] Try to validate bootstrap phase 2 [1.15 sec, 18.96 MB]
 [info] Try to validate bootstrap phase 2 [1.15 sec, 18.96 MB]
 [info] Try to validate bootstrap phase 2 [1.15 sec, 18.96 MB]

Fatal error: Cannot redeclare my_custom_func() (previously declared in /var/drupal/settings.php:9) in /var/drupal/settings.php on line 9
 [warning] Drush command terminated abnormally. [1.16 sec, 19.6 MB]

System Configuration

Q A
Drush version? 13.3.3
Drupal version? 11.1.1
PHP version 8.3
OS? Linux
@greg-1-anderson
Copy link
Member

Haven't investigated, but as a workaround, you could wrap your function in if(!function_exists())

@dandjo
Copy link
Author

dandjo commented Jan 21, 2025

@greg-1-anderson Tried this. The settings.php gets included twice somewhere. When I call debug_print_backtrace() at the beginning of my settings.php I get this:

#0 /var/www/html/core/lib/Drupal/Core/Site/Settings.php(146): require()
#1 /var/www/html/core/lib/Drupal/Core/DrupalKernel.php(1058): Drupal\Core\Site\Settings::initialize('/var/www/html', 'sites/default', Object(Composer\Autoload\ClassLoader))
#2 /var/www/html/core/lib/Drupal/Core/DrupalKernel.php(291): Drupal\Core\DrupalKernel->initializeSettings(Object(Symfony\Component\HttpFoundation\Request))
#3 /var/www/vendor/drush/drush/src/Boot/DrupalBoot8.php(195): Drupal\Core\DrupalKernel::createFromRequest(Object(Symfony\Component\HttpFoundation\Request), Object(Composer\Autoload\ClassLoader), 'prod', true, '/var/www/html')
#4 /var/www/vendor/drush/drush/src/Boot/BootstrapManager.php(211): Drush\Boot\DrupalBoot8->bootstrapDrupalConfiguration(Object(Drush\Boot\BootstrapManager), NULL)
#5 /var/www/vendor/drush/drush/src/Boot/BootstrapManager.php(397): Drush\Boot\BootstrapManager->doBootstrap(3, 6, NULL)
#6 /var/www/vendor/drush/drush/src/Application.php(219): Drush\Boot\BootstrapManager->bootstrapMax()
#7 /var/www/vendor/drush/drush/src/Application.php(185): Drush\Application->bootstrapAndFind('cr')
#8 /var/www/vendor/symfony/console/Application.php(284): Drush\Application->find('cr')
#9 /var/www/vendor/symfony/console/Application.php(193): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /var/www/vendor/drush/drush/src/Runtime/Runtime.php(110): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /var/www/vendor/drush/drush/src/Runtime/Runtime.php(40): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 /var/www/vendor/drush/drush/drush.php(140): Drush\Runtime\Runtime->run(Array)
#13 /var/www/vendor/bin/drush.php(119): include('/var/www/vendor...')


#0 /var/www/html/core/lib/Drupal/Core/Site/Settings.php(146): require()
#1 /var/www/vendor/drush/drush/src/Commands/core/CacheRebuildCommands.php(54): Drupal\Core\Site\Settings::initialize('/var/www/html', 'sites/default', Object(Composer\Autoload\ClassLoader))
#2 [internal function]: Drush\Commands\core\CacheRebuildCommands->rebuild(Array)
#3 /var/www/vendor/consolidation/annotated-command/src/CommandProcessor.php(276): call_user_func_array(Array, Array)
#4 /var/www/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
#5 /var/www/vendor/consolidation/annotated-command/src/CommandProcessor.php(175): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#6 /var/www/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(387): Consolidation\AnnotatedCommand\CommandProcessor->process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#7 /var/www/vendor/symfony/console/Command/Command.php(279): Consolidation\AnnotatedCommand\AnnotatedCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 /var/www/vendor/symfony/console/Application.php(1094): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /var/www/vendor/symfony/console/Application.php(342): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /var/www/vendor/symfony/console/Application.php(193): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /var/www/vendor/drush/drush/src/Runtime/Runtime.php(110): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 /var/www/vendor/drush/drush/src/Runtime/Runtime.php(40): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 /var/www/vendor/drush/drush/drush.php(140): Drush\Runtime\Runtime->run(Array)
#14 /var/www/vendor/bin/drush.php(119): include('/var/www/vendor...')

@dandjo
Copy link
Author

dandjo commented Jan 21, 2025

Also, when wrapping my function in if (!function_exists() the application exits with an error telling me some settings are not set which I am applying with my custom function.

To be more specific: we are using a custom function for retrieving environment variables and passing them to to the $settings array. For instance the config_sync_directory. When using the wrapper above I get:

  The config sync directory is not defined in $settings["config_sync_directory"]  

@dandjo
Copy link
Author

dandjo commented Jan 21, 2025

Here's what we do in detail. The *.inc Files in the subdirectory use the tm_getenv() function.

<?php

/**
 * @param string $name
 * @param mixed|null $default
 *
 * @return array|false|string
 */
function tm_getenv(string $name, mixed $default = NULL) {
  $value = getenv($name);
  if (is_string($value)) {
    $value = trim($value, "\"\0\t\n\x0B\r ");
  }
  return $value ?: $default;
}

/**
 * MODULE OR PROJECT SETTINGS
 * This is for all module or project specific config/settings.
 */
foreach (glob($app_root . '/' . $site_path . '/settings/*.inc') as $filename) {
  require_once $filename;
}

@dandjo
Copy link
Author

dandjo commented Jan 21, 2025

What is perhaps also important: This problem does not exist with Drush 12.5 and Drupal 10.4. We use the exactly same mechanism there.

@dandjo
Copy link
Author

dandjo commented Jan 22, 2025

Tried some scenarios for a workaround. The Problem with

  The config sync directory is not defined in $settings["config_sync_directory"]  

is caused by the Settings get initialized twice as mentioned in comment 2605404404 and require_once will only include the *.inc files in the first run. If I'm using require instead of require_once our stack is functional again.

So the main issue here is that Drupal\Core\Site\Settings::initialize is called twice when doing a drush cr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants