What does a class constructor do? - php

I'm dumbfounded. I've been looking for a nice definition as to what a class constructor(specifically in PHP) exactly does.
As I understand it, it's the initial function that the class executes, when called, correct?
It is called whether or not we specifically call the function itself?
Can anyone shed some light here? Or at least point me in the right direction.

PHP allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
A constructor creates an Object of the class that it is in by initializing all the instance variables and creating a place in memory to hold the Object.
For example you may want to initialize
an integer variable to 10 or 20 based
on a certain condition, when your
class is created. In such a case you
cannot hard code the value during
variable declaration. such kind of
code can be placed inside the
constructor so that the initialization
would happen when the class is
instantiated.
When a PHP class is first called, the class will automatically run the class constructor function, which can help automatically configure the class. This can be useful if you need to preset some instance variables, sessions or cookies – prior to using the class methods.
A good read on Constructors in PHP

You're more or less correct - it is a function that is called when the class is instantiated (created with the new keyword).
You shouldn't have to specifically call it unless you extend a class and override the constructor, because a subclasses __construct() doesn't call it's parent constructor unless explicitly defined with parent::__construct().
E.g.
class A {
public $value;
function __construct() {
$this->value = "A";
}
}
$a = new A();
echo $a->value; // "A";
class B extends A {
}
$b = new B();
echo $b->value; // "A";
class C extends A {
function __construct() {
$this->value = "C";
}
}
$c = new C();
echo $c->value; // "C";
class D extends A {
function __construct() {
$this->value = "D";
parent::__construct();
}
}
$d = new D();
echo $d->value; // "D";

A constructor is called whenever a new instance (i.e. object) of a class is created. This allows you to setup the state of the object, as well as pass in any dependencies that the object might need to work properly, such as a CacheManager, or a database connection, or...
If you have an inheritance chain, i.e. Class C extends Class B which extends Class A, then remember to explicitly call the parent constructor if you override the constructor somewhere further down the chain:
<?php
class C extends B
{
public function __construct ($constructorParams)
{
parent::__construct($constructorParams);
}
}
The constructor should NOT return a value.

As I understand it, it's the initial function that the class executes, when called, correct?
It's the method called when a new instance of the class is first created. It's an instance method, because it only works on instances. (An object is an instance; a class is
something to which an object belongs. It's possible to have methods belong to the class, not to an instance. PHP calls these static methods, but that isn't always the terminology other languages use.)
In some languages, the constructor actually returns the new object. This is not the case in PHP, where the constructor exists for initialization purposes.
It is called whether or not we specifically call the function itself?
Correct. It's called when you use the new operator.
class Foo {
public function __construct() { echo "I foo'd.\n" ;}
}
$f = new Foo(); // Echos "I foo'd.\n"
You probably want to read over the PHP manual sections about classes and objects.

No.
No.
Yes.
Constructor is only called when you create a object. It is not called when you later only use your object somewhere.
When you create a new object, a constructor is a method that is called and it initialize the variables/fields of an object.
A constructor must have the same name as the class its in.

Yes. From Wikipedia -
In PHP (version 5 and above), the constructor is a method named __construct(), which the keyword new automatically calls after creating the object. It is usually used to automatically perform various initializations such as property initializations. Constructors can also accept arguments, in which case, when the new statement is written,you also need to send the constructor the function parameters in between the parentheses.
Wikipedia PHP Constructor Definition
PHP Site: What Constructors do ?

It's called when you create a new instance of the class, which is called automatically and you can initiate any local variables there. To do works which has to be done before freeing / destroying your object you can use the Destructor. Constructors and Destructors are'nt PHP specific but general for OO Programming languages.
See this

