Edit report at http://bugs.php.net/bug.php?id=52330&edit=1

 ID:          52330
 Updated by:  ahar...@php.net
 Reported by: whistl0r+phpbug at googlemail dot com
 Summary:     __construct() method should always return a new instance
-Status:      Open
+Status:      Wont fix
 Type:        Bug
 Package:     Class/Object related
 PHP Version: Irrelevant

 New Comment:

That might seem odd, but it seems consistent enough to me. It breaks
down one of two ways:



1. You call the constructor by instantiating an object with new. It
behaves like a constructor -- return values are ignored and a new object
instance is created.



2. You call the constructor by calling $object->__construct(). It
behaves like a method call, including return values being returned.



Basically, if you don't want __construct() to act like a method call,
don't call it like a method call.


Previous Comments:
------------------------------------------------------------------------
[2010-07-13 16:35:38] whistl0r+phpbug at googlemail dot com

Description:
------------
Please see the test script. This should be normal PHP 5.3 class with a
good OOP design.



In PHP it is possible, that I can call the constructor multiple times,
for example:



$person = new \My\Person('Jens', 'Mander');

echo sprintf('Name: %s %s', $person->getName(), $person->getSurname());
// Will output "Name: Jens Mander"



$person->__construct('John', 'Doe');

echo sprintf('Name: %s %s', $person->getName(), $person->getSurname());
// Will output "Name: John Doe"



In my understanding, it is unexpected, that

1) you can access the constructor method in an instantiated object. The
constructor should only instantiate the object - when you have the
object, there is no need to call it again. If you need something to
"reset" your object state, you should implement such a method.



2) If you can call the constructor again, that it will change the object
and *not* return a new instance.



For example:

If you add a "return new \stdClass();" line to your constructor, it will
still change the instance you called it from, but now it will also
return a "stdClass" - that's inconsistent, isn't it?

Test script:
---------------
<?php

namespace My;



class Person

{

  protected $_name = null;

  

  protected $_surname = null;

  

  /**

  * Constructor.

  * 

  * @param  string OPTIONAL $name

  * @param  string OPTIONAL $surname

  * @return \My\Person

  */

  public function __construct($name = null, $surname = null)

  {

    if ($name !== null)

    {

        $this->setName($name);

    }

    

    if ($surname !== null)

    {

        $this->setSurname($surname);

    }

  }

  

  /**

  * Returns the name.

  * 

  * @return null|string Null, when no name was set

  */

  public function getName()

  {

    return $this->_name;

  }

  

  /**

  * Returns the surname.

  * 

  * @return null|string Null, when no name was set

  */

  public function getSurname()

  {

    return $this->_surname;

  }

  

  /**

  * Set the name.

  * 

  * @param  string $name

  * @return \My\Person Provides fluent interface

  * @throws \Exception

  */

  public function setName($name)

  {

    if (!is_string($name) || empty($name))

    {

      throw new \Exception('Name cannot be empty and must be a
string!');

    }

    

    $this->_name = $name;

    

    

    return $this;

  }

  

  /**

  * Set the surname.

  * 

  * @param string $name

  * @return \My\Person Provides fluent interface

  * @throws \Exception When $name isn't a string or empty

  */

  public function setSurname($name)

  {

    if (!is_string($name) || empty($name))

    {

      throw new \Exception('Name cannot be empty and must be a
string!');

    }

    

    $this->_surname = $name;

    

    

    return $this;

  }

}

Expected result:
----------------
- FATAL error e.g. "Object already constructed!"



- The __construct() call should return a *new* object.

Actual result:
--------------
The __construct() method will work on the object, from where you called
it.


------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=52330&edit=1

Reply via email to