Laravel控制器子文件夹路由

111

我是 Laravel 的新手。为了尝试保持我的应用程序有组织,我想把我的控制器放到控制器文件夹的子文件夹中。

controllers\
---- folder1
---- folder2
我试图路由到一个控制器,但laravel找不到它。

我尝试定位到一个控制器,但是 Laravel 找不到它。

Route::get('/product/dashboard', 'folder1.MakeDashboardController@showDashboard');

我做错了什么?

16个回答

150

对于 Laravel 5.3 及以上版本:

php artisan make:controller test/TestController

如果文件夹不存在,这将创建test文件夹,然后在其中创建TestController

TestController将如下所示:

<?php
namespace App\Http\Controllers\test;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class TestController extends Controller
{
    public function getTest()
    {
        return "Yes";
    }
}

你可以通过以下方式注册你的路由:

Route::get('/test','test\TestController@getTest');

有没有办法在 Laravel 4.2 中实现以上相同的功能? - Sagar Arora
12
php artisan make:controller test\TestController 会创建 testTestController.php 文件,而使用 php artisan make:controller 'test\TestController' (注意有引号)则可以正常工作。 - Laravel 5.4 - Giovanni S
3
php artisan make:controller test/TestController - Amrit Shrestha

75

将你的控制器添加到文件夹中:

controllers\
---- folder1
---- folder2

创建您的路由,不需要指定文件夹:

Route::get('/product/dashboard', 'MakeDashboardController@showDashboard');

运行

composer dump-autoload

请再试一次


我认为你也需要使用 artisan dump-autoload,或者仅使用 composer dump-autoload 就足够了吗? - reikyoushin
1
对于/controllers,只需要使用composer。但是如果你在ClassLoader::addDirectories中有一些composer没有的东西,你也需要使用artisan。 - Antonio Carlos Ribeiro
我突然想起我遇到过类似的情况...请看我的评论,位于原帖回答下方。 - reikyoushin
composer dump-autoload 对我也起作用。如果你使用的是Windows操作系统,你可以使用一个.bat文件来运行composer dump-autoload,而不是每次在CMD中输入。这就是我正在使用的: PUSHD "E:\path\to\non-public" newline START /B "Window 1" composer dump-autoload newline pause - vinsa
7
如果文件夹1和文件夹2中有两个同名的控制器,会怎么样?例如:admin/PostsController.php 和 frontend/PostsController.php。 - Levent Yumerov
显示剩余3条评论

52

对于使用 Laravel 5 的用户,您需要在子目录中设置控制器的名称空间(Laravel 5 仍处于开发阶段,每天都在发生变化)。

要获得如下的文件夹结构:

Http
----Controllers
    ----Admin
            PostsController.php
    PostsController.php

像这样,将Admin\PostsController.php文件放入命名空间中:

<?php namespace App\Http\Controller\Admin;

use App\Http\Controllers\Controller;

class PostsController extends Controller {

    //business logic here
}

那么你的路线是:

$router->get('/', 'Admin\PostsController@index');

最后,别忘了执行composer或artisan dump命令

composer dump-autoload
或者
php artisan dump

截至2015年1月23日,对我来说有效。随着L5尚未发布,这可能会有所变化。 - sehummel
感谢这个小技巧。在LV4中,您可以跳过“use App\Http\Controllers\Controller;”语句,因为您扩展了BaseController,它直接从Controller继承而来。但在LV5中情况不同,因为它直接扩展Controller,PSR-4自动加载需要知道在哪里找到Controller。 - Lionel Morrison
4
@user ?php namespace App\Http\Controller\Admin; 应该改为 Controller[s] 在末尾加上 s。 - Sven van den Boogaart
这个对我有用,但需要注意的是,在composer语句中必须加上“-o”,例如: composer dump-autoload -o - Scott Byers
这对我没有用,错误信息现在显示App\Http\Controllers\Auth\Controller未找到,为什么会添加单词Controller并且丢失控制器的实际名称?我认为是斜杠造成的。-o也没有帮助。 - blamb
好的,我找到了为什么它对我不起作用的原因,我正在扩展另一个控制器。我想现在必须通过完整的命名空间进行扩展,因为这个控制器位于我需要扩展的控制器的子文件夹中。终于! - blamb

20

对于 Laravel 5 或 Laravel 5.1 LTS,如果您在 Admin 文件夹中有多个控制器,则 Route::group 对您非常有帮助。例如:

更新: 可用于 Laravel 5.4

我的文件夹结构:

