Welcome Guest, Not a member yet? Register   Sign In
Avoiding massive controller: where to put individual files
#1

I'm currently in the process of migrating a site to CI. Our old site had a fairly clever AJAX gateway file that would bootstrap our application and then checks its query string to determine which method was to be run and it would then include some other PHP file that matched the requested method. We have tons of these little method files and they add up to about 8000 lines of code -- which would be a LOT if we try to cram them in some massive ajax controller. I know we can create an ajax directory which contains multiple ajax controllers, but this would require us to painstakingly change a lot of our site's javascript if we have to totally remap all of our ajax urls to some new scheme.

Two questions:

1) If I ultimately determine to retain our old scheme whereby a single ajax gateway interprets the query string and includes some specific method file, where should I put all these files in the CI directory structure? Are they libraries? helpers? Please advise.

2) If there is a compelling reason to gut our existing AJAX scheme and move to some magic new organizational scheme, can anyone suggest to me an effective means of organizing our AJAX files? An important thing to consider is that most of our ajax actions depend on a user's session data, so all of our ajax files need to have a starting point that effectively retrieves this information.
Reply
#2

Firstly, have a nice choice with CI Big Grin

for your massive php file is all stored in same folder (not root folder), so I purpose that you can modify your .htaccess file to ignore rewrite url for that folder. so you can have 2 systems (1 is CodeIgniter and 1 is your old AJAX gateway) in a same time.

This is an sample of .htacess file

RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt|assets|YOUR_FOLDER_PATH_HERE)
RewriteRule ^(.*)$ /index.php/$1 [L]

hope that this is what you need Smile
Follow us at https://twitter.com/LIBRETeamStudio to get a lot of new cool stuff
Reply
#3

(12-18-2014, 12:43 AM)libreteam_studio Wrote: Firstly, have a nice choice with CI Big Grin

for your massive php file is all stored in same folder (not root folder), so I purpose that you can modify your .htaccess file to ignore rewrite url for that folder. so you can have 2 systems (1 is CodeIgniter and 1 is your old AJAX gateway) in a same time.

This is an sample of .htacess file

RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt|assets|YOUR_FOLDER_PATH_HERE)
RewriteRule ^(.*)$ /index.php/$1 [L]

hope that this is what you need Smile

I truly appreciate your thoughtful response. However, I do intend in this project to adapt all of my code to proper CodeIgniter-based concepts. The old code utilizes Joomla code objects so it must be essentially rewritten. The question is not so much how I alter the URL mapping, but rather where do these files go in the directory structure of CI? They are not controllers. Do they belong in the library directory? Or core directory?
Reply
#4

(12-27-2014, 02:52 PM)sneakyimp Wrote: The question is not so much how I alter the URL mapping, but rather where do these files go in the directory structure of CI? They are not controllers. Do they belong in the library directory? Or core directory?

core is to extend or replace core libraries.
model is for your data model (database classes).
libraries is for your other classes.
helpers is for file containing functions.
third_party is for files from other project used by you application.
Reply
#5

I have to support legacy code (not written by me) with some controller files with 4000-8000 lines. It is very hard.

My personal choice is skinny controllers. Bit CodeIgniter alone does not help much in this regard.

When a controller is loaded its constructor is executed and then the specific method that router calls is executed. The other methods are "dead code" for the particular request.

For dealing with this problem there is an extreme, experimental maybe approach demonstrated by this framework: https://github.com/bluzphp
Here is a sample controller: https://github.com/bluzphp/skeleton/blob...ssword.php - it is not even a class, it is a function that is loaded only for a particular request. There is no dead code.

Approximate simulation of this could be done in CodeIgniter if you have a separate controller for each possible request with a constructor and index method only. But this is quite extreme. Other methods could be implemented too, it is desireable the controller file not to excede about... let us say 400 lines.

But to split a massive controller file into smaller ones brings another problem - where to put the common code for initialization that usually is put within the constructor. Some people make libraries and then load them manually within all the controllers. This may be done, but it is not convenient. Another way that is better IMO is using base controllers - see this: http://avenir.ro/codeigniter-tutorials/n...ontroller/

If you want to implement some pure classes that are not CodeIgniter-specific, see this: http://forum.codeigniter.com/thread-420.html

So, to have skinny controllers, move code as much as you can within models, libraries, helpers, classes, etc and adopt the base controllers concept.
Reply
#6

(12-27-2014, 07:33 PM)includebeer Wrote: core is to extend or replace core libraries.
model is for your data model (database classes).
libraries is for your other classes.
helpers is for file containing functions.
third_party is for files from other project used by you application.

Perhaps you could be more specific? Like perhaps delineate where core libraries differ from non-core libraries? I've heard that model files may do more than just deal directly with a database. Do helpers contain ONLY functions? Might they not contain classes?
Reply
#7

Thanks for your response, Ivan. Your contributions are always very helpful.

(12-27-2014, 08:18 PM)ivantcholakov Wrote: When a controller is loaded its constructor is executed and then the specific method that router calls is executed. The other methods are "dead code" for the particular request.
I like CodeIgniter's basic routing approach very much, but I guess I agree you might have a lot of dead code in a file. I don't expect this will be much of a performance issue if one has APC or some other byte code caching module installed on their server. I both agree and disagree that it causes a code organization problem. Yes your controller files might get large, but you are allowed to use a directory to create multiple controllers. It's limited flexibility, but at least there is some flexibility.

