8

Could someone tell me how the "old-style" object constructor is different from the "new-style" constructor? I'm learning PHP OOP, and I want to know when I'm reading old syntax vs new syntax, and better understand how OOP has changed in PHP over time.

New Style

class aObject
{
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }
}
Will
  • 24,082
  • 14
  • 97
  • 108
White Lotus
  • 353
  • 2
  • 6
  • 16
  • 1
    The difference is that the old object used a method with the same name of the class as a constructor, the new object uses a "magic" method called `__construct()`.... but old really is old now, has been deprecated for nearly 10 years and is now completely replaced by the new method – Mark Baker Jan 02 '16 at 12:10
  • @Mark Baker Thanks, so it deviated away from C++ construct? – White Lotus Jan 02 '16 at 12:12
  • This is all clearly explained in the documentation! Why don't you simply read it? – arkascha Jan 02 '16 at 12:13
  • 1
    Because the PHP website is blocked? Our school wants us to read from textbooks before going online. Why StackOverflow isn't blocked beats me. – White Lotus Jan 02 '16 at 12:14
  • 4
    Schools never cease to amaze me, wonder why they keep doing silly stuff like that – JimL Jan 02 '16 at 12:16
  • They enjoy making us suffer. The C++ Reference page is blocked also, along with a long list of other would be useful resources. – White Lotus Jan 02 '16 at 12:17
  • But it's also why schools don't produce good students, they have this insistence on teaching pupils (often out of date techniques) while handicapping them so they can't learn how to do it properly – Mark Baker Jan 02 '16 at 12:17
  • 1
    proxy around that restriction and read the php manual as one should – Alex Andrei Jan 02 '16 at 12:20
  • 2
    @WhiteLotus - Don't let your school's internet blockers put you off from learning.... keep fighting to learn the best you can, not simply what your teachers insist on limiting you to – Mark Baker Jan 02 '16 at 12:20
  • They claim that they are teaching us how the core concepts but they are often out of date to begin with. This is where the public library is your friend, except you can't access during school hours... I wonder if I can tunnel a connection to a computer that's nonrestrictive. – White Lotus Jan 02 '16 at 12:20
  • There is no reason to close-vote this question, whoever did. It is valid, does not seem to be a duplicate, is not too-broad, and is not opinion-based. A similar question for Python has 464 upvotes as of current. This is a great question. – Will Jan 04 '16 at 07:19

1 Answers1

12

The "old" constructor syntax is referring to PHP4. The last release of PHP4 was in 2008, and the first release of PHP5 was in 2004. This is an example of an old-style class and a new-style class.

Old (PHP4)

<?php

class MyOldClass
{
    var $foo;

    function MyOldClass($foo)
    {
        $this->foo = $foo;
    }

    function notAConstructor()
    {
        /* ... */
    }
}

New (PHP5+)

<?php

class MyNewClass
{
    var $foo;

    public function __construct($foo)
    {
        $this->foo = $foo;
    }

    public function notAConstructor()
    {
        /* ... */
    }
}

You'll notice a couple of things here. The most significant change is that the canonical way to name a constructor has changed from ClassName() to __construct(). This gives all class constructors the same, predictable name--a necessary convenience. Imagine you had a class called ParentClass with 20 children, each with their own constructors. If you wanted to call the parent constructor from each child class, you'd call ParentClass::ParentClass(). If you wanted to change the name of ParentClass, you'd have to change all 20 constructor calls. But, with the new method, you'd just call parent::__construct(), which would always work, even when the parent class's name changes.

Related to this change, PHP5 also introduced class destructors (__destruct()), which is called when an object is destroyed (the opposite of a constructor).

Another key change is that PHP5 introduced method and property visibility which allows a sort of "access control" for methods and properties of the class. Only methods and properties marked public cam be accessed from contexts outside of the class or its children. Here are examples of this:

<?php

class StackOverflow
{
    /* This can be accessed from anywhere.
     *
     * You can access it from outside the class:
     *     $so = new StackOverflow();
     *     $so->publicProperty = 10;
     *     echo $so->publicProperty;
     * 
     * Or from inside the class:
     *     $this->publicProperty = 5;
     *     echo $this->publicProperty;
     */
    public $publicProperty = 1;

    /* This can be accessed only from methods inside this class.
     *
     *     $this->privateProperty = 5;
     *     echo $this->privateProperty;
     * 
     * You cannot access it from outside the class, as above.
     * Private properties cannot be accessed from child classes,
     * either.
     */
    private $privateProperty = 2;

    /* This can be accessed only from methods inside this class,
     * OR a child-class.
     *
     *     $this->protectedProperty = 5;
     *     echo $this->protectedProperty;
     * 
     * You cannot access it from outside the class, as with public.
     * You can, however, access it from a child class. 
     */
    protected $protectedProperty = 3;
}

Now, methods work the exact same way. You can mark a function (method) within a class as public, private, or protected. In PHP4, all class members were implicitly public. Similarly, a constructor (__construct()), can also be public, private, or protected!

If a class does not contain a public constructor, it cannot be instantiated by code outside of the class (or, its children, for protected). So how would you use such a class? Well, static methods, of course:

<?php

class ClassWithPrivateConstructor
{
    private $foo;

    private function __construct($foo)
    {
        $this->foo = $foo;
    }

    public static function fromBar($bar)
    {
        $foo = do_something_to($bar);

        return new self($foo);
    }
}

To instantiate this class from somewhere else, you'd call:

$obj = ClassWithPrivateConstructor::fromBar($bar);

This can be useful when you need to pre-process input before calling the constructor, or when you need multiple constructors that take different parameters.

This method names, __construct(), and other method names that begin with __, like __get(), __set(), __call(), __isset(), __unset(), __toString(), etc. are called magic methods.

PHP5 brought a lot of dramatic changes, but largely tried to maintain compatibility with PHP4 code, and thus, old-style constructors were still allowed.

PHP7 has now been released this year, with no changes to constructor syntax. The only significant class-related change in PHP7 was to allow the use of Anonymous Classes (see here).

As of PHP7, the old-style constructors are officially deprecated (raises E_DEPRECATED error), and will be removed entirely in PHP8.

Will
  • 24,082
  • 14
  • 97
  • 108