PHP Autoloader不能在Ubuntu生产服务器上运行

时间:2015-06-21 07:30:31

标签: php ubuntu composer-php

我需要开发我的API(基于PHP)的环境:

  1. 本地开发:Mac OS Yosemite - 运行PHP 5.5.20
  2. 生产服务器:Ubuntu服务器 - 运行PHP 5.5.9
  3. 我的代码使用composer进行自动加载,如下所示:

    {
        "require": {
            "facebook/php-sdk": "@stable",
            "everyman/neo4jphp": "dev-master",
            "predis/predis": "1.0.1",
            "aws/aws-sdk-php": "2.*"
        },
    
        "autoload": {
            "psr-0": {
                "PicoCore\\": "",
                "PicoCore\\Authentication\\" : "PicoCore/authentication",
                "PicoCore\\Aws\\" : "PicoCore/aws",
                "PicoCore\\Cache\\" : "PicoCore/cache",
                "PicoCore\\Database\\" : "PicoCore/database",
                "PicoCore\\Database\\Managers\\" : "PicoCore/database/managers",
                "PicoCore\\Facebook\\" : "PicoCore/facebook",
                "PicoCore\\Objects\\" : "PicoCore/objects",
                "PicoCore\\Rest\\" : "PicoCore/rest",
                "PicoCore\\Configuration\\" : "PicoCore/configuration",
                "PicoCore\\Configuration\\Api\\" : "PicoCore/configuration/api",
                "PicoCore\\Configuration\\PictureReceiver\\" : "PicoCore/configuration/pictureReceiver",
                "PicoCore\\Configuration\\PictureUploader\\" : "PicoCore/configuration/pictureUploader",
                "PicoCore\\Scripts\\" : "PicoCore/scripts",
                "PicoCore\\Times" : "PicoCore/times"
            }
        }
    }
    

    这是我的加载功能:

    // autoload_namespaces.php @generated by Composer
    
    $vendorDir = dirname(dirname(__FILE__));
    $baseDir = dirname($vendorDir);
    
    return array(
        'PicoCore\\Times' => array($baseDir . '/PicoCore/times'),
        'PicoCore\\Scripts\\' => array($baseDir . '/PicoCore/scripts'),
        'PicoCore\\Rest\\' => array($baseDir . '/PicoCore/rest'),
        'PicoCore\\Objects\\' => array($baseDir . '/PicoCore/objects'),
        'PicoCore\\Facebook\\' => array($baseDir . '/PicoCore/facebook'),
        'PicoCore\\Database\\Managers\\' => array($baseDir . '/PicoCore/database/managers'),
        'PicoCore\\Database\\' => array($baseDir . '/PicoCore/database'),
        'PicoCore\\Configuration\\PictureUploader\\' => array($baseDir . '/PicoCore/configuration/pictureUploader'),
        'PicoCore\\Configuration\\PictureReceiver\\' => array($baseDir . '/PicoCore/configuration/pictureReceiver'),
        'PicoCore\\Configuration\\Api\\' => array($baseDir . '/PicoCore/configuration/api'),
        'PicoCore\\Configuration\\' => array($baseDir . '/PicoCore/configuration'),
        'PicoCore\\Cache\\' => array($baseDir . '/PicoCore/cache'),
        'PicoCore\\Aws\\' => array($baseDir . '/PicoCore/aws'),
        'PicoCore\\Authentication\\' => array($baseDir . '/PicoCore/authentication'),
        'PicoCore\\' => array($baseDir . '/'),
        'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'),
        'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'),
        'Everyman\\Neo4j' => array($vendorDir . '/everyman/neo4jphp/lib'),
        'Aws' => array($vendorDir . '/aws/aws-sdk-php/src'),
    );
    

    当我在我的本地开发中运行我的代码时 - 它完美运行,所以我将它推送到我的远程存储库并将其从生产服务器中拉出来。

    当我尝试在我的生产服务器中运行我的代码时,收到Class not found错误,表明我的自动加载功能无法正常运行。

    任何想法可能是什么原因?

    更新 当我试图加载外部库(如AWS)时,它确实有效,所以问题就在于我的文件夹加载方式。

    更新 这是我试图从index.php加载的类:

    <?php
    //require Pico Core autoload
    require 'core/vendor/autoload.php';
    
    //require Pico Api autoload
    require 'vendor/autoload.php';
    
    use PicoCore\Rest\ApiInitializer;
    use PicoCore\Configuration\Error;
    use PicoApi\Managers\ApiManager;
    
    try {
        //initialize the API
        ApiInitializer::initialize();
        //initialize a new Api with the request
        $api = new ApiManager($_REQUEST['request']);
        echo utf8_encode($api->processApi());
    
    } catch (Exception $e) {
        echo json_encode(Array(Error::jsonErrorField() => $e->getMessage()));
    }
    

    这是我收到的错误Class 'PicoCore\Rest\ApiInitializer' not found

    结构是:

    api
     |
     core
       |
       PicoCore
          |
         folders..
         rest
          |
          ApiInitializer.php
         folders...
        vender
     PicoApi (folder)
     vendor (foldeR)
     index.php
    

1 个答案:

答案 0 :(得分:3)

这是您错误的自动加载定义。

您想使用班级

PicoCore\Rest\ApiInitializer

你有这些文件:

api/index.php
api/vendor/...    (with your required external dependencies)
api/composer.json (with the autoloading mentioned in your question)
api/core/PicoCore/rest/ApiInitializer.php

您已配置此自动加载功能:

&#34; autoload&#34;:{        &#34; psr-0&#34;:{            &#34; PicoCore \休息\&#34; :&#34; PicoCore / rest&#34;        }     }

这是不匹配的。当您使用类PicoCore\Rest\ApiInitializer时,composer将尝试查找具有该类前缀的条目。它将成功检测到前缀为PicoCode\Rest的类可以通过目录中的PSR-0规则找到(相对于composer.jsonPicoCore/rest的位置。

第一个奇怪的事情:还有一个名为&#34; core&#34;的目录。在这里,你似乎包括两个自动加载器。不要这样做,Composer最适合只有一个自动加载器。

第二件事:如果我忽略了那个&#34;核心&#34;一个目录,PSR-0规则声明类名将被转换为路径 - 然后在为前缀给出的路径中搜索。

PicoCore\Rest\ApiInitializer路径为PicoCore/Rest/ApiInitializer.php(注意大写&#34; R&#34;&#34;休息&#34;),找到的路径为{ {1}}。

您没有此文件。这就是为什么Composer无法找到并加载它。这甚至不计算这个&#34;核心&#34;目录级别,如果您使用了两个PicoCore/rest/PicoCore/Rest/ApiInitializer.php文件,一个在composer.json中,另一个在api中,并且api/core中的一个用于查找类。

建议:

  1. 对名称空间内的每个类使用PSR-4。
  2. 不要使用文件系统的小写命名空间或类名称部分。
  3. 缩短自动加载定义。如果您将api/core下面的所有小写目录重命名为命名空间中正在使用的正确大写变体,则只需要一行自动加载定义,定义PicoCore前缀。其余的由PSR-4(或PSR-0)完成。
  4. 默认情况下,MacOS使用不区分大小写的文件系统,将其切换为区分大小写是一件坏事:https://apple.stackexchange.com/questions/71357/how-to-check-if-my-hd-is-case-sensitive-or-not这就是为什么它在Mac上工作,而不是Linux。< / p>