Purpose of PHP Constructors

Benefits of using a constructor?

Yes the constructor is called when the object is created.

A small example of the usefulness of a constructor is this

class Bar
{
// The variable we will be using within our class
var $val;

// This function is called when someone does $foo = new Bar();
// But this constructor has also an $var within its definition,
// So you have to do $foo = new Bar("some data")
function __construct($var)
{
// Assign's the $var from the constructor to the $val variable
// we defined above
$this->val = $var
}
}

$foo = new Bar("baz");

echo $foo->val // baz

// You can also do this to see everything defined within the class
print_r($foo);

UPDATE:
A question also asked why this should be used, a real life example is a database class, where you call the object with the username and password and table to connect to, which the constructor would connect to. Then you have the functions to do all the work within that database.

What is the function __construct used for?

__construct was introduced in PHP5 and it is the right way to define your, well, constructors (in PHP4 you used the name of the class for a constructor).
You are not required to define a constructor in your class, but if you wish to pass any parameters on object construction then you need one.

An example could go like this:

class Database {
protected $userName;
protected $password;
protected $dbName;

public function __construct ( $UserName, $Password, $DbName ) {
$this->userName = $UserName;
$this->password = $Password;
$this->dbName = $DbName;
}
}

// and you would use this as:
$db = new Database ( 'user_name', 'password', 'database_name' );

Everything else is explained in the PHP manual: click here

constructor - CodeIgniter

  • The reason this line is necessary is because your local constructor will be overriding the one in the parent controller class so we need to manually call it.
  • Constructors are useful if you need to set some default values, or run a default process when your class is instantiated. Constructors can't return a value, but they can do some default work.

Read Codeigniter Constructors

And Possible Duplicate of PHP Codeigniter - parent::__construct

Example

public function  __construct()
{
parent::__construct();
$this->load->helper('date');
$this->load->library('session');
$this->load->model('My_model');
$this->load->library('cart');

}

Why does PHP 5 use __contruct() instead of className() as constructor?

My guess would be that by the time object-oriented capability was being added to PHP, the designers were looking at Python.

Under what circumstances should we make a class constructor private

When do we have to define a private constructor?

class smt 
{
private static $instance;
private function __construct() {
}
public static function get_instance() {
{
if (! self::$instance)
self::$instance = new smt();
return self::$instance;
}
}
}

What's the purpose of using a private constructor?

It ensures that there can be only one instance of a Class and provides a global access point to that instance and this is common with The Singleton Pattern.

What are the pros & cons of using a private constructor?

  • Are Singletons really that bad?

  • What is so bad about singletons?

How to initialize PHP constructor fields in Visual Studio Code

you can use this PHP Constructor Visual Studio Code package to generate class constructor with variable and it's property.
Just install and use shortcut key Ctrl+Shift+P then command Insert Constructor Property. That's it. It will generate what you expect.

PHP Traits: How to circumvenient constructors or force them to be called?

I think you are trying to make the trait do a job it is not designed for.

Traits are not a form of multiple inheritance, but rather "horizontal reuse" - they're often described as "compiler-assisted copy-and-paste". As such, the job of a trait is to provide some code, so that you don't have to copy it into the class manually. The only relationship it has is with the class where the use statement occurs, where the code is "pasted". To aid in this role, it can make some basic requirements of that target class, but after that, the trait takes no part in inheritance.

In your example, you are concerned that a sub-class might try to access $primaryModel without running the constructor code which initialises it, and you are trying to use the trait to enforce that; but this is not actually the trait's responsibility.

The following definitions of class Sub are completely equivalent:

trait Test {
public function foo() {
echo 'Hello, World!';
}
}
class ParentWithTrait {
use Test;
}
class Sub inherits ParentWithTrait {
}

vs:

class ParentWithMethodDefinition {
public function foo() {
echo 'Hello, World!';
}
}
class Sub inherits ParentWithMethodDefinition {
}

In either case, class Sub could have its own definition of foo(), and by-pass the logic you'd written in the parent class.

The only contract that can prevent that is the final keyword, which in your case would mean marking your constructor as final. You can then provide an extension point that can be overridden for sub-classes to add their own initialisation:

class Base {
final public function __construct() {
important_things(); // Always run this!
$this->onConstruct(); // Extension point
}
protected function onConstruct() {
// empty default definition
}
}
class Sub {
protected function onConstruct() {
stuff_for_sub(); // Runs after mandatory important_things()
}
}

A trait can also mark its constructor as final, but this is part of the code being pasted, not a requirement on the class using the trait. You could actually use a trait with a constructor, but then write a new constructor as well, and it would mask the trait's version completely:

trait Test {
final public function __construct() {
echo "Trait Constructor";
}
}
class Noisy {
use Test;
}
class Silent {
use Test;
public function __construct() {
// Nothing
}
}

As far as the trait is concerned, this is like buying a bottle of beer and pouring it down the sink: you asked for its code and didn't use it, but that's your problem.

Crucially, though, you can also alias the methods of the trait, creating a new method with the same code but a different name and/or a different visibility. This means you can mix in code from traits which declare constructors, and use that code in a more complex constructor, or somewhere else in the class altogether.

The target class might also use the "final + hook" pattern:

trait TestOne {
final public function __construct() {
echo "Trait TestOne Constructor\n";
}
}
trait TestTwo {
final public function __construct() {
echo "Trait TestTwo Constructor\n";
}
}
class Mixed {
final public function __construct() {
echo "Beginning\n";
$this->testOneConstructor();
echo "Middle\n";
$this->testTwoConstructor();
echo "After Traits\n";
$this->onConstruct();
echo "After Sub-Class Hook\n";
}
use TestOne { __construct as private testOneConstructor; }
use TestTwo { __construct as private testTwoConstructor; }

protected function onConstruct() {
echo "Default hook\n";
}
}
class ChildOfMixed extends Mixed {
protected function onConstruct() {
echo "Child hook\n";
}
}

The trait hasn't forced the Mixed class to implement this pattern, but it has enabled it, in keeping with its purpose of facilitating code reuse.

Interestingly, the below code doesn't work, because the as keyword adds an alias, rather than renaming the normal method, so this ends up trying to override the final constructor from Mixed:

class ChildOfMixed extends Mixed {
use TestTwo { __construct as private testTwoConstructor; }

protected function onConstruct() {
$this->testTwoConstructor();
echo "Child hook\n";
}
}


Related Topics



Leave a reply



Submit