致命错误:registerContainerConfiguration 的声明必须与 Kernel::registerContainerConfiguration 的声明兼容

Posted

技术标签:

【中文标题】致命错误:registerContainerConfiguration 的声明必须与 Kernel::registerContainerConfiguration 的声明兼容【英文标题】:Fatal error: Declaration of registerContainerConfiguration must be compatible with that of Kernel::registerContainerConfiguration 【发布时间】:2011-04-04 22:03:24 【问题描述】:

有人知道为什么会这样吗?

据我所知,子类方法的声明方式与父类方法相同。

谢谢!

这是我的内核代码:

<?php

require_once __DIR__.'/../src/autoload.php';

use Symfony\Framework\Kernel;
use Symfony\Components\DependencyInjection\Loader\YamlFileLoader as ContainerLoader;
use Symfony\Components\Routing\Loader\YamlFileLoader as RoutingLoader;

use Symfony\Framework\KernelBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\ZendBundle\ZendBundle;
use Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle;
use Symfony\Bundle\DoctrineBundle\DoctrineBundle;
use Symfony\Bundle\DoctrineMigrationsBundle\DoctrineMigrationsBundle;
use Symfony\Bundle\DoctrineMongoDBBundle\DoctrineMongoDBBundle;
use Symfony\Bundle\PropelBundle\PropelBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Application\UfaraBundle\UfaraBundle;



class UfaraKernel extends Kernel 
    public function registerRootDir() 
        return __DIR__;
    

    public function registerBundles() 
        $bundles = array(
                new KernelBundle(),
                new FrameworkBundle(),
                new ZendBundle(),
                new SwiftmailerBundle(),
                new DoctrineBundle(),
                //new DoctrineMigrationsBundle(),
                //new DoctrineMongoDBBundle(),
                //new PropelBundle(),
                //new TwigBundle(),
                new UfaraBundle(),
        );

        if ($this->isDebug()) 
        

        return $bundles;
    

    public function registerBundleDirs() 
        $bundles = array(
                'Application'        => __DIR__.'/../src/Application',
                'Bundle'             => __DIR__.'/../src/Bundle',
                'Symfony\\Framework' => __DIR__.'/../src/vendor/symfony/src/Symfony/Framework',
                'Symfony\\Bundle'    => __DIR__.'/../src/vendor/symfony/src/Symfony/Bundle',
        );

        return $bundles;
    

    public function registerContainerConfiguration(LoaderInterface $loader) 
        return $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
    

    public function registerRoutes() 
        $loader = new RoutingLoader($this->getBundleDirs());

        return $loader->load(__DIR__.'/config/routing.yml');
    

这里是父类代码:

<?php

namespace Symfony\Framework;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Resource\FileResource;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Loader\DelegatingLoader;
use Symfony\Component\DependencyInjection\Loader\LoaderResolver;
use Symfony\Component\DependencyInjection\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Framework\ClassCollectionLoader;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * The Kernel is the heart of the Symfony system. It manages an environment
 * that can host bundles.
 *
 * @author     Fabien Potencier <fabien.potencier@symfony-project.org>
 */