#include<iostream>
using namespace std;
class shape{
protected:
int w, h, a;
public:
shape(int, int);
};
shape :: shape(int x, int y){
w = x;
h = y;
};
class triangle : public shape{
public:
void disp_area();
};
void triangle :: disp_area(){
a = (w + h) * 1 / 2;
cout<<endl<<" Area Of Triangle : "<<a;
};
class rectangle : public shape{
public:
void disp_area();
};
void rectangle :: disp_area(){
a = w * h;
cout<<endl<<" Area Of Rectangle : "<<a;
};
int main(){
triangle obj1;
rectangle obj2;
obj1.shape(2, 3);
obj2.shape(4, 5);
obj1.disp_area();
obj2.disp_area();
return 0;
};

Related

Inheritance and function calls parent and sub-class

I encountered the following structure:
// parent class
class A
{
public function myFunc1()
{
$this->myFunc2();
}
private function myFunc2()
{
echo "called from class A";
}
}
// sub-class
class B extends A
{
private function myFunc2()
{
echo "called from class B";
}
}
$foo = new B();
$foo->myFunc1();
I expected, since there is no myFunc1() in class B, that the parent-function is called. This seems to be correct.
Now, to play it safe, I var_dump $this in myFunc1() and it shows, that this is an object from type B.
From my understanding, it should call myFunc2() from the Class B, but this isn't happening. It is calling the method from class A.
called from class A
instead of
called from class B
Yes, the functions are private and if I change it to protected, it works as expected. But private implies, that I have access to this function(s), when I'm in the specific context, doesn't it?
Private functions are only available within the class they are defined in, not in sub classes.
This means that your Object has two completely different functions, that happen to have the same name. Object B is aware of having one of them while Object A is only aware of having the other one. They do not interact in any way.
Since these functions are entirely private to the specific class they were defined in, there is no way to override them, or for any other class to call them.
If you need behavior that allows you to override how the class works, you'll have to use protected instead, which is designed specifically to be callable and changeable from extensions (and as such is a completely different beast all-together).
private always belongs to the same class you can't inherit it. That's the reason why myFunc1() calls myFunc2() from class A. If you want to overwrite it you have to change the visibility to protected.

prevent class instantization standalone, enabled from factory

