在laravel中组织控制器

时间:2017-07-14 19:02:11

标签: php laravel laravel-5 directory-structure

我最近潜入了laravel(版本5.4 )的世界。虽然最初很困惑,但MVC的概念在编写大型应用程序时非常有意义。您希望外部开发人员轻松理解的应用程序。

使用laravel可以大大简化PHP中的编码,并使语言再次变得有趣。但是,除了将代码划分为各自的模型,视图和控制器之外,如果我们需要划分控制器以防止它们变得过大,会发生什么?

我发现的一个解决方案是为每个文件夹定义一个控制器,然后使用可进一步向控制器添加功能的特征填充该控制器。 (All-caps =文件夹):

CONTROLLER
    HOME
        Controller.php
        TRAITS
            additionalFunctionality1.php
            additionalFunctionality2.php
            additionalFunctionality3.php
            ...
    ADMIN
        Controller.php
        TRAITS
            additionalFunctionality1.php
            additionalFunctionality2.php
            additionalFunctionality3.php
            ...

routes/web.php内,我会将所有内容初始化为:

Route::namespace('Home')->group(function () {
    Route::get('home', 'Controller.php@loadPage');
    Route::post('test', 'Controller.php@fun1');
    Route::post('test2', 'Controller.php@fun2');
    Route::post('test3', 'Controller.php@fun3');
});
Route::namespace('Admin')->group(function () {
    Route::get('Admin', 'Controller.php@loadPage');
    Route::post('test', 'Controller.php@fun1');
    Route::post('test2', 'Controller.php@fun2');
    Route::post('test3', 'Controller.php@fun3');
});

由于我是laravel的新手,这似乎是一种简单而优雅的方式来组织我的逻辑。然而,在研究laravel控制器组织时,我没有看到它。

问题

在短期和长期中,是否存在组织这样的数据的问题?什么是更好的选择?

示例控制器:

<?php

namespace App\Http\Controllers\Message;

use DB;
use Auth;
use Request;
use FileHelper;

use App\Http\Controllers\Message\Traits\MessageTypes;
use App\Http\Controllers\Controller;

class MessageController extends Controller
{   
    // Traits that are used within the message controller
    use FileHelper, MessageTypes;

    /** 
      * @var array $data Everything about the message is stored here
      */
    protected $data = []; // everything about the message

    /** 
      * @var booloean/array $sendableData Additional data that is registered through the send function
      */
    protected $sendableData = false;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('access');
    }

    /**
      * Enable sendableData by passing data to the variable
      *
      * @param array $data Addition data that needs to registrered 
      * @return MessageController
      */
    protected function send ($data = []) { 
        // enable sendableData by passing data to the variable
        $this->sendableData = $data;  

        return $this;
    }

    /**
      * Enable sendableData by passing data to the variable
      *
      * @param string $type The type of message that we will serve to the view 
      * @return MessageController
      */
    protected function serve ($type = "message") {
        $this->ss();
        $this->setData(array_merge($this->sendableData, $this->status[$type]));
        $this->data->id = DB::table('messages')->insertGetId((array) $this->data);
    }

    /**
      * Set the data of the message to be used to send or construct a message 
      * Note that this function turns "(array) $data" into "(object) $data"
      *
      * @param array $extend Override default settings 
      * @return MessageController
      */
    protected function setData(array $extend = []) {
        $defaults = [
            "lobby" => Request::get('lobbyid'),
            "type" => "text",
            "subtype" => null,
            "body" => null,
            "time" => date("g:ia"),
            "user" => Auth::User()->username,
            "userid" => Auth::User()->id,
            "day" => date("j"),
            "month" => date("M"),
            "timestamp" => time(),
            "private" => Request::get('isPrivate') ? "1" : "0",
            "name" => Request::get('displayname'),
            "kicker" => null
        ];
        $this->data = (object) array_merge($defaults, $extend);

        // because a closure can not be saved in the database we will remove it after we need it
        unset($this->data->message);

        return $this;
    }

    /**
      * Send out a response for PHP
      *
      * @return string 
      */
    public function build() {
        if($this->data->type == "file") {
            $filesize = @filesize("uploads/" . $this->data->lobby . "/" . $this->data->body);
            $this->data->filesize = $this->human_filesize($filesize, 2);
        }
        // do not send unneccessary data
        unset($this->data->body, $this->data->time, $this->data->kicker, $this->data->name, $this->data->timestamp);

        return $this->data;
    }

    /**
      * Send out a usable response for an AJAX request
      *
      * @return object
      */
    public function json() {
        return json_encode($this->build());
    }

}

?>

2 个答案:

答案 0 :(得分:1)

Laravel架构对于任何规模的应用程序都足够简单。

Laravel为开发人员提供了几种机制来处理应用程序中的脂肪控制器。

  • 使用Middlewares进行身份验证。
  • 使用Requests进行验证和操作数据。
  • 使用Policy作为您的应用程序角色。
  • 使用Repository编写数据库查询。
  • 使用TransformersAPIs转化数据。

这取决于您的申请。如果它太大并且具有不同的模块或功能,那么您应该使用模块化方法。 一个很好的包可用于制作独立模块here

希望这有帮助。

答案 1 :(得分:0)

我认为你应该做一点点不同!首先,您应该使用与控制器相同级别的特征,因为特征不是控制器,您的树应该看起来更像:

Http
   Controller
     Controller.php
     Home
       YourControllers
     Admin
       Your admin controllers
   Traits
      Your Traits

接下来你的路线需要更像:

Route::group(['prefix' => 'home'], function()
{
    Route::get('/', 'Home\YourController@index')->name('home.index');
}



Route::group(['prefix' => 'admin',  'middleware' => ['admin']], function()
{
    Route::get('/', 'Admin\DashboardController@index')->name('dashboard.index');
}

你可以使用许多扭结或路线,如:

Route::post('/action', 'yourControllers@store')->name('controller.store');
Route::patch('/action', 'yourControllers@update')->name('controller.update');
Route::resource('/action', 'yourController');

资源路由自动创建最常用的,如post,patch,edit,index。你只需要编写动作和控制器及其动作。你可以用这个命令检查你的toutes:php artisan route:list

Laravel还有许多自动功能,例如使用此命令创建控制器:php artisan make:controller YourController。

对于路由,前缀会创建url的一部分,例如路由组中具有前缀“admin”的所有路由将像:www.yourwebsite.com/admin/theroute一样,并且也可以为某些用户阻止用中间件。

为了熟悉laravel我建议你在Laracasts上按照Jeffrey Way从头开始学习laravel 5.4教程,他很擅长解释和展示laravel如何工作。这是一个链接:https://laracasts.com/series/laravel-from-scratch-2017

希望它有所帮助,问我是否想知道其他任何事情或有一些精确性,我会尽力回答你!