旧式和新式PHP构造函数之间的区别

时间:2016-01-02 12:07:51

标签: php oop php4

有人能告诉我"旧式"对象构造函数不同于" new-style"构造函数?我正在学习PHP OOP,我想知道我何时阅读旧语法和新语法,并且更好地了解OOP随着时间的推移如何改变。

新款式

class aObject
{
    public $name;

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

1 个答案:

答案 0 :(得分:8)

“旧”构造函数语法指的是PHP4。 PHP4的最后一个版本是在2008年,PHP5的第一个版本是在2004年。这是一个旧式类和一个新式类的例子。

旧(PHP4)

<?php

class MyOldClass
{
    var $foo;

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

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

新(PHP5 +)

<?php

class MyNewClass
{
    var $foo;

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

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

你会注意到这里的一些事情。最重要的变化是命名构造函数的规范方法已从ClassName()更改为__construct()。这为所有类构造函数提供了相同的,可预测的名称 - 这是必要的便利。想象一下,你有一个名为ParentClass的班级,里面有20个孩子,每个孩子都有自己的构造函数。如果要从每个子类调用父构造函数,则调用ParentClass::ParentClass()。如果要更改ParentClass的名称,则必须更改所有20个构造函数调用。但是,使用新方法,您只需调用parent::__construct(),即使父类的名称发生更改,它也会一直有效。

与此更改相关,PHP5还引入了类析构函数__destruct()),它在对象被销毁时被调用(与构造函数相反)。

另一个关键变化是PHP5引入了method and property visibility,它允许对类的方法和属性进行某种“访问控制”。只能从类或其子项之外的上下文中访问标记为public的方法和属性。以下是这方面的例子:

<?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;
}

现在,方法的工作方式完全相同。您可以将类中的函数(方法)标记为publicprivateprotected。在PHP4中,所有类成员都隐式public。同样,构造函数(__construct())也可以是publicprivateprotected

如果某个类不包含 public 构造函数,则无法通过类之外的代码(或其子代,protected)实例化。那你怎么用这样的课呢?嗯,static methods,当然:

<?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);
    }
}

要从其他地方实例化此类,您可以调用:

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

当您需要在调用构造函数之前预处理输入,或者需要多个采用不同参数的构造函数时,这非常有用。

此方法命名__construct()以及以__开头的其他方法名称,例如__get()__set()__call()__isset()__unset()__toString()等称为magic methods

PHP5带来了很多dramatic changes,但很大程度上试图保持与PHP4代码的兼容性,因此仍然允许使用旧式构造函数。

PHP7现已在今年发布,没有对构造函数语法进行任何更改。 PHP7中唯一重要的class相关变化是允许使用匿名类(参见here)。

从PHP7开始,旧式构造函数are officially deprecated(引发E_DEPRECATED错误),将在PHP8中完全删除。