1

Can we declare __constructor and class name constructor in same class?

If yes, does both get called when object gets created. Also what will be the sequence.

If only one will get called then which one? and Why?

Rishabh Srivastava
  • 3,683
  • 2
  • 30
  • 58
Rohit Londhe
  • 49
  • 1
  • 1
  • 5
  • 1
    Why not just try it out? ;) Also, keep in mind, classes in namespaces don't support PHP4 style constructors. They only support `__construct()`. – Seer Apr 22 '15 at 10:10
  • Just to know, do you have a real case using __contructor + class name ? – Vincent Decaux Apr 22 '15 at 10:10
  • 1
    possible duplicate of [\_\_construct() vs SameAsClassName() for constructor in PHP](http://stackoverflow.com/questions/217618/construct-vs-sameasclassname-for-constructor-in-php) – yergo Apr 22 '15 at 10:13

2 Answers2

3

Further down this answer you'll find your individual questions answered in a handy list format. But first, allow me to give you some general information, documentation quotes, links and code snippets that'll help you understand all this a bit better.

You can define both types of constructors, but PHP will never treat both methods as constructors at the same time, as is explained here:

For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, and the class did not inherit one from a parent class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.

so the same name constructor is a fallback if no __construct method is found. Its main purpose is to maintain backwards compatibility with hopelessly outdated versions of PHP, so it's something that will be removed in the next major release of PHP (PHP7 is coming later this year). PHP7 will softly deprecate this "feature", and it'll be removed completely from PHP8

As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.

In case of PHP 5.3.3 and up, if you're using namespaces at least, the same-name constructors won't work at all

So in short:

class Foo
{
    public function Foo()
    {
        //this is the constructor
    }
}

but:

class Foo
{
    public function __construct()
    {
        //this is the constructor
    }
    public function Foo()
    {
        //this is just a method
    }
}

It's also worth noting that defining both possible constructors in the same class emits an E_STRICT notice. But on with the examples...

or:

class Bar
{
    public function __construct()
    {
        //this is the constructor
    }
}


class Foo extends Bar
{
    public function Foo()
    {
        //this is a regular function
        //Bar::__construct is the constructor
    }
}

And

namespace Foo\Bar;
class Foo
{
    public function Foo()
    {
       //this is just a method
       //Foo\Bar\Foo is a class without a constructor
    }
}

So basically:

  • Can you define a same-name constructor? Yes, if there is no __construct method defined on the class or any of its ancestors. If a __construct method exists, the same-name constructor becomes a regular method, and PHP will emit a E_STRICT notice
  • Will both methods be called as constructor? No, if a __construct method exists, that's the constructor. If not, the method with the class name will be called. Why? Because PHP5 favours the __construct methods, the PHP4 constructors is a backwards-compatibility fallback mechanism. Fallbacks will never take precedence over the default, that's why only the __construct method will be invoked. Simple.
  • Defining both types of constructors emits an E_STRICT notice (in PHP5, PHP7 will emit an E_DEPRECATED notice if it sees a PHP4-style constructor).
  • If your class is namespaced, it depends on the PHP version 5.3.3 and up will only use __construct methods. Given that we're currently on version 5.6, and PHP7 is due this year, I wouldn't write code that requires a deprecated PHP version
  • PHP7 is due soon, and it breaks backwards compatibility

All in all, the same-name constructors have been replaced by __construct quite some time ago, so I'd use that. More over: using the name-based constructor mechanism is quite error-prone considering they turn into regular methods the moment a __construct method is found somewhere in the inheritance chain. Using both emits notices, which implies a significant performance hit
If you really want to, you could perhaps conceivably think about maybe dreaming to write something along the lines of:

class Foo
{
    private $constructed = false;
    public function __construct()
    {
        if ($this->constructed === false)
        {
            $this->Foo();
        }
    }
    public function Foo()
    {
        $this->constructed = true;
        //do constructor stuff...
    }
}

Adding inheritance to the mix, and you'll end up with this:

class BaseClass//the parent
{
    protected $constructed = false;
    final public function __construct()
    {
        if ($this->constructed === false)
        {
            $class = explode('\\', get_class($this));
            $method = end($class);
            if (method_exists($this, $method))
            {
               //use func_get_args_array() + call_user_func_array
               //if your constructor takes arguments:
               call_user_func_array(
                   array($this, $method),
                   func_get_args_array()
               );
               $this->constructed = true;
               //simple version: $this->{$method}();
            }
        }
    }
}

But let's be honest for a second, that would really be a silly thing to do, wouldn't it? That, and the notices aren't solved by using this approach, so you still have to account for those notices anyway. That, and your constructor, at least in the second case, breaks the liskov principle (inherited contract breach) if your child class constructor requires arguments.

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
0

yes you can ,but it does't make sense to me, why you want to do so , if you like some functionality then use contractor overriding . in PHP 5.3.3 class name method treated as normal function , for example.

<?php
namespace Foo;
class Bar {
    public function Bar() {
        // treated as constructor in PHP 5.3.0-5.3.2
        // treated as regular method as of PHP 5.3.3
    }
}
?>

it's mean in version 5.3.3 or higher you have to declare constructor like __construct class name constructor will not work if you use both .

Abdul Manan
  • 2,255
  • 3
  • 27
  • 51
  • PHP 5.3.3 will still use same-name constructor methods _if_ the class is not namespaced and there is no regular `__construct` method defined (either in the class itself, or in its parents) – Elias Van Ootegem Apr 22 '15 at 10:57