"Class not found" 我错过了什么?

"Class not found" What did I miss?

我想向模型添加访问器和修改器。在 Laravel 4 中一切正常,但在 Laravel 5 中我遇到了一些麻烦。 我的 App 目录中有一个 "lib" 文件夹,其中包含 "db_transformers.php" 文件。此文件包含 类 与 "dbDate" 类似,具有 set 和 get 函数,可将存储在数据库中的日期转换为用户友好的格式。

"db_transformers.php" 文件的命名空间:

<?php namespace App\lib;    

我也参考了模型中的文件夹:

use App\lib;

但是我的方法仍然报错:

public function getDateTimeAttribute($value)
{
    return dbDate::get($value);
}

这将 return 一个 "Class 'App\dbDate' not found" 错误。

我的问题是什么?

您需要使用完整的 class 名称:use App\lib\dbDate;

您也可以考虑为此目的使用视图装饰器,因为在您的模型中这样做确实不合适。

有几个软件包可以帮助解决这个问题,例如https://github.com/ShawnMcCool/laravel-auto-presenter

您将自动加载(PHP including/requiring 一个 class 定义文件)与名称空间(一个允许 PHP classes/functions 分层命名的系统混淆了以帮助防止代码冲突)。

这很容易做到。涵盖 Laravel 5 中自动加载的更改超出了 Stack Overflow 问题的范围,但如果您有兴趣,我已经在 how autoloading works with composer/Laravel 4/Laravel 5 上写了多篇文章系列。

对于您的具体问题,您说您在名为 db_transformers.php 的文件中定义了一个名为 dbDate 的 class,并且 db_transformers.php 的命名空间为 App\lib

#File: lib/db_transformers.php
namespace App\lib;
//other code
class dbDate
{
    //other code
}
//other code

这意味着您的 class 的全名是 App\lib\dbDate整个是class的名字。这可能是在 PHP 中习惯命名空间的最重要的事情。

这意味着如果您想在其他代码中使用 class,您需要引用完整的 class 名称,包括前导反斜杠。

return \App\lib\DbDate::get($value);

您还可以使用 use 关键字导入 class

use App\lib\DbDate;
//other code
public function getDateTimeAttribute($value)
{
    //since we imported the class with `use`, we don't need to type the full name
    return DbDate::get($value);
}

使用关键字 将特定的 class 导入 到当前命名空间。当你说

use App\lib;

你说的是 PHP

You know that global classApp\lib? I'm going to refer to it below as lib

因为你没有一个名为 lib 的 class,这是没有意义的,这就是你的 use 没有帮助的原因。

这就是名称空间。您需要解决的另一个问题是自动加载。当您想要在项目中使用 class 定义文件时,自动加载可以让您跳过 requireinclude statement/function。

Laravel 4 使用了一堆不同的自动加载器,包括一种叫做 classmap 自动加载器的东西。 classmap 自动加载器会自动解析项目中的所有文件以查找 classes,并创建一个巨大的地图,其中 class 位于其中(这有点过于简化了,请参阅 article series 我之前链接了完整的细节)。

在 Laravel 4 中,classmap 自动加载器可能会为您读取 lib 中的文件。 Laravel 5 reduced the number of autoloaders,其中包括摆脱大多数文件夹的 class 地图自动加载器。

您可以在 Laravel 5 中做的最简单的事情是配置您的项目以再次使用 class 地图自动加载器。打开 composer.json 并找到此部分

    "autoload": {
            "classmap": [
                    "database"
            ],
            "psr-4": {
                    "App\": "app/"
            }
    },

并将 lib 添加到 classmap 自动加载器部分

    "autoload": {
            "classmap": [
                    "database",
                    "lib"
            ],
            "psr-4": {
                    "App\": "app/"
            }
    },

这告诉作曲家在创建自动加载器文件时包含 lib 文件夹。您需要 运行 dumpautoload 命令

composer dump-autoload

完成后,您应该可以根据需要使用 lib/db_transformers.php 中定义的 classes。