I recently dove into the world of laravel (version 5.4). While initially confused, the concept of MVC makes a lot of sense in writing large applications. Applications that you want to be easily understood by outside developers.
Using laravel for this has greatly simplified coding in PHP and has made the language fun again. However, beyond dividing code into its respective models, views, and controllers, what happens if we need to divide controllers to prevent them from growing too large?
A solution that I have found to this is to define one controller each folder and then fill that controller with traits that further add functionalities to the controller. (All-caps = folder):
CONTROLLER
HOME
Controller.php
TRAITS
additionalFunctionality1.php
additionalFunctionality2.php
additionalFunctionality3.php
...
ADMIN
Controller.php
TRAITS
additionalFunctionality1.php
additionalFunctionality2.php
additionalFunctionality3.php
...
Within routes/web.php I woud initialize everything as so:
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');
});
With me being new to laravel, this seems like a simple and elegant way to organize my logic. It is however something I do not see while researching laravel controller organization.
The Question
Is there an issue, both in the short-run and in the long-run, of organizing my data like this? What is a better alternative?
Example Controller:
<?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());
}
}
?>