未找到 Laravel/Lumen 自定义类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34141397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel / Lumen custom class not found
提问by camelCase
I am experiencing an issue when trying to use a custom, namespaced class in Lumen, the micro-framework by Laravel. I am getting a Class not found
error when trying to instantiate the class.
我在尝试在 Laravel 的微框架 Lumen 中使用自定义命名空间类时遇到问题。Class not found
尝试实例化类时出现错误。
The relative directory:
相对目录:
|--- app
| |---Classes
| | |--- GetImages.php < My custom, namespaced class
|--- Http
|--- |--- routes.php < Using the class here works
| |--- Processors
| | |--- get.php < Using the class here does not work, generates the error (listed below)
The GetImages.phpfile, reduced for brevity:
该GetImages.php文件,减少了简洁:
namespace App\Classes;
class GetImages
{
public $name = 'Class instantiated';
}
The get.phpfile, where error is occurring:
发生错误的get.php文件:
use App\Classes\GetImages;
$n = new GetImages;
return $n->name;
If I make an ajax
request within the home page like $.get('http://www.example.com/app/Http/Processors/get.php')
I get the following error:
如果我ajax
在主页内提出请求,例如$.get('http://www.example.com/app/Http/Processors/get.php')
我收到以下错误:
Fatal error: Class 'App\Classes\GetImages' not found in http://www.example.com/app/Http/Processors/get.php on line 5.
However, as stated above, if I instantiate this class inside the routes.php
file, it works properly.
但是,如上所述,如果我在routes.php
文件中实例化这个类,它就可以正常工作。
The autoloadportion of composer.json
:
的自动加载部分composer.json
:
"autoload": {
"psr-4": {
"App\": "app/"
},
"classmap": [
"database/"
],
"files": [
"app/Http/helpers.php"
]
}
I feel this is an autoloading issue, but I have done composer dumpautoload -o
, composer update
, and followed PSR-4
standards, without any change. Any ideas what I'm missing?
我觉得这是一个自动加载的问题,但我已经做了composer dumpautoload -o
,composer update
和跟随PSR-4
的标准,没有任何变化。任何想法我错过了什么?
回答by Marcin Nabia?ek
If you run http://www.example.com/app/Http/Processors/get.php
and your whole get.php
file content looks like this:
如果您运行http://www.example.com/app/Http/Processors/get.php
并且您的整个get.php
文件内容如下所示:
use App\Classes\GetImages;
$n = new GetImages;
return $n->name;
it won't work because the file with class hasn't been loaded. In fact this file has nothing in common with Laravel/Lumen, it's just simple PHP file. When you use framework it uses Composer autoloader to load valid files, and when you use simple file you need to include autoloader or include necessary files manually.
它不会工作,因为尚未加载带有类的文件。实际上这个文件与 Laravel/Lumen 没有任何共同之处,它只是一个简单的 PHP 文件。当您使用框架时,它使用 Composer 自动加载器来加载有效文件,而当您使用简单文件时,您需要包含自动加载器或手动包含必要的文件。
You have 3 options:
您有 3 个选择:
- create route for this action and do what you want in controller
- at the beginning of file add
require '/vendor/autoload.php';
(with valid path to autoload file - manually require
GetImages
classrequire 'app/Classes/GetImages.php';
- 为此操作创建路由并在控制器中执行您想要的操作
- 在文件开头添加
require '/vendor/autoload.php';
(自动加载文件的有效路径 - 手动要求
GetImages
类require 'app/Classes/GetImages.php';
The best option will be probably the 1st one when you use framework and you don't use standalone PHP file to do the job.
当您使用框架并且不使用独立的 PHP 文件来完成这项工作时,最好的选择可能是第一个。
回答by Sven
You make an AJAX request to this URL: $.get('http://www.example.com/app/Http/Processors/get.php')
您向此 URL 发出 AJAX 请求: $.get('http://www.example.com/app/Http/Processors/get.php')
If this really gets you an answer from PHP, then you are bypassing your whole framework and made a big mistake when setting it up.
如果这真的让您从 PHP 得到了答案,那么您就绕过了整个框架并在设置时犯了一个大错误。
Every static asset should belong into the public
folder in an appropriate sub directory of your choice (images may go into public/img
etc.).
每个静态资产都应该属于public
您选择的适当子目录中的文件夹(图像可能会进入public/img
等)。
There should also be a file public/index.php
, which is supposed to get every request that is not an existing file somewhere in public
. This requires correct configuration of the web server, i.e. an Apache web server usually will get a .htaccess file (if you cannot add the contents to the vhost) that does the URL rewriting.
还应该有一个文件public/index.php
,它应该获取public
. 这需要正确配置 web 服务器,即 Apache web 服务器通常会得到一个 .htaccess 文件(如果你不能将内容添加到 vhost),它会进行 URL 重写。
The index.php
will bootstrap the autoloading of Composer, then initialize the framework and pass the current request to it for processing. The routing will find the associated controller, which will do some fancy data processing, and return a result (in the form of a rendered template, JSON data or anything else).
该index.php
将引导作曲的自动加载,然后初始化框架和当前请求传递给它用于处理。路由会找到关联的控制器,它会做一些奇特的数据处理,并返回一个结果(以渲染模板、JSON 数据或其他任何形式)。
This means that the URLs you should be using will never be identical to the path names of actual existing files. But this is what you did: app/Http/Processors/get.php
is directly accessed. This is a huge security hole, because all frameworks assume that the only folder that is publicly accessible is the public
folder. You are exposing one directory level higher, and everyone can access any file (if he knows it's name, or if your web server creates a directory listing). This might expose configuration files with sensitive passwords.
这意味着您应该使用的 URL 永远不会与实际现有文件的路径名相同。但这就是你所做的:app/Http/Processors/get.php
直接访问。这是一个巨大的安全漏洞,因为所有框架都假设唯一可公开访问的public
文件夹是文件夹。你暴露了一个更高的目录级别,每个人都可以访问任何文件(如果他知道它的名字,或者如果你的网络服务器创建了一个目录列表)。这可能会暴露带有敏感密码的配置文件。
And also it breaks your script in the Ajax request, because now you have to do all the initialization work again.
而且它会破坏 Ajax 请求中的脚本,因为现在您必须再次执行所有初始化工作。
Creating a controller is not enough, you also have to fix the configuration in general.
创建控制器是不够的,您还必须在一般情况下修复配置。
回答by racl101
I've got it working by adding a PS4 entry for the namespace of my custom classes and the directory where they are to be found within the composer.json file like so:
我已经通过为我的自定义类的命名空间和在 composer.json 文件中找到它们的目录添加一个 PS4 条目来使其工作,如下所示:
"autoload": {
"psr-4": {
"App\": "app/",
"MyCompany\MyCodeLibrary\": "MyCodeLibrary/"
},
"classmap": [
"database/"
]
},
Then within the project root (same directory containing the app
directory) I create my MyCodeLibrary
directory.
然后在项目根目录(包含app
目录的同一目录)中创建我的MyCodeLibrary
目录。
Then I just need to run:
然后我只需要运行:
$ composer dump-autoload -o
$ composer dump-autoload -o
And now, within the MyCodeLibrary
directory I add whatever classes I want. Let's say for example I add a class call Calculator.php
. I create it within MyCodeLibrary
.
现在,在MyCodeLibrary
目录中我添加了我想要的任何类。例如,假设我添加了一个 class call Calculator.php
。我在MyCodeLibrary
.
The file MyCodeLibrary/Calculator.php
would look like this inside (note that I can use the Lumen app()
and config()
helper methods to load my custom config files (or do other things like making database queries.):
该文件MyCodeLibrary/Calculator.php
在内部看起来像这样(请注意,我可以使用 Lumenapp()
和config()
helper 方法来加载我的自定义配置文件(或执行其他操作,例如进行数据库查询。):
<?php
namespace MyCompany\MyCodeLibrary;
class Calculator {
public $app_settings;
public __construct() {
// load custom config files
app()->configure('my-app-settings');
$this->app_settings = config('my-app-settings');
}
...
// other custom class methods
...
}
And if I need to use my class in Lumen Controllers, I can use it like this:
如果我需要在 Lumen Controllers 中使用我的类,我可以这样使用它:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use MyCompany\MyCodeLibrary\Calculator;
class TestController extends Controller
{
public $calculator;
public function __construct() {
$this->calculator = new Calculator();
}
public function doSomething() {
$this->calculator->something();
}
...
}
I know it's not the funnest thing to manually create your own instances but it works. I really don't know if there's a clever Laravel-like way to create new instances of your custom classes automagically with service providers and/or facades in Lumen because I haven't tried to look for it. Primarily, because I'm trying to keep it light. Otherwise I'd be using Laravel.
我知道手动创建自己的实例并不是最有趣的事情,但它确实有效。我真的不知道是否有一种类似于 Laravel 的聪明方式来使用 Lumen 中的服务提供者和/或外观自动创建自定义类的新实例,因为我还没有尝试寻找它。主要是因为我试图让它保持轻松。否则我会使用 Laravel。