abstract class Kernel implements HttpKernelInterface, \Serializable

    protected $bundles;
    protected $bundleDirs;
    protected $container;
    protected $rootDir;
    protected $environment;
    protected $debug;
    protected $booted;
    protected $name;
    protected $startTime;
    protected $request;

    const VERSION = '2.0.0-DEV';

    /**
     * Constructor.
     *
     * @param string  $environment The environment
     * @param Boolean $debug       Whether to enable debugging or not
     */
    public function __construct($environment, $debug)
    
        $this->environment = $environment;
        $this->debug = (Boolean) $debug;
        $this->booted = false;
        $this->rootDir = realpath($this->registerRootDir());
        $this->name = basename($this->rootDir);

        if ($this->debug) 
            ini_set('display_errors', 1);
            error_reporting(-1);

            $this->startTime = microtime(true);
         else 
            ini_set('display_errors', 0);
        
    

    public function __clone()
    
        if ($this->debug) 
            $this->startTime = microtime(true);
        

        $this->booted = false;
        $this->container = null;
        $this->request = null;
    

    abstract public function registerRootDir();

    abstract public function registerBundles();

    abstract public function registerBundleDirs();

    abstract public function registerContainerConfiguration(LoaderInterface $loader);

    /**
     * Checks whether the current kernel has been booted or not.
     *
     * @return boolean $booted
     */
    public function isBooted()
    
        return $this->booted;
    

    /**
     * Boots the current kernel.
     *
     * This method boots the bundles, which MUST set
     * the DI container.
     *
     * @throws \LogicException When the Kernel is already booted
     */
    public function boot()
    
        if (true === $this->booted) 
            throw new \LogicException('The kernel is already booted.');
        

        if (!$this->isDebug()) 
            require_once __DIR__.'/bootstrap.php';
        

        $this->bundles = $this->registerBundles();
        $this->bundleDirs = $this->registerBundleDirs();
        $this->container = $this->initializeContainer();

        // load core classes
        ClassCollectionLoader::load(
            $this->container->getParameter('kernel.compiled_classes'),
            $this->container->getParameter('kernel.cache_dir'),
            'classes',
            $this->container->getParameter('kernel.debug'),
            true
        );

        foreach ($this->bundles as $bundle) 
            $bundle->setContainer($this->container);
            $bundle->boot();
        

        $this->booted = true;
    

    /**
     * Shutdowns the kernel.
     *
     * This method is mainly useful when doing functional testing.
     */
    public function shutdown()
    
        $this->booted = false;

        foreach ($this->bundles as $bundle) 
            $bundle->shutdown();
            $bundle->setContainer(null);
        

        $this->container = null;
    

    /**
     * Reboots the kernel.
     *
     * This method is mainly useful when doing functional testing.
     *
     * It is a shortcut for the call to shutdown() and boot().
     */
    public function reboot()
    
        $this->shutdown();
        $this->boot();
    

    /**
     * Gets the Request instance associated with the master request.
     *
     * @return Request A Request instance
     */
    public function getRequest()
    
        return $this->request;
    

    /**
     * Handles a request to convert it to a response by calling the HttpKernel service.
     *
     * @param  Request $request A Request instance
     * @param  integer $type    The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
     * @param  Boolean $raw     Whether to catch exceptions or not
     *
     * @return Response $response A Response instance
     */
    public function handle(Request $request = null, $type = HttpKernelInterface::MASTER_REQUEST, $raw = false)
    
        if (false === $this->booted) 
            $this->boot();
        

        if (null === $request) 
            $request = $this->container->get('request');
         else 
            $this->container->set('request', $request);
        

        if (HttpKernelInterface::MASTER_REQUEST === $type) 
            $this->request = $request;
        

        $response = $this->container->getHttpKernelService()->handle($request, $type, $raw);

        $this->container->set('request', $this->request);

        return $response;
    

    /**
     * Gets the directories where bundles can be stored.
     *
     * @return array An array of directories where bundles can be stored
     */
    public function getBundleDirs()
    
        return $this->bundleDirs;
    

    /**
     * Gets the registered bundle names.
     *
     * @return array An array of registered bundle names
     */
    public function getBundles()
    
        return $this->bundles;
    

    /**
     * Checks if a given class name belongs to an active bundle.
     *
     * @param string $class A class name
     *
     * @return Boolean true if the class belongs to an active bundle, false otherwise
     */
    public function isClassInActiveBundle($class)
    
        foreach ($this->bundles as $bundle) 
            $bundleClass = get_class($bundle);
            if (0 === strpos($class, substr($bundleClass, 0, strrpos($bundleClass, '\\')))) 
                return true;
            
        

        return false;
    

    /**
     * Returns the Bundle name for a given class.
     *
     * @param string $class A class name
     *
     * @return string The Bundle name or null if the class does not belongs to a bundle
     */
    public function getBundleForClass($class)
    
        $namespace = substr($class, 0, strrpos($class, '\\'));
        foreach (array_keys($this->getBundleDirs()) as $prefix) 
            if (0 === $pos = strpos($namespace, $prefix)) 
                return substr($namespace, strlen($prefix) + 1, strpos($class, 'Bundle\\') + 7);
            
        
    

    public function getName()
    
        return $this->name;
    

    public function getSafeName()
    
        return preg_replace('/[^a-zA-Z0-9_]+/', '', $this->name);
    

    public function getEnvironment()
    
        return $this->environment;
    

    public function isDebug()
    
        return $this->debug;
    

    public function getRootDir()
    
        return $this->rootDir;
    

    public function getContainer()
    
        return $this->container;
    

    public function getStartTime()
    
        return $this->debug ? $this->startTime : -INF;
    

    public function getCacheDir()
    
        return $this->rootDir.'/cache/'.$this->environment;
    

    public function getLogDir()
    
        return $this->rootDir.'/logs';
    

    protected function initializeContainer()
    
        $class = $this->getSafeName().ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
        $location = $this->getCacheDir().'/'.$class;
        $reload = $this->debug ? $this->needsReload($class, $location) : false;

        if ($reload || !file_exists($location.'.php')) 
            $this->buildContainer($class, $location.'.php');
        

        require_once $location.'.php';

        $container = new $class();
        $container->set('kernel', $this);

        return $container;
    

    public function getKernelParameters()
    
        $bundles = array();
        foreach ($this->bundles as $bundle) 
            $bundles[] = get_class($bundle);
        

        return array_merge(
            array(
                'kernel.root_dir'         => $this->rootDir,
                'kernel.environment'      => $this->environment,
                'kernel.debug'            => $this->debug,
                'kernel.name'             => $this->name,
                'kernel.cache_dir'        => $this->getCacheDir(),
                'kernel.logs_dir'         => $this->getLogDir(),
                'kernel.bundle_dirs'      => $this->bundleDirs,
                'kernel.bundles'          => $bundles,
                'kernel.charset'          => 'UTF-8',
                'kernel.compiled_classes' => array(),
            ),
            $this->getEnvParameters()
        );
    

    protected function getEnvParameters()
    
        $parameters = array();
        foreach ($_SERVER as $key => $value) 
            if ('SYMFONY__' === substr($key, 0, 9)) 
                $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
            
        

        return $parameters;
    

    protected function needsReload($class, $location)
    
        if (!file_exists($location.'.meta') || !file_exists($location.'.php')) 
            return true;
        

        $meta = unserialize(file_get_contents($location.'.meta'));
        $time = filemtime($location.'.php');
        foreach ($meta as $resource) 
            if (!$resource->isUptodate($time)) 
                return true;
            
        

        return false;
    

    protected function buildContainer($class, $file)
    
        $parameterBag = new ParameterBag($this->getKernelParameters());

        $container = new ContainerBuilder($parameterBag);
        foreach ($this->bundles as $bundle) 
            $bundle->registerExtensions($container);

            if ($this->debug) 
                $container->addObjectResource($bundle);
            
        

        if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) 
            $container->merge($cont);
        
        $container->freeze();

        foreach (array('cache', 'logs') as $name) 
            $dir = $container->getParameter(sprintf('kernel.%s_dir', $name));
            if (!is_dir($dir)) 
                if (false === @mkdir($dir, 0777, true)) 
                    die(sprintf('Unable to create the %s directory (%s)', $name, dirname($dir)));
                
             elseif (!is_writable($dir)) 
                die(sprintf('Unable to write in the %s directory (%s)', $name, $dir));
            
        

        // cache the container
        $dumper = new PhpDumper($container);
        $content = $dumper->dump(array('class' => $class));
        if (!$this->debug) 
            $content = self::stripComments($content);
        
        $this->writeCacheFile($file, $content);

        if ($this->debug) 
            $container->addObjectResource($this);

            // save the resources
            $this->writeCacheFile($this->getCacheDir().'/'.$class.'.meta', serialize($container->getResources()));
        
    

    protected function getContainerLoader(ContainerInterface $container)
    
        $resolver = new LoaderResolver(array(
            new XmlFileLoader($container, $this->getBundleDirs()),
            new YamlFileLoader($container, $this->getBundleDirs()),
            new IniFileLoader($container, $this->getBundleDirs()),
            new PhpFileLoader($container, $this->getBundleDirs()),
            new ClosureLoader($container),
        ));

        return new DelegatingLoader($resolver);
    

    /**
     * Removes comments from a PHP source string.
     *
     * We don't use the PHP php_strip_whitespace() function
     * as we want the content to be readable and well-formatted.
     *
     * @param string $source A PHP string
     *
     * @return string The PHP string with the comments removed
     */
    static public function stripComments($source)
    
        if (!function_exists('token_get_all')) 
            return $source;
        

        $output = '';
        foreach (token_get_all($source) as $token) 
            if (is_string($token)) 
                $output .= $token;
             elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) 
                $output .= $token[1];
            
        

        // replace multiple new lines with a single newline
        $output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output);

        // reformat  "a la python"
        $output = preg_replace(array('/\n\s*\/', '/\n\s*\/'), array(' ', ' '), $output);

        return $output;
    

    protected function writeCacheFile($file, $content)
    
        $tmpFile = tempnam(dirname($file), basename($file));
        if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) 
            chmod($file, 0644);

            return;
        

        throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
    

    public function serialize()
    
        return serialize(array($this->environment, $this->debug));
    

    public function unserialize($data)
    
        list($environment, $debug) = unserialize($data);

        $this->__construct($environment, $debug);
    