(12-27-2014, 08:18 PM)ivantcholakov Wrote: For dealing with this problem there is an extreme, experimental maybe approach demonstrated by this framework: https://github.com/bluzphp
Here is a sample controller: https://github.com/bluzphp/skeleton/blob...ssword.php - it is not even a class, it is a function that is loaded only for a particular request. There is no dead code.
I've looked at it a bit. Looks like it uses a pretty generic namespace 'Application' but somehow manages to use anonymous functions. The function definition has a "use ($view)" syntax that I don't really understand.

Thanks for showing me, but I don't think I will be learning that framework.

(12-27-2014, 08:18 PM)ivantcholakov Wrote: Approximate simulation of this could be done in CodeIgniter if you have a separate controller for each possible request with a constructor and index method only. But this is quite extreme. Other methods could be implemented too, it is desireable the controller file not to excede about... let us say 400 lines.
Yes that does sound extreme -- and unnecessary I think. It sort of defeats the point of grouping common functionality into a common controller. Surely the point of putting multiple public methods in a single controller is to group like functionality such that those similar public methods can easily share non-public methods because they are all dealing with similar requests?

(12-27-2014, 08:18 PM)ivantcholakov Wrote: But to split a massive controller file into smaller ones brings another problem - where to put the common code for initialization that usually is put within the constructor. Some people make libraries and then load them manually within all the controllers. This may be done, but it is not convenient. Another way that is better IMO is using base controllers - see this: http://avenir.ro/codeigniter-tutorials/n...ontroller/
Well said! This is precisely what I'm doing now. So far, the only stuff that seems appropriate in base controller classes is session-related. I expect I will probably encounter more stuff that seems appropriate for a base class. My bigger concern is that I have a lot of 'cross-cutting concerns' such as a registry, sending email, etc. and I'm wondering where I should put code that is going to be used by many different controllers. My database classes seem pretty obviously to belong to the model directory, but I'm wondering about other code. I have some pretty elaborate purchase-related behavior that communicates with payment gateways and has all kinds of database interaction and logic branching depending on the database state. If that all ends up controllers, my controllers are going to be huge.


If you want to implement some pure classes that are not CodeIgniter-specific, see this: http://forum.codeigniter.com/thread-420.html

So, to have skinny controllers, move code as much as you can within models, libraries, helpers, classes, etc and adopt the base controllers concept.
[/quote]
Reply
#8

(12-28-2014, 12:23 PM)sneakyimp Wrote:
(12-27-2014, 07:33 PM)includebeer Wrote: core is to extend or replace core libraries.
model is for your data model (database classes).
libraries is for your other classes.
helpers is for file containing functions.
third_party is for files from other project used by you application.

Perhaps you could be more specific? Like perhaps delineate where core libraries differ from non-core libraries?

I should have say "core classes". CodeIgniter's core classes are in system/core

http://www.codeigniter.com/user_guide/ge...asses.html



Quote:I've heard that model files may do more than just deal directly with a database. Do helpers contain ONLY functions? Might they not contain classes?

That's the way CodeIgniter's is structured. Nothing prevents you from putting whatever you want in those files. In my models I also have functions that do other stuff than database operations. Like data validation, for example. Stuff related to the database model.

I suggest you read the User Guide to learn the basics of CI :

"Models are PHP classes that are designed to work with information in your database. For example, let's say you use CodeIgniter to manage a blog. You might have a model class that contains functions to insert, update, and retrieve your blog data."
http://www.codeigniter.com/user_guide/ge...odels.html

"Helpers, as the name suggests, help you with tasks. Each helper file is simply a collection of functions in a particular category. "
http://www.codeigniter.com/user_guide/ge...lpers.html
Reply
#9

I truly appreciate the extra detail and links you've provided here.

It seems pretty clear that the only things that should go in core are classes that extend/replace/mimic CI_* classes that are native to CodeIgniter. I'm thinking an extension of CI_Controller or CI_Model, for instance.

includebeer Wrote:In my models I also have functions that do other stuff than database operations. Like data validation, for example. Stuff related to the database model.
OK this is interesting. I might have been inclined to create a validation library, seeing as how it seems very 'library-like' in my vague reckoning of these things. I feel I should mention that when I've done a validation tool in the past, it was a class with all static methods so instantiating it would be pointless. My autoloader is making me much calmer about this.

Seems like models then are predominantly database-related, but with other possibly tangential stuff? I'm imagining classes of greater complexity that build on the basic db classes via Object Composition or Function Composition. I can't help but wonder about things like email functionality, payment gateway classes, etc. These seem like libraries to me but what do I know. Maybe payment gateway classes belong in third_party?

Still not sure what helpers are. Will check the reading. Thanks for your response.
Reply
#10

@sneakyimp

Models contain business logic in the generic sense. Some people see them only interacting with the database, well, its a narrow interpretation. If you think that a piece of code belongs to a model, move it there.

About the emails: Sending emails from models is not a problem. It would be nice emails to be driven by an Event system, but CodeIgniter alone does not have such.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB