Welcome Guest, Not a member yet? Register   Sign In
Alternative Controller
#1

[eluser]Unknown[/eluser]
Hi guys,

I'm newbie and I'm having some problems with te Controller extending.

Here's my case:
I have defined two different controllers which extend the controller class, and my pages extend not the Controoller, but the Frontend or Backend one:
Frontend extends Controller, Backend extends Controller and in the controllers folder => class Login extends Backednd. I put those files(Frontend & Backend) in the application library folder and tried to autoload it via $autoload['libraries'], but it seems that autoloading doens't work and I'm getting an error message:
Fatal error: Class 'Backend' not found in ....

Must I include the Frontend/Backend classes in all my pages (from the controllers folder) or there a better solution?
#2

[eluser]Don Pinkster[/eluser]
Controllers are not libraries. You must include them in every controller page as you suggested yourself Smile
#3

[eluser]dyron[/eluser]
I think, it works with a "MY_Controller.php" file in the application/libraries folder.

My_Controller.php
Code:
class Frontend extends Controller {
}

class Backend extends Controller {
}
#4

[eluser]Sarfaraz Momin[/eluser]
Absolutely dyron, You are correct. You can add 2 files one for frontend and one for backend in application/libraries folder. Then you can just extend those classes. Simple, isn't it. If you have any doubts lemme know. Would try to paste some code to help you.

Good Day !!!
#5

[eluser]tonanbarbarian[/eluser]
I think the reason that autoload is not working in this case is that autoload is done AFTER the controller is created.

The way I have done this before is to override the Router. The advantage of this method is that you can determine which extension library is needed based on the route

libraries/MY_Router.php
Code:
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');

class MY_Router extends CI_Router {
  
  /**
   * Constructor
   */
  function MY_Router() {
    parent::CI_Router();

    // at this point we know the current route
    // so determine what libraries we need to load
    if ($this->directory == 'admin/')
      // admin so load the backend
      load_class('Backend', false);
    else
      // front end
      load_class('Frontend', false);

  } // MY_Router()

} // class MY_Router
Since the Router knows where we need to go immediately after it is instanciated we can just check the directory and if it is 'admin/' or whatever else you want, we know to load the appropriate class.
We use load_class rather than $CI->load->library because at this point there is not controller instanciated.
The 2nd parameter of load_class being set to false will ensure that the class is loaded but not instanciated.
#6

[eluser]Michael Wales[/eluser]
Just extend the controller class - the MY_Controller.php method that was described in previous replies.
#7

[eluser]esra[/eluser]
Maybe to clarify a few points mentioned above. Please, correct me if I'm wrong.

Case A. If a file called Controllers.php was placed in application/libraries/, it would be autoloaded to replace system/libraries/Controller.php. However, it would need to include all of the code necessary to serve as an MVC Controller. Inhiertance from system/libraries/Controller.php would not exist.

Case B. The use of the subclass_prefix (MY_ by default) is a namespacing scheme used by CI to identify extensions of the framework libraries for automatic class loading (or rather file loading because a file could include multiple classes). To learn how it works, study system/core/common.php (controller loading is handled here by the front controller). If a file called MY_Controller.php existed in application/libraries/ and the subclass_prefix was set to 'MY_', CI would automatically load that file rather than system/libraries/Controller.php. MY_Controller.php is assumed to be an extension of system/libraries/Controller.php even though it could fall into Case A where it is a replacement for system/libraries/Controller.php (that is, if MY_Controller does not extend Controller, it should theoretically completely replace Controller with no inhieritance).

The use of the subclass_prefix does not have to be restricted to the naming of parent class extensions. You can name all of your classes using the same subclass_prefix, but only the system/libraries/classnames are going to be autoloaded. For example, you could replace 'MY_' with 'C' as a namespace and use 'C' as a prefix for all of your application library classes (in this case, 'C' could represent a class). Why would you want to do this--possibly for file naming consistency reasons.

Libraries do not have to be restricted to a single class in a single file. You could include multiple classes in the same file and those classes would be inheirited when loaded by a controller. For example, the classes for a base Backend Controller and base Frontend Controller, as well as other base controllers, could reside in the same file and all classes would be available to the controller if that file was loaded. Would you want to do that? This is a question you need to consider on your own or it could be a methodology forced by a team or company development guidelines.

As an aside, controllers could include other code if that code does not have to be shared among other controllers. For example, it is possible to include helper code in a controller after the closing class brace. It's also possible to include another class in a controller (but there are a lot of arguments about why you should not). Basically, there are a lot of things you can do that are not mentioned in the user guide. A good understanding of OOP inhieritance should clarify such things.

tonybarbarian... CI actually uses two autoloading approaches. config/autoload.php is the application-specific autoloading approach. The loading routines in common.php define the framework's autoloading approach for classes and class extensions. It would be nice to see a better explanation in the user guide under a topic such as 'Front Controller Operation'.

Lastly and somewhere in 1.5.x, the use of the CI_ namespace (the other namespace used by CI) changed. In the past, most CI framework libraries included the CI_ namespace in their class names and aliases existed for calling something like Controller rather than CI_Controller. Now it appears to be the other way around. Controller is Controller, but CI_Controller is an alias for Controller for legacy reasons. When looking at some of the older code on the wiki, you need to keep this in mind. The code will still work, but the coding convention was changed as CI matured.
#8

[eluser]Phil Sturgeon[/eluser]
What he said... :coolsmile:




Theme © iAndrew 2016 - Forum software by © MyBB