I want to disable a class to be instantized by new operator, but lets suppose a getObject method what creates and returns an instance of it. Is it doable?
class C
{
protected function __construct()
{
}
public static function getObject()
{
return new self();
}
}
UPDATE:
The code above fulfills the requirement: the class cannot be instantiated using new, one needs to use the factory method getObject() to create an object. However, the OP did not specify the reason they need such a construct.
There are several reasons such a design emerges; one of them is when the creation of objects of type C needs to be completed with some initialization that, for whatever reason, cannot be done in the class' constructor.
Another reason for this way of constructing objects of class C is the Singleton design pattern; which in fact is an "anti-pattern", but this is another discussion; in order to implement a Singleton, class C should look like this:
class C
{
private static $instance = NULL;
protected function __construct()
{
}
public static function getObject()
{
if (! isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
Singleton or not, because method getObject() is static it cannot be stubbed or mocked by the test frameworks and its original implementation have to be used. More, because it is the only way to create objects of class C, other classes that use this class cannot be tested in isolation.
All in all, even the construction is possible, it is not recommended. Enforcing the creation of objects of class C using language mechanisms made the class a nuisance for testing other classes that use it.
If the creation of objects of class C needs to be done by a certain method because of its complex initialization, a better way is use the Builder design pattern. Make it a non-static method of another class (the "builder") and instruct the programmers (using the class documentation) to not create objects of class C directly, using new. This way it does not affect the testability of other classes.
I want to disable a class to be instantized by new operator
A common approach is to privatize the constructor.
class Example {
private function __construct() {
}
}
The following would result in a fatal error.
$object = new Example();
While this will work, I would encourage you, and future readers, to review Design Patterns in PHP.

Can we create an object of a class inside another class in php?

Can we create an object of a class inside another class in php?I hav made a small application in php,now I am trying to convert the entire code in a class-methods-object fashion.I m now Confused.
You you can do that, but whether you should depends on the lifetime of the two classes and their relation to each other. Basically, you have the choice between Composition and Aggregation.
Composition
You use Composition when the created object has a lifetime equal or less than the object that will use it, e.g.
class A
{
private $belongsToAOnly;
public function __construct()
{
$this->belongsToAOnly = new IBelongToA;
}
}
In this case A "owns" IBelongToA. When A is destroyed, IBelongToA is destroyed too. It cannot live on it's own and is likely just an implementation detail of A. It could be a ValueObject like Money or some other Data Type.
From Craig Larman's "Applying UML and Patterns":
the composite is responsible for creation and deletion of it's parts - either by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must be destroyed, or attached to another composite"
Aggregation
You use Aggregation when the lifetime of the created object is longer:
class A
{
private $dbAdapter;
public function __construct(DbAdapter $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
}
}
Unlike with Composition, there is no implication of ownership here. A uses DbAdapter but when A is destroyed DBAdapter lives on. It's a "uses" relationship instead of an "owns" relationship.
Creator Pattern (GRASP)
A good heuristic to decide when an object may create another object at runtime can be found in the Creator Pattern in GRASP which states that objects may create other objects when
Instances of B contains or compositely aggregates instances of A
Instances of B record instances of A
Instances of B closely use instances of A
Instances of B have the initializing information for instances of A and pass it on creation.
Alternatively, you can create Factories whenever you need to create instances of something and aggregate the factory instances, which will give you a cleaner separation of collaborators and creators.
Testability
An issue stemming from creating objects within objects is that they are difficult to test. When you do unit-testing, you usually do not want to recreate and bootstrap the entire system environment but concentrate on testing just that particular class in isolation. To do that, you swap out dependencies of that class with Mock Objects. You cannot do that when you use Composition.
So depending on what the collaborators of a class do, you might want to decide to always use Aggregation, because then you are effectively doing Dependency Injection all the way, which will allow you to swap out collaborators of a class easily, for instance to replace them with Mocks.
Yes you can, but that increases code coupling and makes testing harder.
I'd suggest creating it outside the class and pass it as an argument (it is called Dependency Injection).
class Foo
{
}
class Bar
{
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
}
$foo = new Foo();
$bar = new Bar($foo);
yes you can do it ..
here is one example..
a.php
<?php
class a{
public function function_1(){
echo "b";
}
}
?>
b.php
<?php
include_once ("a.php");
class b{
public function function_b(){
$a = new a;
$a->function_1();
}
}
$b= new b;
$b->function_b();
?>
Yes, you can create an object from a specific class from inside another class.
class SomeClass{
}
class SomeOtherClass {
function hello(){
$o = new SomeClass;
}
}
Yes, you can also define a function in a class. You can do everything in a class in php, please post your code where you confused.
Examples:
Object in a class.
class Foo
{
public $bar; // another object!
public __construct()
{
$this->bar = new Bar();
}
}
(global)Function in a class
<?php
class Foo
{
public function __construct()
{
function __construct()
{
echo "Yes, I'm a global function!";
}
}
}
new Foo();
__construct();
?>

PHP empty constructor

Just wondering is it best to define an empty constructor or leave the constructor definition out completely in PHP? I have a habit of defining constructors with just return true;, even if I don't need the constructor to do anything - just for completion reasons.
If you don't need a constructor it's best to leave it out, no need to write more code. When you DO write it, leave it empty... returning true doesn't have a purpose.
There is a difference between the two: If you write an empty __construct() function, you overwrite any inherited __construct() from a parent class.
So if you don't need it and you do not want to overwrite the parent constructor explicitly, don't write it at all.
EDIT:
previous answer is no longer valid, since PHP now behaves like other oop programming languages.
constructors aren't part of interfaces. therefore you are now allowed to override them how you prefer without any issues whatsoever
the only exception to this is:
interface iTest
{
function __construct(A $a, B $b, Array $c);
}
class Test implements iTest
{
function __construct(A $a, B $b, Array $c){}
// in this case the constructor must be compatible with the one specified in the interface
// this is something that php allows but that should never be used
// in fact as i stated earlier, constructors must not be part of interfaces
}
PREVIOUS OLD NOT-VALID-ANYMORE ANSWER:
there is an important difference between an empty constructor and no constructor at all
class A{}
class B extends A{
function __construct(ArrayObject $a, DOMDocument $b){}
}
VS
class A{
function __construct(){}
}
class B extends A{
function __construct(ArrayObject $a, DOMDocument $b){}
}
// error B::__construct should be compatible with A constructor
You should only define an empty constructor if your object should never be instantiated. If that is the case, make the __construct() private.
constructor always return instance of class in which its defined . Hence you never use "return" inside constructor . Lastly its better not to define it if you are not gona use it .
One reason you might want to define an empty constructor is when you want to avoid calling a function that has the same class name.
class FooBar {
function foobar() {
echo "Hello world";
}
}
new FooBar(); // outputs "Hello world" in PHP < 8
This is due PHP 4 backwards compatibility, where constructors had the same name of the class.
Anyway it got deprecated in PHP 7.4.26.
class FooBar {
function __construct() {
}
function foobar() {
echo "Hello world";
}
}
new FooBar(); // no output

Accessing child variables from the super class without instanciation

I'm attempting to access member variables in a child class via the parent class without instantiation.
This is one of my attempts but B::getStatic() fails with Access to undeclared static property.
Is there another solution to this, possibly without static?
class A {
static public function getStatic() {
return self::$myStatic;
}
}
class B extends A {
public static $myStatic = 5;
}
class C extends A {
public static $myStatic = 6;
}
var_dump(B::$myStatic);
var_dump(B::getStatic());
var_dump(C::$myStatic);
var_dump(C::getStatic());
The concept you're running into is called "Late Static Binding." Until PHP 5.3.0, there was no support for this.
If you're running 5.3.0 or higher, update the getStatic() method:
static public function getStatic() {
return static::$myStatic;
}
The others are right, the way your code is it can't be done since the variable doesn't exist at compile time.
The way to do something like this is usually with an abstract class (available in PHP5 and up, it looks like).
Class A would be the abstract class, and would have a getStatic() function. Classes B and C would extend A and have definitions for the getStatic() function. This way, when you call getStatic() you will get the value the subclass defines since there is no definition in A.
The caveat to this approach is that you can't instantiate A since it's abstract. You would ALWAYS have to make a B or a C (or a subclass there-of).
You could also make a setter in A and have the subclasses use it to set the value (instead of an '='s). That would let you instantiate A and it could set the value if it ever needs to. You might be able to make the setter private so it can't be called directly, I don't know if subclasses can use private functions in PHP.
You have a mismatch between the declaration of the function and variable.
Either you need to move the declaration of the function to B
or
move the declaration of the variable to A.
Class B inherits the properties from class A instead of the reverse.
Why don’t you use B::$myStatic like in your example?
You have to move myStatic into A. Your method getStatic in A can't access a variable that does not exist in A.
From the PHP manual:
Static references to the current class
like self:: or __CLASS__ are resolved
using the class in which the function
belongs, as in where it was defined:
So because the method is defined in A, when you call getStatic() on B or C it is trying to return a::$myStatic, which doesn't exist. Even if it did exist you would only ever get that value back, not any overridden value in a subclass.
A solution is Late Static Bindings, but this is only available in PHP 5.3 which is not yet released.
$myStatic must be declared static in class A: See here.
class A {
public static $myStatic = 5;
}
class B extends A {
public static $myStatic = 3;
}
class C extends A {
public static $myStatic = 1;
}
Then just use B::$myStatic ...

Categories