【问题标题】:Composer in Codeigniter prevents MY_ controllers from loadingCodeigniter 中的 Composer 阻止加载 MY_ 控制器
【发布时间】:2014-04-17 06:21:19
【问题描述】:

在我的 Codeigniter 项目中经历了设置作曲家的痛苦之后,我把这个:

  require_once "./vendor/autoload.php";

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

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

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

以前效果很好。任何关于为什么会发生这种情况的指针都非常感谢。

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

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

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

【问题讨论】:

    标签: php codeigniter composer-php


    【解决方案1】:

    __autoload函数只能有一个,与spl_autoload_*函数互斥,就像documented in the PHP.net page一样。

    提示 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 的文档。 BasicsDetails

    请注意,我发现您自己的自动加载功能有点奇怪。您是说对于名称中不以“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_foo.php”,那将不兼容 PSR-0。

    【讨论】:

    • 非常感谢您的详细解答。但是,只有 spl_autoload_register 部分对我有用。我之前尝试过完全没有效果的“classmap”方法。由于您怀疑的原因, psr-0 方法对我不起作用。我使用的自动加载功能是从 Phil Sturgeon 的博客中复制的。为什么“类图”方法似乎对我以外的所有人都有效,这对我来说仍然是个谜。令人沮丧。
    • 你的常量EXT是如何定义的?
    • define('EXT', '.php');它位于 Codeigniter 的 index.php 文件中。
    【解决方案2】:

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

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

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

    【讨论】:

    • 这对我不起作用。我读到您必须修改 composer.json 文件以包含自动加载。我也试过了,但它根本行不通。
    【解决方案3】:

    您可能在修改 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 COMPOSER PACKAGES
     * --------------------------------------------------------------------
     *
     */
    include_once './vendor/autoload.php';
    

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

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

    最后,这很重要,在 composer 中转储自动加载。

    composer dump-autoload
    

    它现在应该可以工作了。

    【讨论】:

      猜你喜欢
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 2013-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多