Best way to do multiple constructors in PHP
I'd probably do something like this:
<?php
class Student
{
public function __construct() {
// allocate your stuff
}
public static function withID( $id ) {
$instance = new self();
$instance->loadByID( $id );
return $instance;
}
public static function withRow( array $row ) {
$instance = new self();
$instance->fill( $row );
return $instance;
}
protected function loadByID( $id ) {
// do query
$row = my_awesome_db_access_stuff( $id );
$this->fill( $row );
}
protected function fill( array $row ) {
// fill all properties from array
}
}
?>
Then if i want a Student where i know the ID:
$student = Student::withID( $id );
Or if i have an array of the db row:
$student = Student::withRow( $row );
Technically you're not building multiple constructors, just static helper methods, but you get to avoid a lot of spaghetti code in the constructor this way.
Is it possible to overload a constructor in PHP
The best way to do this is with an optional param, as others have said in the comments, PHP does not support overloading, so this would be my suggestion:
class Foo
{
public function __construct($p1, $p2 = null)
{
$this->p1 = $p1;
$this->p2 = $p2;
}
}
This means that you can choose to use $p2
when creating the class but you must use $p1
.
AFAIK, this is the only form of overloading (if you can call it that) that exists as yet in PHP
Edit
An extension from kingkero's answer, I came up with this solution which keeps logic out of the constructor minus a function call:
<?php
class overload
{
public function __construct()
{
return $this->switchConstruct(func_get_args());
}
protected function switchConstruct(array $args)
{
switch (count($args))
{
case 0:
return print "0 params<br />";
case 1:
return call_user_func_array(array($this, 'constr1'), $args);
case 2:
return call_user_func_array(array($this, 'constr2'), $args);
}
die("Invalid number of args");
}
protected function constr1($a)
{
print "constr1 called<br />";
}
protected function constr2($a, $b)
{
print "constr2 called<br />";
}
}
oop PHP more than one constructors
There are many ways of declaring 'multiple' constructors in PHP, but none of them are the 'correct' way of doing so (since PHP technically doesn't allow it). I don't see anything wrong with how you're doing it there, however. If you'd like more information, check out this Stack Overflow question.
You could just use an
if
statement. Something like this, perhaps?public function __set($property_name,$value)
{
$hidden_properties = array(
'comment_id',
'any_other_properties'
);
if(!in_array($property_name, $hidden_properties) &&
property_exists($this, $property_name))
{
$this->$property_name = $value;
}
}
Type hinting and multiple constructors
Correct, that's one of the limitations of the language.
(and the strlen() > 0
anyway can't be checked via a type. That auto-casts to string… so your method allows everything but "", null and false?)
Generally, there is RFCs in draft to expand the typehinting of PHP in 7.1:
https://wiki.php.net/rfc/union_types
That would allow you to write int | float | array | string $data = null
.
Multiple constructors in an abstract class
Here is a little approach:
<?php
abstract class MyClass {
protected $id = "";
protected $title = "";
function __construct($title) {
$this->id = strtolower($title);
$this->title = $title;
}
static function createWithTitle($title) {
$instance = new static($title);
return $instance;
}
static function createWithIdAndTitle($id, $title) {
$instance = new static($title);
$instance->id = $id;
return $instance;
}
abstract function render();
}
class Concrete extends MyClass {
function render() {
var_dump('id=' . $this->id, 'title=' . $this->title);
}
}
Concrete::createWithTitle('Title')->render();
Concrete::createWithIdAndTitle(1, 'Title')->render();
Note the static
keyword is very important here instead of self
see Late Static Bindings
How to implement php constructor that can accept different number of parameters?
One solution is to use defaults:
public function __construct($name, $lastname = null, $age = 25) {
$this->name = $name;
if ($lastname !== null) {
$this->lastname = $lastname;
}
if ($age !== null) {
$this->age = $age;
}
}
The second one is to accept array, associative array or object (example about associative array):
public function __construct($params = array()) {
foreach ($params as $key => $value) {
$this->{$key} = $value;
}
}
But in the second case it should be passed like this:
$x = new Person(array('name' => 'John'));
The third option has been pointed by tandu:
Constructor arguments work just like any other function's arguments. Simply specify defaults php.net/manual/en/… or use
func_get_args()
.
EDIT: Pasted here what I was able to retrieve from original answer by tandu (now: Explosion Pills).
Related Topics
Best Way to Defend Against MySQL Injection and Cross Site Scripting
Unformat Money When Parsing in PHP
On Delete Cascade With Doctrine2
Writing a New Line to File in PHP (Line Feed)
Manually Parse Raw Multipart/Form-Data Data With PHP
The First Day of the Current Month in PHP Using Date_Modify as Datetime Object
What's the Difference Between 'Isset()' and '!Empty()' in PHP
Creating Jquery Ajax Requests to a PHP Function
How to Check If an Array Value Exists
Notice: Trying to Get Property of Non-Object Error
Codeigniter: Create New Helper