未找到Laravel / Lumen自定义类

时间:2015-12-07 19:16:59

标签: php laravel composer-php laravel-5.1 lumen

在尝试使用Laravel的微框架Lumen中使用自定义的命名空间类时,我遇到了一个问题。尝试实例化类时,我收到Class not found错误。

相关目录:

|--- 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)

GetImages.php 文件,为简洁而减少:

namespace App\Classes;

class GetImages
{
    public $name = 'Class instantiated';
}

get.php 文件,其中发生错误:

use App\Classes\GetImages;

$n = new GetImages;
return $n->name;

如果我在主页中发出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.

但是,如上所述,如果我在routes.php文件中实例化此类,则它可以正常工作。

composer.json自动加载部分:

"autoload": {
    "psr-4": {
        "App\\": "app/"
    },
    "classmap": [
        "database/"
    ],
    "files": [
        "app/Http/helpers.php"
    ]
}

我觉得这是一个自动加载问题,但我已经完成了composer dumpautoload -ocomposer updatePSR-4标准,没有任何变化。我缺少什么想法?

3 个答案:

答案 0 :(得分:1)

如果您运行http://www.example.com/app/Http/Processors/get.php,则整个get.php文件内容如下所示:

use App\Classes\GetImages;

$n = new GetImages;
return $n->name;

它不起作用,因为没有加载类的文件。事实上,这个文件与Laravel / Lumen没有任何共同之处,它只是简单的PHP文件。当您使用框架时,它使用Composer自动加载器来加载有效文件,当您使用简单文件时,您需要包含自动加载器或手动包含必要的文件。

您有3个选项:

  • 为此操作创建路线并在控制器中执行您想要的操作
  • 在文件开头添加require '/vendor/autoload.php';(具有自动加载文件的有效路径
  • 手动需要GetImages课程require 'app/Classes/GetImages.php';

当您使用框架并且不使用独立的PHP文件来完成工作时,最好的选择可能是第一个。

答案 1 :(得分:1)

您向此网址发出了AJAX请求:$.get('http://www.example.com/app/Http/Processors/get.php')

如果这真的能让你得到PHP的答案,那么你就会绕过整个框架并在设置时犯了一个大错误。

每个静态资源都应属于您选择的相应子目录中的public文件夹(图像可能会进入public/img等。)

还应该有一个文件public/index.php,它应该在public中的某个位置获取不是现有文件的每个请求。这需要正确配置Web服务器,即Apache Web服务器通常会获取URL重写的.htaccess文件(如果您无法将内容添加到vhost)。

index.php将引导Composer的自动加载,然后初始化框架并将当前请求传递给它进行处理。路由将找到关联的控制器,它将执行一些奇特的数据处理,并返回结果(以呈现的模板,JSON数据或其他任何形式)。

这意味着您应该使用的URL永远不会与实际现有文件的路径名相同。但这就是你所做的:直接访问app/Http/Processors/get.php。这是一个巨大的安全漏洞,因为所有框架都假设唯一可公开访问的文件夹是public文件夹。您将更高的一个目录级别公开,并且每个人都可以访问任何文件(如果他知道它的名称,或者您的Web服务器创建目录列表)。这可能会使用敏感密码公开配置文件。

它还会破坏Ajax请求中的脚本,因为现在您必须再次执行所有初始化工作。

创建控制器是不够的,您还必须修改配置。

答案 2 :(得分:0)

我通过为自定义类的命名空间添加PS4条目以及在composer.json文件中找到它们的目录来实现它:

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

然后在项目根目录(包含app目录的同一目录)中创建我的MyCodeLibrary目录。

然后我只需要运行:

$ composer dump-autoload -o

现在,在MyCodeLibrary目录中,我添加了我想要的任何类。让我们说例如我添加了一个类调用Calculator.php。我在MyCodeLibrary内创建它。

文件MyCodeLibrary/Calculator.php内部看起来像这样(注意我可以使用Lumen app()config()辅助方法来加载我的自定义配置文件(或者做其他事情,比如制作数据库查询):

<?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
  ...
}

如果我需要在Lumen控制器中使用我的类,我可以这样使用它:

<?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();
  }

  ...

}

我知道手动创建自己的实例并不是最有趣的事情,但它有效。我真的不知道是否有一种聪明的类似Laravel的方式来自动地与Lumen中的服务提供商和/或外墙一起创建自定义类的新实例,因为我还没有尝试寻找它。主要是因为我试图保持清醒。否则我会使用Laravel。