Codeigniter中的Composer阻止MY_控制器加载


Composer in Codeigniter prevents MY_ controllers from loading

在经历了在我的Codeigniter项目中设置composer的痛苦之后,我放了这个:

  require_once "./vendor/autoload.php";

到我的index.php文件中。在将所有内容上传到服务器后,我收到错误消息,即在main.php控制器中找不到MY_Mainconroller(位于application/core中)。出于某种奇怪的原因,作曲家自动加载破坏了我的CI.

我在config.php中使用这种方法来自动加载我的客户控制器扩展:

 function __autoload($class)
 {
    if(strpos($class, 'CI_') !== 0)
    {
       @include_once( APPPATH . 'core/'. $class . EXT );
    }
 } 

它以前运行得非常好。任何关于为什么会发生这种情况的线索都将不胜感激。

我修改了composer.json文件并添加了:

"autoload": {
    "classmap": ["application/core"]
}

这是CI论坛上提出的,但也没有解决问题。。。。

您只能有一个__autoload函数,它与使用spl_autoload_*函数是互斥的,就像PHP.net页面中记录的那样。

提示spl_autoload_register()为自动加载类提供了一种更灵活的替代方法。因此,不鼓励使用__autoload(),将来可能会弃用或删除它。

发件人http://php.net/spl_autoload_register

如果您的代码有一个现有的__autoload()函数,那么该函数必须在__autoload堆栈上显式注册。这是因为spl_autoload_register()将用spl_autoload()或spl_autoload_call()有效地替换__autoload()函数的引擎缓存。

现在解决方案非常简单:使用Composer的自动加载功能。您所要做的就是在现有的composer.json文件中添加一个新的密钥"autoload"。如果您的代码遵循PSR-0标准,这可能会起作用:

"autoload": {
    "psr-0": {
        "MY''" : "application/core/"
    }
}

这种变体在开发时工作量最小,因为可以立即找到新的类。

否则,您可以使用类映射:

"autoload": {
    "classmap": ["application/core/"]
}

这将迫使你在每次添加新类或重命名它时重新创建自动加载器,因为旧的类映射不知道在哪里可以找到它

看看Composer的文档。基础、细节

注意,我发现你自己的自动加载功能有点奇怪。您的意思是,对于名称中不以"CI_"开头的每个类,都包含一个文件。名称中其他地方有"CI_"的类呢?您正在大量尝试自动加载所有以"CI_"开头的内容,无论它是否可以在您的目录中找到。正确的做法是只加载你知道自己负责的类,比如:

if(strpos($class, 'MY_') === 0) // starts with "MY_"
{
   require_once( APPPATH . 'core/'. $class . EXT );
}

请注意,PSR-0标准定义在不使用名称空间时,类名中的每个下划线都转换为目录分隔符。因此,如果您的类名为"MY_foo",则相对路径将为"MY/foo.php",即"application/core/MY/foo.php"。如果您当前拥有"application/core/MY_fo.php",则与PSR-0不兼容。

不确定你发生了什么,但我第一次尝试时似乎记得类似的事情。我现在总是把:

$vendor_path = './vendor/autoload.php';
if (file_exists($vendor_path))
{
   require $vendor_path;
} 

在我的index.php文件的顶部,在其他任何东西之前,它总是平稳地运行

修改composer.json.后,您可能会忘记运行"composer dump autoload"

以下是详细的步骤。请注意,我使用的是Phil Sturgeon博客中完全相同的自动加载脚本,就像最初的问题一样,当我添加Composer部分时,它就坏了。

首先,将其从index.php(Phil Sturgeon位)中删除:

 function __autoload($class)
 {
    if(strpos($class, 'CI_') !== 0)
    {
       @include_once( APPPATH . 'core/'. $class . EXT );
    }
 } 

然后,将以下内容添加到index.php中,就在"LOAD the BOOTSTRAP FILE"位之前。这是作曲家的自动加载。

/*
 * --------------------------------------------------------------------
 * LOAD COMPOSER PACKAGES
 * --------------------------------------------------------------------
 *
 */
include_once './vendor/autoload.php';

将其添加到composer.json中。现在composer将负责加载application/core文件夹中的文件。

"autoload": {
    "classmap": ["application/core/"]
}

最后,也是非常重要的一点,在composer中转储自动加载。

composer dump-autoload

现在应该可以了。