I want my controllers to be extended from my base controller (no from Zend_Controller_Action).
How can I extend my base Contoller from Zend_Contoller_Action. And where this custom base controller to be placed so it will be accessible to other contollers.
Thanks in advance
To extend write:
abstract class Mylib_YourBaseController extends Zend_Contoller_Action{
}
Create a directory called Mylib in the same place the Zend library is, that's it.
My_Controller_Action extends Zend_Controller_Action { ... }
Place it in library/My/Controller/Action.php , then in you're app.ini ( or at bootstrap ) you need to register the namespace My , then all you're controllers can extend My_Controller_Action .
Related
It appears that in Zend Framework 2, every controller seems to extend the AbstractActionController by default.
I was thinking if there's a way for all my controllers to extend a CustomController that in turn extends the AbstractActionController.
The purpose of this CustomController, is to do checks like whether a user is authorized to access my other controllers or not and also may be generate menu navigation.
Is this still a good idea and if so, will doing this work?
**IndexController.php**
class IndexController extends CustomController {
}
**CustomController.php**
class CustomController extends AbstractActionController {
}
Thanks,
Of course you can extend a base class and it will work.
Is it a good idea ? It really depends on your project.
For authentication and permission check, you could also use a module like ZfcRbac or BjyAuthorize
For navigation, there is spiffy-navigation
If you use php 5.4+, Traits can also be an alternative to inheritance
This question already has answers here:
Codeigniter extending extended MY_Controller
(5 answers)
Closed 8 years ago.
class Settings extends USER_Controller {...}
class USER_Controller extends MY_Controller {...}//limit access to user and define some params and functions that is user depended
class MY_Controller extends CI_Controller {...}//provide extra functionality accross all controllers
well if i try to create above 3 class's this will not work.
yet if i just use settings extends MY_Controller it will work fine.
so is there a way i can put a middle class between my controller and MY_Controller -the base controller that extends CI_Controller ?
As #Minhaz Ahmed said, the problem is loading the class. Codeigniter only loads the class with the subclass prefix as in,
https://github.com/EllisLab/CodeIgniter/blob/develop/system/core/CodeIgniter.php#L276
if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
{
require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
}
So after some diggings I have came with a solution using both codeigniter hooks and spl_​autoload_​register() for my project without hacking the CORE. Please follow the steps to achieve what's in THE QUESTION.
Enable hooks in the config file if it isn't already.
create a hook in application/config/hooks.php as below.
$hook['pre_system'] = array(
'class' => '',
'function' => 'autoload',
'filename' => 'autoload.php',
'filepath' => 'hooks',
'params' => ''
);
Create the autoload.php in application/hooks folder.
inside the autoload.php file,
function autoload()
{
spl_autoload_register(function($class)
{
if(strpos($class,'CI_') !== 0 && file_exists(APPPATH.'core/'.$class.EXT))
{
require_once APPPATH . 'core/' . $class . EXT;
}
});
}
That's it.
Note: Here, I've used pre_system hook, not pre_controller, since codeigniter loads the base controller classes between pre_system and pre_controller hooks.
Hope this helps. If there are any issues with this please do comments.
Place the user_controller class file at the end of MY_Controller.php
MY_Controller.php in /application/core/
class MY_Controller extends CI_Controller {...}
class USER_Controller extends MY_Controller {...}
Now from your controller in your controllers folder, you can extend the controller from USER_Controller:
class Settings extends USER_Controller {...}
What did the best job for CI 2.1.4:
application/core
create for example:
- base_controller (base instructions, extending from ci_controller)
- admin_controller (extending from basecontroller and adds authentication instructions)
Then use them in: application/controllers:
for example:
class users extends admin_controller...
You could use Phil's core solution, its simple and easy.
http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY
You can extend the class the way you want but the problem is loading the class, you have to include your USER_Controller your Settings Class. Problem is not extend problem is including the file, so you have to find a way to include the second class.
See http://www.php.net/manual/en/function.spl-autoload.php
I want to register a script within the beforeAction method(Yii Framework). But I don't want to repeat that method in every single controller, so my question is how can i create a beforeAction() that all controllers will inherit?
Thx,
The default yiic generated yii webapp has a Controller class in project/protected/components/Controller.php , and all controllers in the app inherit from this Controller.
That class is the perfect place to add the beforeAction.
Edit: Incase you have not used yiic and don't have this default Controller class, it's fine to add a new class that extends from CController, and then have your controllers extend from this new class. You can keep all the common functionality for your controllers in this parent controller class.
You need to create BaseController.php inside components directory. Inside this file you will inherit your BaseController from CController. Write your beforeAction there. After this you will need to inherit all you controllers from BaseController.
1) Create Common parent Controller with extended with CController (example SomeController)
2) register script in the beforeAction() in this Controller (example SomeController)
3) extend this controller of your SiteController or Module Controller.
<?php
class SomeController extends CController
{
public function beforeAction()
{
// Your Register Script
}
}
class SiteController extends SomeController
{
// public function actionIndex
}
Am working with wiredesignz modular extensions for codeigniter, and i was wondering if its possible to access a regular codeigniter controller's public property from a module's controller
for example, this is a regular ci controller
<?php
class Dog extends CI_Controller {
public $name;
function __construct()
{
$this->name = "xyz";
}
}
and this a module controller
<?php
class Test extends MX_Controller {
function get_name()
{
//access the $name property of the dog controller here
}
}
If you're using HMVC there's no reason why all or any of your controllers can't inherit from MX_Controller. You can have controllers in your normal application/controllers or application/core folders that inherit MX_Controller, they don't have to be "module" controllers.
If you need to access properties from one controller in another why not create a base controller e.g. MY_Controller that extends MX_Controller, put it in either application/controllers or application/core and then every time you create a "module" controller simply inherit from MY_Controller instead of MX_Controller.
Don't forget you can load any module controller and use it like a library class.
I'm trying to extend my controllers with a global base controller as such:
class BaseController extends Zend_Controller_Action {
// common controller actions
public function listAction() {
// do stuff
}
}
class IndexController extends BaseController {
// index controller specific actions
}
class LoginController extends BaseController {
// login controller specific actions
}
But I get this error:
PHP Fatal error: Class 'BaseController' not found in /var/www/Zend/project/application/controllers/IndexController.php on line 3
Any ideas on how to get Zend to "see" this controller?
Autoloader
Setup the autoloader and register your library which should be besides the Zend library with the autoloader like so (in your bootstrap.php after setting the include path):
//AutoLoad loads classes automatically if they are used
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Mylibrary_');
Zend naming conventions
Then you should rename your BaseController as follows
/Zend (folder)
/Mylibrary (folder)
/Controller (folder)
Action.php <-- this is your basecontroller file
which contains:
class Mylibrary_Controller_Action extends Zend_Controller_Action
{
}
and your normal controllers in the controller folder:
class IndexController extends Mylibrary_Controller_Action
{
}
so basically when you want to extend the framework you keep a parallel structure in your own library.
I would separate it into your own library, i.e. create the file library/YourApp/Controller/Action.php, and consequently name it YourApp_Controller_Action extends Zend_Controller_Action. From there you could place controllers where they should be and let them extend YourApp_Controller_Action in favor of Zend_Controller_Action.
To find the file you should rely on the autoloader to look not just inside of library/Zend, but also in library/YourApp. I.e. look for the set_include_path in your bootstrap.
With this technique you should keep in mind that your custom "basecontroller" might get bloated with methods that not all of your controllers needs to inherit.
the quick solution that does not take advantage of the autoloader functionality is to
require_once '/path/to/BaseController.php' in the index-controller file.
If you have set-up autocontroller, then it can not find it, so you should consider checking what's wrong. Try the previous approach and inform on results.
Even more quicker solution (and conceptually more correct) is NOT to create base controllers at all:)
You have common action? Use action helpers. You have some functionality that must be autorun? Use controller plugins.
By design ZF controllers were made as flexible as possible, and limiting yourself by inheritance (and coupling it brings) is just not the best possible strategy.