I have a very big AppController. Nearly 75 functions and 130 kilobytes. It seems like that slows my system. Therefore I need to put those functions inside another file, and include that file, when some other controller needs it.
Options are creating a new controller or a new component. I'm trying to make a selection. What would be the advantages or disadvantages?
My points are:
I don't plan to use these functions inside another project. These functions will only be used by this project.
Inside my AppController I use these files, models, components. So they should be accessible by new structure.
App::import('Vendor', 'MyFancyVendor', array('file' => 'MyFancyVendor.php'));
App::uses('CakeEmail', 'Network/Email');
public $uses = array('Mytable1', 'Mytable2', 'Mytable3', 'Mytable4');
public $components = array('Session');
public $helpers = array('Session','Html');
Edit: Although using a huge new controller/component seems like the same with the old structure, difference is: Say it MyController12 and MyController13 doesn't use the methods of these huge functions inside AppController. But because of MyController12 is created from AppController it loads models, components and other things that it doesn't need. If I put of these logic out of my AppController, MyController12 will not load all that logic.
Follow this pattern:
Gather all related functionality in libraries.
Move all the data logic in the models.
Move all the view logic int the views (remember views are not templates)
For whatever else left, create some helpers
This will make your controller thinner. Creating other controllers should be your last chance, considering that you really don't want to use these kind of functionality in any other projects or part of the website.
The number of functions and the size of the files has absolutely no impact on the time code takes to execute.
Example: this has over 50 plugins loaded, 100ish controllers, 84k lines of code and the pages load reasonably fast.
You need to look at the queries being run. I suspect you are using queries with recursive set to 1 or 2. You should use containable at the very least.
Also look at the explain for your selects. If you are using mysql check that, or what ever is similar for your engine.
You can also install debug kit which displays a lot about what is taking time and can be sped up.
From what i can read, maybe its best that you think about dividing your AppController into multiple different files. Without seeing what your AppController it seems like it is assuming a lot of different roles.
Maybe its better to use different controllers for Mytable1, MyTable2, Mytable3, Mytable4, and use Components to share any information between them.
To answer your question, it is to use BOTH, and also to use Libs, and Helpers. Controllers where necessary, and Components where necessary. There's no point in changing your huge AppController into a huge Component. Split your files where you see something in common. Such as a ImageController, or Postcontroller, both however will use the Session Component.
Edit: What about changing the $helpers, $components, and $uses, from the AppController to the Individual controllers? Use relationships so that CakePHP can find the models. And make sure controllers aren't loading extra models / classes, as i doubt a big controller would cause sluggishness ( unless its your code )
Related
I'm developing a laravel app and would like to know some best practices.
As an example, I'm thinking about creating multiple controllers instead of writing more than 10 methods in a single controller.
I would like to know what are or( if there are any ) advantages other than code readability.
My main concern is that how does it affect when there are more files to compile by the PHP compiler.
Since I'm using a framework is it going to compile all the files or only the file requested by web.php
Some insight would be great!
If the 10 methods you have in a controller are all related, then keep them in that controller. If you have a FruitController with methods related to performing actions on types of Fruit, but you also include some methods for performing actions on Vegetables, move the Vegetable methods to a new controller.
Consider encapsulation when composing your files.
In general, avoid making files for the sake of it. If it makes sense to create a new file as the logic you intend to place inside that file has no other existing home, then fine, otherwise add your logic to an existing file.
I'm not sure splitting related code into separate files increases readability, large files can be readable as long as the code is well formatted and consistent (amongst other things). Check out this book on clean code if you're interested.
What you will get though is a decrease in productivity and maintainability by having to flick through and maintain several files that are all related.
There is no advantage of using multiple controllers instead of one controller, as long as it is related to one single model. You may say it increases readability, but this is better to unify them in one single controller which is associated with your model and try to pick expressive names for the methods. The main idea is to create one single controller associated with each of your models. Feel free to add as much as methods possible into your models to talk to your database and make queries and call those methods in the associated controller. Then you can trigger those controllers through the web.php routes to handle your data and pass them to the view layer.
When you create separate controller for particular functionality this is more readable for old and new developer.
Also please check this link
From laravel:
Instead of defining all of your request handling logic as Closures in route files, you
may wish to organize this behavior using Controller classes. Controllers can group
related request handling logic into a single class. Controllers are stored in the
app/Http/Controllers directory.
I recommend that you divide your logic into different controllers. For example you can place all your user logic into one controller userController.php:
Create User
Edit User
Delete User
Then create another controller to manage the logic for another controller like sending emails etc. In this way your logic is more organized, easy to work with and you can find and update your methods easier.
I'm currently using Symfony2 and and I'm trying to divide my code into different controller (like an Ajax Controller, a User Controller etc...) but I don't really know when I should use a create a new One.
For example my DefaultController is starting to be quite big (~800 lines) and I was wondering if having a too long controller could impact the website's performance? (Longer loading time...)
And, if it does, when should I split the controller into smaller ones ?
I would say that you should group your actions by which operate on the same data (entities) or operate within a well defined responsibility. E.g. UserController for users, PostController for blog posts, etc. This means that if you want to create an action which role is different than the rest of the actions, put it in a separate controller.
Symfony is caching almost everything so I don't think that huge controllers would cause an impact to the perfomance but if you have a thousands lines long controller, I'm not sure that it does only one thing.
The controller's size can be a warning sign too for the misplaced queries and business logic. You should separate QueryBuilder calls into Repository classes and other logic to services and event handlers. You can save more lines by using annotations instead of PHP code.
I think it's a good idea to start with a controller for each relevant model, with a CRUD structure.
Of course it depends on your needs, but if you have a model "Post", you probably will need a PostController with CRUD routes and methods, like : index (/posts), new, update, create, delete...
Depending what you need you can delete or add some method relative to a
Post from this base structure.
Try to detect what is realy relative to a specific model in your defaultController and create a controller for it.
Good luck.
What #riska and #Yoann said all holds true.
In addition, I prefer not to create separate controller if I'm sure that it hold only that one method. In that case, I just put it into DefaultController.
From my experience, controllers are the part of UI layer. If you care a lot about keeping your controllers small, let me give you the best scenario you can make what a controller must do:
1.Call the appropriate service
2.Return the response
That is 2 lines of code for each controller action, or you can even make it in one line.
Like person above said, controllers are usually separated by what type of entities / services they operate on. If you for example have an entity - lets say User, the following actions are most likely to be in there: createAction, editAction, removeAction, registerAction, activateAction, loginAction, logoutAction and so on...
It does not have any impact on performance if your controllers are thin or fat. The code will be executed in the similar flow, and all classes are being cached in the production environment.
I have a controller that is starting to feel very bloated. Some of the actions themselves are very large and much as I try to split things up, navigating this file is getting tiresome.
I was wondering if there is any way, and specifically any convention, for managing very large controllers? Is there a way to split a controller up into easier-to-manage sections?
I see that there is a CAction class. Is this the way to go? What about methods that aren't actions?
I think you should read this link http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices to improve your structure with MVC.
Besides, If you want to make your controller be simple then you can use CAction.
From http://www.yiiframework.com/doc/api/1.1/CAction:
CAction provides a way to divide a complex controller into smaller actions in separate class files.
To make your model be lean, you can use Behaviors from Yii.
Maybe your controller is bloated because it's doing things that should be sent to the model? Controllers should act as traffic cops. They respond to a request, gather the needed data (from various models), and then send that data to a view. Maybe your controller is doing some of the work that your model(s) should be doing?
I have a several functions which are quite large, and are only used in one controller function each, and I'm wondering where to put these? They are not displaying any views, but instead crunching some numbers.
If I'm not wrong, there are 4 possible places where i could put these function: in my controller, in a helper, in a library or in a model. But none of these seem appropriate, since I don't want the code to be loaded every time a user uses the controller, and model should be used to do database stuff, and helpers and libraries should contain code that can be used over and over again.
If it is business logic, the best place to put it is in the controller as a private method, then you can call that method from within the controller.
Just as a note, helpers aren't always loaded unless you autoload them or load them in the constructor of your controller. So, as an alternative, you can make these methods of a helper then just load the helper in the controller action you wish to use them. That way they only get loaded when you need them.
CodeIgniter comes with helpers that you probably might not use (doesn't load unless you specify it in the application/config/config.php file) and I don't think its a problem having functions that you only use once stored there (application/helpers ). For example I might use a random password generator once only, but its still there and won't be loaded unless I call it.
$this->load->helper('my_string_generators');
I'm thinking of re-working my MVC before I get to far along with it. At the moment it uses a sinle controller which takes the user input and determines the model. The model has maby differ methods which I call actions, because one is called automatically. The model loads its view file, which again holds many different methods. The model can set properties which can be used in the view. Then the controller calls th template classwhich parses the output for display.
Is this the bst way to do it?
Or should each different part (news, contact, about) have its own controller, which loads a specific model and view. Essentially, instead of grouping methods into a single file, it uses multipe files.
I'm kind of lost as to how I should do it.
Cheers
Start using a MVC that works and is well-known like in Symfony or Cake. From that you will decide:
what do to in your own, knowing the best practices;
to drop your own if you feel like you can save time by using theses.
If you are thinking of advancing your own MVC model, like #e-satis have said, you will need to experience what is happening in already developed systems. However, as based on my experience in designing MVC model and determining what is there in opensource community, I stick back to my own MVC for two good reasons. One reason is the flexibility of customization and the other is own MVC privacy.
I used the following approach for MVC design pattern.
A Router.php file identifying user-request urls. This router will be able to fetch controllers and include the file and call the controller default method.
The loaded controller is also able to load other controllers if required to function. This is done using a global method, where all controller Class will extend to a MainController Class which is able to call to other controllers.
I do use a global registry to set and get variables from one controller to the other.
The Models are used to get the Data from Table, and most of my Models will represent Database functions which includes CRUD (Create Read Update Delete). So that a controller can easily manipulate database table data using a model.
Naming conventions in all controller, models, and views is also important, if you want to system to be more intelligent to identify the required action knowing the file name.
I use the Views separately for each type of controller. And these views will be sent to a Master Template View file.
Same as models, the controller will be able to set Views to Master View.
There are other customizations which you can do, like applying security methods before calling a class, or after calling a class/controller/model/view etc.
This is done by the MainController, which it will always look into a folder with autoload class which states what files should be loaded before and after of different actions during the process of building the content and delivering the output.
MVC is not a small scale idea, but it is a design idea which can always be developed. There are so many PHP MVC open source frameworks to be found if you know how to search the major search engines like google.com
But I do advice you that, MVC is not a good solution if you are simply developing a small dynamic website, as it will consume more time in developing compared to developing small websites. MVC is ideal, if you have business logic and needs system automation in order to avoid most routine tasks of developing, and like that I would say MVC is most ideal for larger applications.
The model loads its view file
The Controller should act as a Mediator between the Model and the View.
The Model shouldn't be aware of the way the view renders it, and also the View shouldn't be aware of any kind of logic of the Model.
In theory, if your MVC is well structured, you should be able to represent the same Model with different types of Views (HTML, XML, JSON for example).
Build FrontController which parses request uri and decides which controller to load and which method to run. With .htaccess rewrite all request to index.php
//index.php
class FrontController{
function run(){
//parse request uri here /comment/new
//load controller comment
//run controllers method new and pass some request attributes
}
}
// ../controllers/comment.php
class Controller_Comment extends Controller{
function new($request){
//do stuff here
}
}