Composer 和 Linux 生产服务器 - 自动加载不起作用

Posted

技术标签:

【中文标题】Composer 和 Linux 生产服务器 - 自动加载不起作用【英文标题】:Composer & Linux production server - autoload not working 【发布时间】:2017-01-05 16:31:33 【问题描述】:

我已经尝试搜索这个问题并看到了几个答案,但没有运气......

我已经用 Slim Framework v3 安装了 composer。

我在 composer.json 文件中使用 PSR-4 自动加载我的文件,如下所示:

"autoload": 
 "psr-4": 
   "App\\": "App"
 

这是我的文件夹结构:

我使用 Apache 2.4 在 localhost Mac OS X El-Capitan 上运行它,一切都像魔术一样工作。 但是当我将它上传到我的生产 Linux 服务器(也使用 Apache 2.4)时,自动加载似乎非常混乱,并且我收到了如下错误:

警告:包含(/home/friendsapp/public_html/vendor/composer/../../app/Middleware/AuthMiddleware.php):无法打开流:/home/friendsapp/public_html 中没有这样的文件或目录/vendor/composer/ClassLoader.php 在第 412 行

警告:include():无法打开“/home/friendsapp/public_html/vendor/composer/../../app/Middleware/AuthMiddleware.php”以包含(include_path='.:/usr/lib/ php:/usr/local/lib/php') 在 /home/friendsapp/public_html/vendor/composer/ClassLoader.php 第 412 行

致命错误:在第 5 行的 /home/friendsapp/public_html/public/index.php 中找不到类 'App\Middleware\AuthMiddleware'

我已经完全根据我的文件夹结构为我的类命名。

<?php

namespace App\Middleware;

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

use \App\Middleware\Middleware;

use \App\Share\ErrorCode;
use \App\Models\ResultMessage;

use \App\Mappers\AccessTokenMapper;

class AuthMiddleware extends Middleware 

任何帮助将不胜感激! :)

【问题讨论】:

您是否在服务器上运行了composer install composer dump-autoload 难道我不应该在服务器上这样做吗? (至少这是我通过阅读一些关于这个问题的 cmets 所理解的) 我看不到它在您的配置中发生的位置,但您的目录命名中的大写/小写似乎有所不同。 OSX 解析文件时不区分大小写,而 linux 区分大小写。 【参考方案1】:

查看错误/app/Middleware/AuthMiddleware.php中的路径

问题似乎是由在您的生产环境中将App\\ 指向/app 的命名空间冲突引起的,而不是指向/App 的PSR-4 声明。

为避免冲突并映射指定目录的所有命名空间,您可以使用composer.json 中的自动加载classmap 或配置optimize-autoloader(可选)选项来定义所有文件和对象的物理路径在作曲家加载的指定目录中。此外,使用 PSR-4 声明,将尝试从 App 命名空间路径声明中加载类映射路径中未找到的任何文件。例如,当使用 exclude-from-classmap 选项时。

"config": 
    "optimize-autoloader": true
,
"autoload": 
    "psr-4": 
        "App\\": "App/"
    ,
    "classmap": [
        "App/",
    ],

在您的composer.json 中进行更改后,请务必在您的开发环境中运行php composer.phar update --lock

然后将composer.lockcomposer.json 文件上传到生产环境后,从生产环境运行php composer.phar install --no-dev -ophp composer.phar dump-autoload --no-dev -o

-o 选项将强制 optimize-autoloader 类映射运行,--no-dev 将阻止安装开发包 (require-dev)。生产环境推荐使用optimize-autoloader


作为一般做法,每当您将开发更改部署到生产环境时,您都需要运行php composer.phar install --no-dev -o 请参阅How to deploy correctly when using Composer's develop / production switch?。这样,使用 php composer.phar update 从您的开发环境应用的更改将正确安装在您的生产环境中。

【讨论】:

这实际上是..一个很好的答案,解决了我的问题!我通过 SSH 登录并运行“php composer.phar dump-autoload -o”,一切似乎都运行良好。也感谢您的一般做法,我一定会采用它们。 请记住,composer.phar 将自动以--dev 模式运行,所以除非您在生产环境中需要require-dev 依赖项(例如phpunit、phpspec、behat 和codesniffer等),您将受益于添加 --no-dev 开关以避免安装这些依赖项(否则可能会使您自己面临开发库的潜在漏洞)。 非常感谢 --no-dev -o 救了我! 我将classmap 添加到composer.json 并运行dump-autoload -o,它就成功了。【参考方案2】:

对于我的生产服务器,以下工作:

composer install --no-dev -o

然后重启php

在 serverpilot 上:

rm -rf vendor/*
composer5.6-sp install --no-dev -o
sudo service php5.6-fpm-sp restart

【讨论】:

只是 composer 命令对我有用。但是我每次在生产服务器上创建一个新类后都必须运行这个命令,本地服务器不需要。

以上是关于Composer 和 Linux 生产服务器 - 自动加载不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Composer:防止更新需要更高 PHP 版本的包

作曲家自动加载在生产服务器上不起作用

如何使用composer创建生产稳定drupal 8项目?

Linux服务器下安装Composer 并使用Composer安装Thinkphp5.1

Linux服务器下安装Composer 并使用Composer安装Thinkphp5.0

Composer安装说在生产环境中出现以下错误