diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index be9821d..e1842fc 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -217,6 +217,7 @@ public static function createFromRequest(Request $request, $class_loader, $envir // Include our bootstrap file. $core_root = dirname(dirname(dirname(__DIR__))); require_once $core_root . '/includes/bootstrap.inc'; + $class_loader_class = get_class($class_loader); $kernel = new static($environment, $class_loader, $allow_dumping); @@ -245,6 +246,18 @@ public static function createFromRequest(Request $request, $class_loader, $envir $response->prepare($request)->send(); } + // If the class loader is still the same, possibly upgrade to the APC class + // loader. + if ($class_loader_class == get_class($class_loader) + && Settings::get('class_loader_auto_detect', TRUE) + && function_exists('apc_fetch')) { + $prefix = 'drupal.' . hash('sha-256', 'drupal.' . Settings::getHashSalt()); + $apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader($prefix, $class_loader); + $class_loader->unregister(); + $apc_loader->register(); + $class_loader = $apc_loader; + } + return $kernel; } diff --git a/core/rebuild.php b/core/rebuild.php index 24474d0..78d4fce 100644 --- a/core/rebuild.php +++ b/core/rebuild.php @@ -20,7 +20,12 @@ // Change the directory to the Drupal root. chdir('..'); -$autoloader = require_once 'autoload.php'; +// APC user cache to ensure APC classloader is reset. +if (function_exists('apc_fetch')) { + apc_clear_cache('user'); +} + +$autoloader = require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/includes/utility.inc'; $request = Request::createFromGlobals(); diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index d4bb0de..152e3a9 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -383,18 +383,29 @@ /** * Class Loader. * - * By default, Composer's ClassLoader is used, which is best for development, as - * it does not break when code is moved in the file system. You can decorate the - * class loader with a cached solution for better performance, which is - * recommended for production sites. - * - * To do so, you may decorate and replace the local $class_loader variable. - * - * For example, to use Symfony's APC class loader, uncomment the code below. + * If the APCu extension is detected, the Symfony APC class loader is used for + * performance reasons. Detection can be prevented by setting + * class_loader_auto_detect to false, as in the example below. + */ +# $settings['class_loader_auto_detect'] = FALSE; + +/* + * If the APCu extension is not detected, either because APCu is missing or + * because auto-detection has been disabled, auto-loading falls back to + * Composer's ClassLoader, which is good for development as it does not break + * when code is moved in the file system. You can also decorate the base class + * loader with another cached solution than the Symfony APCu class loader, as + * all production sites should have a cached class loader of some sort enabled. + * + * To do so, you may decorate and replace the local $class_loader variable. For + * example, to use Symfony's APC class loader without automatic detection, + * uncomment the code below. */ /* if ($settings['hash_salt']) { - $apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader('drupal.' . $settings['hash_salt'], $class_loader); + $prefix = 'drupal.' . hash('sha-256', 'drupal' . $settings['hash_salt']); + $apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader($prefix, $class_loader); + unset($prefix); $class_loader->unregister(); $apc_loader->register(); $class_loader = $apc_loader;