Php 我们可以在同一个类中声明_构造函数和类名构造函数吗?
我们可以在同一个类中声明_构造函数和类名构造函数吗 如果是,则在创建对象时会调用这两者。还有什么顺序Php 我们可以在同一个类中声明_构造函数和类名构造函数吗?,php,oop,constructor,Php,Oop,Constructor,我们可以在同一个类中声明_构造函数和类名构造函数吗 如果是,则在创建对象时会调用这两者。还有什么顺序 如果只有一个会被呼叫,那么是哪一个?为什么呢?在这个答案的后面,你会发现你的个人问题以一种方便的列表格式得到了回答。但首先,请允许我向您提供一些一般信息、文档引用、链接和代码片段,它们将帮助您更好地理解所有这些 您可以定义这两种类型的构造函数,但PHP不会同时将这两种方法视为构造函数,因为: 为了向后兼容,如果PHP5找不到给定类的_construct()函数,并且该类没有从父类继承_const
如果只有一个会被呼叫,那么是哪一个?为什么呢?在这个答案的后面,你会发现你的个人问题以一种方便的列表格式得到了回答。但首先,请允许我向您提供一些一般信息、文档引用、链接和代码片段,它们将帮助您更好地理解所有这些 您可以定义这两种类型的构造函数,但PHP不会同时将这两种方法视为构造函数,因为: 为了向后兼容,如果PHP5找不到给定类的_construct()函数,并且该类没有从父类继承_construct()函数,它将根据类的名称搜索旧式构造函数。实际上,这意味着唯一存在兼容性问题的情况是,该类有一个名为_construct()的方法,该方法用于不同的语义 因此,如果未找到
\u construct
方法,则同名构造函数是一个后备方法。它的主要目的是保持与过时的PHP版本的向后兼容性,因此它是(PHP7将在今年晚些时候发布)的一种功能。PHP7将温和地反对这个“特性”,它将从PHP8中完全删除
从PHP5.3.3开始,与命名空间类名的最后一个元素同名的方法将不再被视为构造函数。此更改不会影响非命名空间的类
在PHP5.3.3及更高版本中,如果您至少使用名称空间,那么相同名称的构造函数根本不起作用
简言之:
class Foo
{
public function Foo()
{
//this is the constructor
}
}
但是:
还值得注意的是,在同一个类中定义两个可能的构造函数会发出E_STRICT
通知。但再举几个例子
或:
及
所以基本上:
- 你能定义一个同名的构造函数吗?是,如果类或其任何祖先上没有定义
方法。如果存在\u construct
方法,则同名构造函数将成为常规方法,PHP将发出\u构造函数
通知E\u STRICT
- 这两个方法都将被称为构造函数吗?否,如果存在
方法,则该方法为构造函数。否则,将调用具有类名的方法。为什么?由于PHP5支持\u构造
\u构造方法,PHP4构造方法是一种向后兼容的回退机制。回退永远不会优先于默认值,这就是为什么只调用
方法的原因。简单\u构造
- 定义这两种类型的构造函数会发出
通知(在PHP5中,如果PHP7看到PHP4样式的构造函数,则会发出E_STRICT
通知)E_DEPRECATED
- 如果您的类是命名空间的,则它取决于PHP版本5.3.3和更高版本,它将只使用
方法。鉴于我们目前使用的是版本5.6,而PHP7将于今年到期,我不会编写需要弃用PHP版本的代码\u construct
- PHP7即将到期,并且
\uu construct
取代,所以我会使用它。更多内容:使用基于名称的构造函数机制非常容易出错,因为在继承链中的某个地方发现\uu构造
方法时,它们就会变成常规方法。使用这两种方法都会发出通知,这意味着
如果你真的想写,你可以想象,也许梦想着写一些东西,大致如下:
class Foo
{
private $constructed = false;
public function __construct()
{
if ($this->constructed === false)
{
$this->Foo();
}
}
public function Foo()
{
$this->constructed = true;
//do constructor stuff...
}
}
将继承添加到混合中,您将得到以下结果:
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}();
}
}
}
}
但老实说,那真是一件愚蠢的事,不是吗?但是,使用这种方法并不能解决这些通知,因此您仍然必须考虑这些通知。如果您的子类构造函数需要参数,那么您的构造函数(至少在第二种情况下)违反了liskov原则(继承的契约违约)。进一步回答这个问题,您会发现您的问题以方便的列表格式得到了回答。但首先,请允许我向您提供一些一般信息、文档引用、链接和代码片段,它们将帮助您更好地理解所有这些 您可以定义这两种类型的构造函数,但PHP不会同时将这两种方法视为构造函数,因为: 为了向后兼容,如果PHP5找不到给定类的_construct()函数,并且该类没有从父类继承_construct()函数,它将根据类的名称搜索旧式构造函数。实际上,这意味着唯一存在兼容性问题的情况是,该类有一个名为_construct()的方法,该方法用于不同的语义 因此,如果未找到
\u construct
方法,则同名构造函数是一个后备方法。它的主要目的是保持与过时的PHP版本的向后兼容性,因此它是(PHP7将在今年晚些时候发布)的一种功能。PHP7将温和地反对这个“特性”,它将从PHP8中完全删除
从PHP5.3.3开始,与命名空间类名的最后一个元素同名的方法将不再被视为构造函数。此更改不会影响非命名空间的类
在PHP5.3.3及更高版本中,如果您至少使用名称空间,那么相同名称的构造函数根本不起作用
简言之:
class Foo
{
public function Foo()
{
//this is the constructor
}
}
但是:
还值得注意的是,在同一个类中定义两个可能的构造函数会发出E_STRICT
通知。但再举几个例子
或:
及
所以基本上:
- 你能定义一个同名的构造函数吗?是,如果类或其任何祖先上没有定义
方法。如果一个\u construct
\uuuu con
class Foo { private $constructed = false; public function __construct() { if ($this->constructed === false) { $this->Foo(); } } public function Foo() { $this->constructed = true; //do constructor stuff... } }
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}(); } } } }
<?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 } } ?>