PHP7 构造函数类名

29

我的Laravel 4.2应用程序在PHP5下工作良好。自从我安装了一个运行PHP7的新vagrant box后,只要我运行一个函数名与类名相同(关系函数)的模型,就会出现错误,像这样:

<?php

use Illuminate\Database\Eloquent\SoftDeletingTrait;

class Participant extends \Eloquent
{

    use SoftDeletingTrait;

    [...]

    public function participant()
    {
        return $this->morphTo();
    }

    [...]    

}

我得到了以下错误信息:

在未来的PHP版本中,类名与其同名的方法将不再作为构造函数;Participant有一个已弃用的构造函数(视图:...)

直到今天我才知道,在PHP4中,与类名相同的方法是类的构造函数。嗯,我真是个糟糕的程序员...但在这种情况下,根据我对PHP7中正在发生的事情的理解,他们更正了我的错误,因为我从来没有想过使用这个函数作为构造函数,因为它仅定义了Eloquent关系。

但是,我该如何摆脱这个消息呢?就我所了解的,我的代码在PHP4中存在错误,但在PHP7中不存在错误,对吧?如果不是必要的,我不想重构这个函数,因为它在多个地方被使用。

有人能解释一下我做错了什么以及为什么旧版本的PHP可以工作吗?

谢谢!


"嗯,我真的是个糟糕的程序员..." :-D - Stack Underflow
2个回答

50

我的理解是,在PHP4中我的代码有缺陷,但在PHP7中没有了,对吗?

不完全正确。PHP7仍然支持PHP4风格的构造函数,只是已被弃用,并会触发一个过时(Deprecated)警告。

你需要做的是定义一个__construct方法,即使是一个空的方法,这样php4的构造函数方法就不会在新创建的类实例上被调用。

class foo
{
    public function __construct()
    {
        // Constructor's functionality here, if you have any.
    }

    public function foo()
    {
        // PHP4-style constructor.
        // This will NOT be invoked, unless a sub-class that extends `foo` calls it.
        // In that case, call the new-style constructor to keep compatibility.
        self::__construct();
    }
}

new foo();

它在旧版PHP中运行良好,因为构造函数不会返回值。每次创建Participant实例时,您隐式调用participant方法,仅此而已。


太容易了!非常感谢,这正是我需要的! - Thomas M.
5
你好!这是一个部分解决方案。请查看 https://cweiske.de/tagebuch/php4-constructors-php7.htm。如果从子类中显式调用旧构造函数,则会失败。要完全解决问题,您必须将构造函数的功能移至新风格的构造函数(__construct)并从旧风格的构造函数中调用它(self::__construct();)。祝好!/ Ángel - Angel
感谢您指出这一点,@Angel。如果您愿意,您可以编辑我的答案并添加这个内容。 - Federkun
关于这个问题 - 为什么要使用 self::__construct() 而不是 $this->__construct()?在这种情况下,两者有什么区别吗? - But those new buttons though..
1
是的@billynoah,如果使用$this->__construct()可能会在任何潜在的子类中出现问题。这个是递归的,而这个则不是。 - Federkun

7

PHP 4风格的构造函数(与定义它们的类名相同的方法)已被弃用,并将在未来删除。如果一个PHP 4构造函数是类中唯一定义的构造函数,PHP 7将发出E_DEPRECATED警告。实现__construct()方法的类不受影响。

<?php
    class foo {
        function foo() {
            echo 'I am the constructor';
         }
     }
?>

You can keep your old constructor but you need to add a new construct like that:

use Illuminate\Database\Eloquent\SoftDeletingTrait;

class Participant extends \Eloquent
{

    use SoftDeletingTrait;

    [...]

    public function __construct()
    {
        return $this->morphTo();
    }

    public function participant()
    {
        return $this->morphTo();
    }

    [...]    

}


1
非常感谢!这正是我需要的。在我的情况下,只有构造函数应该为空,如@Federico所述。 - Thomas M.
1
一个构造函数,比如__construct(),永远不应该包含return语句。 - Tim B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接