【问题讨论】:

【参考方案1】:

您的答案在于导入的命名空间。在Kernel的文件中,有这个use子句:

use Symfony\Component\DependencyInjection\Loader\LoaderInterface;

这样就可以将LoaderInterface 与完全命名空间的类Symfony\Component\DependencyInjection\Loader\LoaderInterface 联系起来。

基本上是做签名:

public function registerContainerConfiguration(Symfony\Component\DependencyInjection\Loader\LoaderInterface $loader);

在您的课程中,您不会导入该命名空间。因此 PHP 默认假定该类在您的命名空间中(因为导入的命名空间都没有该接口名称)。

所以你的签名是(因为你没有声明命名空间):

public function registerContainerConfiguration(\LoaderInterface $loader);

所以要让它们匹配,只需将use 行添加到文件顶部即可:

use Symfony\Component\DependencyInjection\Loader\LoaderInterface;

【讨论】:

谢谢!这行得通,你明白了。我正在用 symfony 2 训练自己到 5.3 和新的可怕形状的命名空间,乍一看,我根本不喜欢它们。 嗯,这有点不直观。所写的签名是相同的(因此是您的问题)。您需要意识到签名是依赖于命名空间的上下文。这就是为什么某些约定要求任何类型提示和类扩展的完全限定名称空间(以避免这种类型的混淆)。更不用说这些命名空间是巨大的......对于更明智的(恕我直言)使用,请查看Lithium...

以上是关于致命错误:registerContainerConfiguration 的声明必须与 Kernel::registerContainerConfiguration 的声明兼容的主要内容,如果未能解决你的问题,请参考以下文章

C# 中连接SQLServer 出现内部致命错误

使命召唤14致命错误怎么解决?

打开AutoCAD 文件就会弹出致命错误

重命名应用程序包生成致命错误“执行重构时发生致命错误”

天正总出现致命错误?是怎么回事儿?

游戏更新就出现发生致命错误Win32Error怎么回事