我必须使用我正在开发API(基于PHP)的环境:
- 本地开发:Mac OS Yosemite-运行PHP 5.5.20
- 生产服务器:Ubuntu服务器-运行PHP 5.5.9
我的代码使用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
错误,表明我的自动加载没有正确运行。
有什么想法吗?原因是什么?
更新:当我试图加载外部libs(如AWS)时,它确实有效,所以问题在于如何加载我的文件夹。
更新:这是我试图从index.php:加载的类
<?php
//require Pico Core autoload
require 'core/vendor/autoload.php';
//require Pico Api autoload
require 'vendor/autoload.php';
use PicoCoreRestApiInitializer;
use PicoCoreConfigurationError;
use PicoApiManagersApiManager;
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 'PicoCoreRestApiInitializer' not found
的错误
结构为:
api
|
core
|
PicoCore
|
folders..
rest
|
ApiInitializer.php
folders...
vender
PicoApi (folder)
vendor (foldeR)
index.php
这是错误的自动加载定义。
你想使用类
PicoCoreRestApiInitializer
你有这些文件:
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
你已经配置了这个自动加载:
"自动加载":{"psr-0":{"PicoCore\Rest\":"PicoCore/Rest"}}
这是不匹配的。当您使用类PicoCoreRestApiInitializer
时,composer将尝试查找具有该类前缀的条目。它将成功地检测到,在目录(相对于composer.json
的位置)PicoCore/rest
中,可以通过PSR-0规则找到前缀为PicoCodeRest
的类。
第一件奇怪的事情:这里有一个名为"core"的额外目录,并且您似乎包括两个自动加载器。不要这么做,Composer只使用一个自动加载器效果最好。
第二件事:如果我忽略"核心"目录一段时间,PSR-0规则规定类名将被转换为路径,然后在给定的前缀路径中进行搜索。
作为路径的PicoCoreRestApiInitializer
是PicoCore/Rest/ApiInitializer.php
(注意"Rest"中的大写"R"),要找到的路径是PicoCore/rest/PicoCore/Rest/ApiInitializer.php
。
你没有这个文件。这就是为什么Composer找不到并加载它的原因。即使不计算这个"核心"目录级别,如果你使用两个composer.json
文件,一个在api
和api/core
,而api/core
中的一个用于查找类,也不会找到它。
建议:
- 对命名空间中的每个类使用PSR-4
- 文件系统的命名空间或类名部分不要小写
- 缩短自动加载定义。如果您将
PicoCore
以下的所有小写目录重命名为命名空间中使用的正确大写变体,则只需要一行自动加载定义,即定义PicoCore
前缀。其余部分由PSR-4(或PSR-0)完成
默认情况下,MacOS使用不区分大小写的文件系统,将其切换为区分大小写被认为是一件坏事:https://apple.stackexchange.com/questions/71357/how-to-check-if-my-hd-is-case-sensitive-or-not这就是为什么它可以在Mac上运行,但不能在Linux上运行。