As far as Kohana is concerned, can you give me a short sentence or two as to WHEN and WHY I need to use a constructor within my controller? After a LOT of reading, I can't seem to wrap my tiny little brain around the constructor concept. Looking for "layman's terms" here. =)
Edit: Question pertains to Kohana v2.3.4
From The Documentation:
If you declare a constructor in your controller, for example to load some resources for the entire controller, you have to call the parent constructor.
public function __construct()
{
parent::__construct(); // This must be included
$this->db = Database::instance();
$this->session = Session::instance();
}
You can see in this example, the documentation demonstrates calling the parent constructor, and then setting up some properties for the class itself that will reference the database connection, and the session.
You see each of your controllers extends the parent controller. For the parent controller to run or import it's functionality into your controller, you need to a constructor in your controller. The parent adds/sets set's functionality behavior of your controllers.
Hope that makes sense, thanks :)
Related
I'm new to Yii2 and returning to PHP dev after a very long time. I have an extensive background in Java development. I stumbled onto this recommendation in the docs for ActiveRecord:
__construct() public method
Defined in: yii\base\BaseObject::__construct()
Constructor.
The default implementation does two things:
Initializes the object with the given configuration $config.
Call init().
If this method is overridden in a child class, it is recommended that
the last parameter of the constructor is a configuration array, like
$config here.
call the parent implementation at the end of the
constructor.
My question is about the last sentence:
call the parent implementation at the end of the constructor.
As a Java dev, this advice seems very weird to me. In Java, not only is it recommended to call the parent constructor as the very first call from your overridden constructor, this is even enforced and it's actually impossible to do it any other way. Either your parent constructor is called first implicitly, or, if you make an explicit call, it MUST be the very first statement in your method. This is enforced by the compiler.
Theoretically, this makes a lot of sense to me. Because as long as you did not call the parent constructor, your parent class did not have the chance to initialize, so any code you write in the constructor before calling the parent constructor would be working with a half-initialized object.
Looking at some SO answers I found, they seem to be going against the advice in the official docs and call the parent::__construct before their own custom logic, as I would expect it. For example, the accepted answer in the question How can I create a constructor in a Yii2 model shows an example where they call the parent first:
function __construct()
{
parent::__construct();
...
}
Another answer in that same question that does follow the official docs' advice scores 0 points:
public function __construct($config = []) {
// your init code here
// ...
parent::__construct();
}
Looking at the article about calling the parent constructor on phptutorial.net, they show an example where they call the parent first, as I would expect it:
class SavingAccount extends BankAccount
{
private $interestRate;
public function __construct($balance, $interestRate)
{
parent::__construct($balance);
$this->interestRate = $interestRate;
}
// ...
}
As I said my PHP is quitte rusty and I am a Yii2 n00b, so I was hoping to get some clarification here about this quitte fundamental thing that is still not clear to me after reading docs, tutorials and SO posts for a few hours now. This investigation was triggered by seeing the constructor being called both first and last very inconsistently in the codebase that I inherited and am currently working on.
In PHP, is there an official recommendation for when to call the parent constructor?
Is the advice to call the parent constructor last also in other PHP frameworks?
Hoping not to incite opinion-based discussion, so please quote official references, point to official docs of other projects etc.
#michal-hynĨica correctly stated the reason for your ambiguity(Worthy of votUp). But since you mentioned that the official reference, on the same page (BaseObject), this issue is explicitly stated: line
In order to ensure the above life cycles, if a child class of BaseObject needs to override the constructor,
....
of the constructor, and the parent implementation should be called at the end of the constructor.
According to the description of this link (similar to your question):
init () is called which further calls bootstrap () to run bootstrapping components.
As a result, this is done to ensure configuration.
The same process is done in the controller class and the main module.
Of course, there are many examples like this on the php site (depending on the need)
Also read lifecycles and entry script in yii. components and structure-applications. Good luck
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.
I'm very new to codeigniter ,
I wanted to know what is the meaning of a constructor in a controller . I saw the following code in a codeigniter tutorial -
class upload extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->helper(form);
}
// rest of the class...
My question is when is the constructor invoked - is it called every time the controller serves a request (e.g the controller class is instantiated for each request it receives?)
Well, that's a more general PHP question. Anyway, yes, the magic method __construct() is called (automatically) upon each instantiation of the class, as you can see in the manual: http://www.php.net/manual/en/language.oop5.decon.php
Usually, in CI is not necessary to call a constructor, unless you actually want one. In the example you posted, the code loads the helper on every instantiation of the class - which is the same as loading the helper in every method, just saves a lot of typing and ensures it's not forgotten. You can alternatively put the library/helper/model you want to have alywas loaded in the respective autoload array in config/autoload.php (check "autoloading" in CI's manual)
Once you define a constructor in your child Controller you're compelled to call the parent constructor (of the mail CI_Controller class), because there is where the main CI object is created and all the classes are loaded, and you need those in your child controller too; if fail to do so your child class will construct separately and won't inherit.
I hope I made myself clear, english is not my mothertongue :)
the constructor is magic Literally its called a magic method.
what makes the constructor cool is that it will do things for you BEFORE any of the methods. So if you have an admin class, and someone should be logged in in order to access it - you can check for login in the constructor and bounce them out if they are not authorized.
in the constructor you can load the models, libraries, helpers, etc that your class needs, and they will be available for any method in the class.
you can load in variables that are used by methods. this is really useful for models.
Don't use _construct() function in latest apache & codeigniter
Use helperlin in index() function
That's a general question. Constructor is a function that is automatically called when instantiated. this function helps us to intialize the things that we are going to need frequently in our code like when we have to load the models of helpers like form e.t.c.
$this->load->model('Model_name');
now when you write this line in your constructor you don't need to load this model again and again in your methods of that class.
I am trying to build my own simple MVC framework, mainly for educational purposes than anything else, I have used CodeIgniter in the past which has provided most of the inspiration for the features I would like to incorporate into my framework.
I would like to build a loader class like CodeIgniters, but I can't understand how CI loads the classes as if they are properties of the calling class i.e
class Random_Controller{
function __construct(){
$this->load->helper('some_class');
$this->some_class->do_something();
/*
How does CI load some_class as if it were a property of Random_Controller?
I can understand using something like $$class_name = new $class_name();
Or $$this->class_name = new $class_name();
But how can the dynamically named object be used with $this->?
*/
}
}
Hopefully that makes sense...
I am always surprised at how simple things appear with the right explanation. One more question though.
If $load is a reference to an instance of load class, and a record of all loaded classes is kept in an array, we are essentially doing:
$this->loaded_classes[$key]->do_something()?
So how does CI resolve the array to a variable name? I have seen some PHP magic methods that are called when variables do not exist or methods do not exist, would this be done in conjuction with these magic methods? In other words if the $this->some_class property does not exist we search for an element in the array with that key?
If that makes sense..
Uhm, well, let's start with this: the CI_Controller super class; it's the one all controllers extends, and acts as the CI superobject all the $this refer to.
CI_Controller acts as a singleton, and during initializing it calls a function, load_class() (you can find in core/common.php) which works as an autoloader : inside a static array ($_classes) it assignes as index the class name, and as value the class instance:
$_classes[$class] = new $name();
Then the companion is_loaded() function (in the same file) registers in an array all the function loaded, and is used to check later if the class has already been instantiated or not.
Ci_Controller assigns then to its $load property an instance of the Loader class (core/loader.php, by using the above mechanism)
$this->load =& load_class('Loader', 'core');
which, in turn, is responsibile for loading all other resources using its own methods: helper(),library(),model() and so on. Have a look at the source for all details, hope you got the picture though
To clarify as per your comment:
$load = new Loader();
$load->helper('helper');
would be the same as:
$this->load->helper('helper'),
as $this->load contains an instance (by reference) of the Loader class.
Then how the helper(),library(),etc methods of the Loader class work would be too much to write here, and beside you can open up the Loader.php file and have a look by yourself.
Sorry if the title is a little vague, I do not know how else to describe it.
I am making my own small framework. Things are going nicely and I am enjoying looking at topics that I usually do not need to check out as 'the magic' does it for me.
My framework is PHP based and I want it to run from a single instance. What I mean by this is the following.
class Controller_Name extends Controller {
public function __construct() {
$this->load->library('session');
$this->load->model('Model_Name');
}
}
class Model_Name extends Model {
public function something() {
if ($this->session->get($something))
// Do something Amazing
}
}
As hopefully illustrated above I want all controllers / Models / Views to share already loaded libraries.
So if a class is loaded in the Controller, I will be able to use it in a view file.
Does anyone know how this done? Can you point me in the direction of an article covering it, what this is called or some php function calls either completely or partly do the job.
As always, any answers are greatly appreciated.
If your aim is to make sure all dependencies inside your classes are resolved, have a look at the Service Containers from the Symfony Dependency Injection Component or the Stubbles framework.
Your controller can implement __get and intercept requests for libraries that have been loaded. Ideally you'd store the libraries in a static field to get the reuse you mentioned you wanted.
Also, to get load to behave like you want I'd personally create a Loader class and create an instance of it in the Controller. Then in the __get magic method I'd make it fetch it from the loader.