我想向模型添加访问器和突变体。在Laravel 4中一切都很好,但在Laraver 5中我遇到了一些麻烦。我的应用程序目录中有一个"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);
}
这将返回一个"找不到类App''dbDate'"错误。
我可能有什么问题?
您混淆了自动加载(PHP包括/需要类定义文件)和命名空间(一个允许对PHP类/函数进行分层命名以帮助防止代码冲突的系统)。
这是一件容易的事情。在Laravel 5中介绍自动加载的更改超出了堆栈溢出问题的范围,但如果你感兴趣,我已经写了一个关于自动加载如何与composer/Laravel 4/Laravel 5.一起工作的多篇文章系列。
对于您的特定问题,您说您在名为db_transformers.php
的文件中定义了一个名为dbDate
的类,而db_transformers.php
的命名空间为App'lib
。
#File: lib/db_transformers.php
namespace App'lib;
//other code
class dbDate
{
//other code
}
//other code
这意味着你班的全名是App'lib'dbDate
。整件事就是类名。这可能是PHP中最需要习惯的名称空间。
这意味着,如果你想在其他代码中使用这个类,你需要引用完整的类名,包括一个前导反斜杠。
return 'App'lib'DbDate::get($value);
您也可以使用use
关键字导入类
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);
}
use关键字将特定类导入到当前命名空间中。当你说
use App'lib;
你告诉PHP
你知道全局类
App'lib
吗?我在下面将其称为lib
由于您没有一个名为lib
的类,这是没有意义的,这就是为什么您的use
没有帮助的原因。
这就是名称空间。您需要解决的另一个问题是自动加载。当您希望在项目中使用类定义文件时,可以通过自动加载跳过require
或include
语句/函数。
Laravel 4使用了一堆不同的自动加载器,包括classmap
自动加载器。classmap自动加载器会自动解析项目中的所有文件以查找类,并创建一个类所在位置的巨大映射(这有点过于简化了,请参阅我之前链接的系列文章以获取完整的详细信息)。
在Laravel 4中,classmap
自动加载器可能会为您读取lib
中的文件。Laravel 5减少了自动加载器的数量,其中包括取消大多数文件夹的类映射自动加载器。
在Laravel 5中,您可以做的最简单的事情就是将您的项目配置为再次使用classmap自动加载器。打开composer.json
并找到该部分
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App''": "app/"
}
},
并将lib
添加到classmap
自动加载器部分
"autoload": {
"classmap": [
"database",
"lib"
],
"psr-4": {
"App''": "app/"
}
},
此命令将告诉composer在创建其自动加载器文件时包含lib
文件夹。您需要运行dumpautoload
命令
composer dump-autoload
之后,您应该能够随心所欲地使用lib/db_transformers.php
中定义的类。
您需要使用完整的类名:use App'lib'dbDate;
您还可以考虑为此目的使用视图装饰器,因为在模型中这样做确实不合适。
有几个软件包可以帮助实现这一点,例如。https://github.com/ShawnMcCool/laravel-auto-presenter