Http
----Controllers
    ----Api
          ----V1
                 PostsApiController.php
                 CommentsApiController.php
    PostsController.php

PostAPIController:

<?php namespace App\Http\Controllers\Api\V1;

use App\Http\Requests;
use App\Http\Controllers\Controller;   
use Illuminate\Http\Request;

class PostApiController extends Controller {  
...

在我的 Route.php 中,我将 namespace 组设置为 Api\V1,整体看起来是这样的:

Route::group(
        [           
            'namespace' => 'Api\V1',
            'prefix' => 'v1',
        ], function(){

            Route::get('posts', ['uses'=>'PostsApiController@index']);
            Route::get('posts/{id}', ['uses'=>'PostssAPIController@show']);

    });

要了解有关创建子文件夹的详细信息,请访问此链接


1
对于 Laravel 5.4,这是我目前找到的唯一解决方案。 - mosh442
完美解决方案 - Mohammed Riyadh
确实完美! - Rytis Dereskevicius
改变游戏规则的东西 ;-) - Strabek

9

1. 创建您的子文件夹,就像以下示例:

app
----controllers
--------admin
--------home

2.在app/routes.php中配置您的代码。

<?php
// index
Route::get('/', 'Home\HomeController@index');

// admin/test
Route::group(
    array('prefix' => 'admin'), 
    function() {
        Route::get('test', 'Admin\IndexController@index');
    }
);
?>

3.在app/controllers/admin/IndexController.php中编写内容,例如:

<?php
namespace Admin;

class IndexController extends \BaseController {

    public function index()
    {
        return "admin.home";
    }
}
?>

4. 访问你的网站,例如:localhost/admin/test 你会在页面上看到 "admin.home"。

附注:请忽略我的英文水平。


2
使用命名空间可以避免命名冲突。+1 - FDisk

8
在 Laravel 5.6 中,假设您的子文件夹名称为 Api
在您的控制器中,您需要这两行代码:
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;

在您的路由文件api.php中,您需要:
Route::resource('/myapi', 'Api\MyController');

6
我找到了一种方法如何做到这一点: 只需将路径添加到 /app/start/global.php 中即可。
ClassLoader::addDirectories(array(

    app_path().'/commands',
    app_path().'/controllers',
    app_path().'/controllers/product',
    app_path().'/models',
    app_path().'/database/seeds',

));

5
错误。由于/controllers已经在Laravel的composer.json基础中,因此任何在其下面的内容都会自动加载。您无需在global.php中添加/controllers/product。 - Antonio Carlos Ribeiro
1
@AntonioCarlosRibeiro 我曾经遇到过这个问题,尝试将模型放在文件夹中,但是卸载composer和artisan自动加载似乎没有起作用。你必须将它们放在composer.json或global.php中。 - reikyoushin
2
很容易检查:运行composer du后,打开vendor/composer/autoload_classmap.php,你的类必须在那里列出。 - Antonio Carlos Ribeiro

6
php artisan make:controller admin/CategoryController

在app/Http/Controllers目录下,admin是子目录,CategoryController是您想要创建的控制器。


5
我将使用Laravel 4.2进行翻译。下面是我的操作步骤:
我有一个如下所示的目录结构:
app
--controllers
----admin
------AdminController.php

在创建控制器之后,我在composer.json中添加了指向新的admin目录的路径:

"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/controllers/admin",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
}, 

下一步,我会运行。
composer dump-autoload

然后。
php artisan dump-autoload

然后在routes.php中,我像这样包含了控制器:
Route::controller('admin', 'AdminController');

一切正常运行良好。


对我来说可以运行,我只需要运行“composer dump-autoload -o”。 - phuang07
为了以防万一,我也使用了php artisan dump-autoload。 - Todor Todorov

5

以下是让您的应用程序有组织的方法:

每个路由文件(web.phpapi.php ...)在一个文件中声明了一个map()方法。

\app\Providers\RouteServiceProvider.php

当你映射路由文件时,可以为其设置->namespace($this->namespace),你将在示例中看到它。

这意味着你可以创建更多的文件,使你的项目更加有结构!

并为每个文件设置不同的命名空间。

但我更喜欢将命名空间设置为空字符串""

2)你可以按照本机 PHP 的方式设置路由控制器,请参见以下示例:

Route::resource('/users', UserController::class);
Route::get('/agents', [AgentController::class, 'list'])->name('agents.list');

现在,您可以在IDE中双击控制器名称,以快速方便地到达该位置。

最佳答案!完全符合Laravel,并在框架已经提供的基础上构建。 - jfoliveira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接