簡體   English   中英

找不到Laravel / Lumen自定義類

[英]Laravel / Lumen custom class not found

當嘗試在Lumen(Laravel的微框架)中使用自定義的,命名空間的類時遇到問題。 嘗試實例化該類時,出現“ 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;

如果我在$.get('http://www.example.com/app/Http/Processors/get.php')之類的主頁中發出ajax請求,則會出現以下錯誤:

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 update ,並遵循了PSR-4標准,沒有任何更改。 有什么想法我想念的嗎?

如果您運行http://www.example.com/app/Http/Processors/get.php ,則整個get.php文件的內容如下所示:

use App\Classes\GetImages;

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

它不會工作,因為尚未加載具有class的文件。 實際上,該文件與Laravel / Lumen沒有任何共同點,只是簡單的PHP文件。 使用框架時,它將使用Composer自動加載器加載有效文件,而當您使用簡單文件時,則需要包含自動加載器或手動包含必要的文件。

您有3種選擇:

  • 為此操作創建路線並在控制器中執行所需操作
  • 在文件的開頭添加require '/vendor/autoload.php'; (具有自動加載文件的有效路徑
  • 手動要求GetImagesrequire 'app/Classes/GetImages.php';

當您使用框架並且不使用獨立的PHP文件來完成這項工作時,最好的選擇可能是第一個。

您對此URL進行AJAX請求: $.get('http://www.example.com/app/Http/Processors/get.php')

如果確實從PHP得到了答案,那么您將繞過整個框架並在設置它時犯了一個大錯誤。

每個靜態資產應該屬於進入public文件夾在你選擇一個合適的子目錄(圖像可能會進入public/img等)。

還應該有一個文件public/index.php ,它應該獲取public某個地方不存在的每個請求。 這需要正確配置Web服務器,即Apache Web服務器通常會獲得一個.htaccess文件(如果無法將內容添加到虛擬主機),該文件將進行URL重寫。

index.php將引導Composer的自動加載,然后初始化框架並將當前請求傳遞給它進行處理。 路由將找到關聯的控制器,該控制器將進行一些精美的數據處理,並返回結果(呈示模板,JSON數據或其他任何形式)。

這意味着您應該使用的URL永遠不會與實際現有文件的路徑名相同。 但這就是您所做的:直接訪問app/Http/Processors/get.php 這是一個巨大的安全漏洞,因為所有的框架假設可公開訪問的唯一文件夾是public文件夾。 您將暴露一個更高級別的目錄,每個人都可以訪問任何文件(如果他知道文件名,或者您的Web服務器創建了目錄列表)。 這可能會公開帶有敏感密碼的配置文件。

而且它還會破壞Ajax請求中的腳本,因為現在您必須再次執行所有初始化工作。

創建一個控制器是不夠的,通常還必須修復配置。

通過為自定義類的命名空間以及在composer.json文件中可以找到它們的目錄添加一個PS4條目來使其工作,如下所示:

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

如果我需要在流明控制器中使用我的類,則可以這樣使用它:

<?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中的服務提供商和/或Facades自動地創建自定義類的新實例,因為我沒有嘗試尋找它。 主要是因為我試圖保持輕巧。 否則我會使用Laravel。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM