Run an init function in codeigniter - php

So I have my codeigniter setup in which I have a whole bunch of autoloaded helpers, libraries etc. I have a function written which I want to execute before the application bootstraps. Lets call the function init() and assume its defined in one of the helpers. Problem is that it uses functions from other autoloaded helpers and libraries etc so calling the init() in the autoloaded file itself does not help because it runs into 'call to undefined function X' etc..
So I want to make the init() call after everything has loaded..I cannot call it in the default controller, because users might have a different URL bookmarked.
What is the best way to call init() in this case?

Add a hook in application/config/hooks.php
$hook['pre_controller'] = function()
{
// ...
};
You may use a function declared in another file, for example:
$hook['pre_controller'] = array(
// ...
'function' => 'init'
);
There are many hooks available but in your case, the 'pre_controller' hook seems appropriate to me because pre_controller called immediately prior to any of your controllers being called. All base classes, routing, and security checks have been done.

Related

yii2 - can someone explain the meaning of parent::init(); statement

I have looked online for the meaning of parent::init(); . All I was able to find was that init() is to initialize some settings which want to be present every time the application runs.
Can anyone please explain the meaning of parent::init() in exact sense, like significance of both the words?
Thanks in advance.( I am sorry if its too simple! )
When we use parent::init(), we are just calling the parent method (in this case init()) inside a method of the current class.
About parent::
For example, let's say we have a class called MyClass. This class have a awesome method that runs alot of things:
class MyClass
{
public function runStuffs()
{
// trigger events, configure external stuff, adding default values to properties.
}
}
Now, after some time, we decided to create a new Class that extends from the first one. And we called MySecondClass:
class MySecondClass extends MyClass
{
}
It already have the method runStuffs(), but, for this second class, we need to do more things in this method, but maintaining what it have.
Sure we could rewrite the whole method and just copy and paste what we have in MyClass and add the new content. But this isn't elegant or even a good practice. what if later on We change the method in MyClass, you probably would like that MysecondClass have that changes too.
So, to solve that problem, we can call the parent method before write your new content:
class MySecondClass extends MyClass
{
public function runStuffs()
{
parent::runStuffs();
// do more things!
}
}
Now MySecondClass->runStuffs() will always do what its parent do and, after that, more stuff.
About the init() method.
init() is a method used in almost all classes from Yii2 framework (since most of then extends from yii\base\Object at some point) and works just like the __constructor() method (native from PHP). But there is some differences, you can read more here.
Actually the init() method is called inside the __constructor(), and the framework encorage us to use init() instead of __construct() whenever is possible.
Now if both are pretty much the same thing, why do they create this method? There is an answer for that here. (take a look at qiang's answer, from the dev team):
One of the reasons for init() is about life cycles of an object (or a component to be exact).
With an init() method, it is possible to configure an object after it is instantiated while before fully initialized. For example, an application component could be configured using app config. If you override its init() method, you will be sure that the configuration is applied and you can safely to check if everything is ready. Similar thing happens to a widget and other configurable components.
Even if init() is called within constructor rather than by another object, it has meaning. For example, in CApplication, there are preInit() and init(). They set up the life cycles of an application and may be overridden so that the customization only occurs at expected life cycles.
Conclusion
So, when you use a init() method and calls parent::init() you are just saying you want to add more things to that method without removing what it already was doing.
The parent::init(); Method is useful to execute a code before every controller and action,
With an init() method, it is possible to configure an object after it is instantiated while before fully initialized.
For example, an application component could be configured using app config.
If you override its init() method, you will be sure that the configuration is applied and you can safely to check if everything is ready.
Similar thing happens to a widget and other configurable components.
In Yii, init() method means that an object is already fully configured and some additional initialization work should be done in this method.
For More Information check this link :
https://stackoverflow.com/questions/27180059/execute-my-code-before-any-action-of-any-controller
Execute my code before any action of any controller
might be helpful to you.

Why do I need the Init function in my Controller?

I am new to PHP and I have a few questions that follows:
Do I need the init function or can I do the job (whatever I need to do in my code) without the init function?
I am saying this because the NetBeans "kinda" created/added automatically the init() function in my project.
In my code I am suppose to create the CRUD functionality in it.
If I don't use it what's the problems I might have and the downsides?
As the official docs would say:
The init() method is primarily intended for extending the constructor. Typically, your constructor should simply set object state, and not perform much logic. This might include initializing resources used in the controller (such as models, configuration objects, etc.), or assigning values retrieved from the front controller, bootstrap, or a registry.
You can have controllers that don't override the init() method, but it will be called under the sheets anyways.
If you are new to PHP, do not start by using a framework. Instead you should learn the language itself.
There is nothing significant about init() function. It is not a requirement for classes in PHP. Hell .. even __construct() is not mandatory in PHP.
That said, Zend Framework executes it right after the controller is created. It is required if you are using ZF.
You can read more about it here.
init() in Zend_Framework for most practical purposes is where you would put code that you need to affect all of the actions in that controller.(at least to test against all of the actions).
For example I often use the init() method to set up the the flashmessenger helper and to set the session namespace I want to be used.:
public function init() {
if ($this->_helper->FlashMessenger->hasMessages()) {
$this->view->messages = $this->_helper->FlashMessenger->getMessages();
}
//set the session namespace to property for easier access
$this->_session = new Zend_Session_Namespace('location');
}
Also Netbeans did not make this method or the controller, Zend_Tool made the controller and the methods utilizing the interface that Netbeans provided. That's why in your PHP settings for Netbeans you have to provide the path to the ZF.bat file and click the register provider button if you change your ZF install.
One more thing...Be aware that there more methods available to the controller that provide hooks into different parts of the dispatch cycle. You may not need them very often but you need to know they are there.
Simply its a constructor for that class(controller)...
init(){
$this->a = 1; //If we set something like this in the init
}
public function fooAction(){
echo $this->a; //1
}
public function barAction(){
echo $this->a; //1
}
ie the variables,objects..that is initialised in init will be available to all the actions in that controller

question related to app_controller

I am trying to include a small code in each page of my site.
Is there any way to do this without modifying each controller?
For example - I want to read/unread message from Message model.
Can i do this using the app_controller? I have add following function in app_controller.php.
I need suggestion. Please help me.
function messageStatus() {
App::import('Model','Message');
$new_message = $this->Message->find(
'first',
array (
'conditions' => array (
'Message.status' => '1'
)
)
);
$this->set("new_message",$new_message);
}
Depending on when you want to execute your actions, you will have to override in the app_controller.php file one of the following functions (according to the documentation), :
beforeFilter()
afterFilter()
beforeRender()
Since all your other controllers will be inheriting the methods of this class, your actions will be executed every time (as specified in the docs) one of your controllers are executed.
If you want to have a controller that does not run the code in the app_controller simply override the method again locally.
As user559744 mentioned you can use AppController within your application to create attributes and methods that can be accessed by your controllers. AppController is the parent class of your controllers.
You should copy app_controller.php from /cake/libs/controller/ to YOURAPP/app_controller.php to avoid making changes to the core files.
http://book.cakephp.org/view/957/The-App-Controller

adding new library in CodeIgniter

I've just started learning CodeIgniter, and I'm following this authentication tutorial by nettuts+. I did not understand one thing in it:
He added the following constructor code in the Welcome controller, which basically can be accessed only if the Session has variable username, otherwise it will redirect to admin controller.
function __construct()
{
session_start();
parent::__construct();
if ( !isset($_SESSION['username'])){
redirect('admin');
}
}
He said:
If you have multiple controllers, then
instead of adding the above code in
every controller, you should Create a
new library, which extends the
controller you will paste the code in,
and autoload the library into
project. That way this code runs
always when a controller is loaded.
Does it mean, I should
Create a file in application/libraries (eg. auth.php)
Paste this code in the auth.php
.
if ( !isset($_SESSION['username'])){
redirect('admin');
}
Now how to autoload this library and make it run every time a controller is loaded as he said?
Thanks
1) to autoload a library, just add it to the array in the file application/config/autoload.php, look for the 'library' section and paste the name of the library(without extension) there, as an element of the array.
$autoload['libraries'] = array ('auth');
2) I suggest you use the native session handler (session library), which works pretty well and avoids you to use php $_SESSION. You set a width $this->session->set_userdata(array('username' => 'User1', 'logged' => 'true'), and then you retrieve the values with $this->session->userdata['logged'], for ex.
Works like a charm and don't have to call session_start() and so on. Go check the help because it's really really clear on that.
3) As for your problem, I'll go, instead, for 'hooks'. There are different hooks, depending on their 'position', i.e. the moment in which you're calling them.
You can use, for ex.. the 'post_controller_constructor', which is called after controller initialization but BEFORE the methods, so it's in a midway between the constructor and the actual method. I usually insert this controls here.
You define hooks in application/config/hooks.php, and give them an array:
$hook['post_controller_constructor'] = array(
'class' => 'Auth',
'function' => 'check',
'filename' => 'auth.php',
filepath' => 'hooks',
'params' => array()
);
Anyway, for all these needs, the docs are pretty clear and straightforward, I suggest you read about hooks and session and you'll see everything gets much clearer!
The other way to do this. This is what he means in tutorial.
Create a library called MY_Controller in your application/libraries folder and extend it from CI_Controller:
Class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
// do the stuff you want to execute on every page.
// like auth.
}
}
Autoload the auth class in autoload.php config file. There is no need to autoload MY_Controller CodeIgniter will automaticly recognise it and run it. You can also load the Auth library within MY_Controller
Extend your controllers with MY_Controller class. (Not CI_Controller)
Extending your controller will give to more control of your project. You can add extra methods to use everywhere on your project.
For more information about extending native libraries of CodeIgniter check Creating Libraries: CodeIgniter.
Add the new library to the autoload library array in config/autoload.php.
$autoload['libraries'] = array ('database', 'session', 'auth');
Then when you want to call the function in controller constructors use $this->auth->function_name();.
You may want to make it a hook if there's a lot of repeat functionality that you don't want to call in every single constructor.

Zend Framework: What are the differences between init() and preDispatch() functions in controller objects?

I think the order of execution is init(), preDispatch() and then action() is called.
Should I initialize my variables, which are common among all actions, in init() or preDispatch()? I've seen people using both functions for initialization. Probably as the name suggests it should be done in init() but then what kind of stuff would go in preDispatch()?
What happens between init() and preDispatch() function calls?
First preDispatch() is called for instances of Zend_Controller_Plugin_Abstract. Here you have the request and response objects, so you might filter the request or do some preparation using the information from the request.
init() of the Zend_Controller_Action is called next as part of the constructor. It's there to help you initialize your controller, without having to override and repeat the signature of the constructor (Zend_Controller_Action::__contruct()).
The controller's preDispatch() method is called here. You can call $request->setDispatched(false) to skip the current action - not sure if you can do that in init()
Then your action method is called (viewAction() for example). Here you do your normal work like fetching stuff from the model and populating the view.
So the distinction should now be clear:
If you want something to be executed before all actions - put it in a plugin and use one of the hooks (besides preDispatch() there is routeStartup and others),
if you want before every action in a controller - init or preDispatch(),
if only for a single action - the action itself.
What happens between init() and preDispatch() function calls?
Almost nothing - preDispatch() is executed, and if you haven't called $request->setDispatched(false), the action is executed.
The init() method is primarily intended for extending the constructor. Typically, your constructor should simply set object state, and not perform much logic. This might include initializing resources used in the controller (such as models, configuration objects, etc.), or assigning values retrieved from the front controller, bootstrap, or a registry.
The preDispatch() method can also be used to set object or environmental (e.g., view, action helper, etc.) state, but its primary purpose is to make decisions about whether or not the requested action should be dispatched. If not, you should then _forward to another action, or throw an exception.
Note: _forward actually will not work correctly when executed from init(), which is a formalization of the intentions of the two methods.
init(): Loaded before functions, So if you want to load it before all functions of project, Put it at bootstrap Class. If before a specified class functions, Put it at init() this class function.
preDispatch(): Loaded before the front Controller.

Categories