Php 使用call\u user\u func\u数组调用子类时未激发扩展类构造函数
我有一个非常奇怪的问题,我不知道这是否是由于调用用户函数数组引起的 PHP5.4上的测试 当前设置 例如,我有一个Php 使用call\u user\u func\u数组调用子类时未激发扩展类构造函数,php,constructor,Php,Constructor,我有一个非常奇怪的问题,我不知道这是否是由于调用用户函数数组引起的 PHP5.4上的测试 当前设置 例如,我有一个AuthController类,它扩展了名为controller的基本控制器: 类AuthController扩展控制器 { 公共函数登录(){ 返回响应::json(数组('error'=>false,'message'=>I'm inAuthController@login')); } } 在extendedController类中,我有一个构造函数,用于设置数据库连接(我添加
AuthController
类,它扩展了名为controller
的基本控制器:
类AuthController扩展控制器
{
公共函数登录(){
返回响应::json(数组('error'=>false,'message'=>I'm inAuthController@login'));
}
}
在extendedController
类中,我有一个构造函数,用于设置数据库连接(我添加了一个var_dump+exit用于测试):
类控制器
{
受保护$db;
受保护函数_u构造(){
$database=Config::env('database');
变量转储($数据库);
出口
}
}
现在要调用AuthController
,我使用call\u user\u func\u数组
调用用户函数数组(数组($controller,$route['action'),$data);
现在应该发生什么:
call_user_func_array(array($this, 'parent::__construct'), $args);
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method OtherSubClass::test() should not be called statically in /var/www/html/test/test1.php on line 22
in test
Fatal error: Call to protected BaseClass::__construct() from invalid context in /var/www/html/test/test1.php on line 24
应该发生的是,控制器的构造函数应该已经启动,在屏幕上生成转储并退出执行
改为:
call_user_func_array(array($this, 'parent::__construct'), $args);
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method OtherSubClass::test() should not be called statically in /var/www/html/test/test1.php on line 22
in test
Fatal error: Call to protected BaseClass::__construct() from invalid context in /var/www/html/test/test1.php on line 24
相反,我实际上是从AuthController
的登录方法response::json()
获得响应
控制器的构造函数永远不会被激发
我很难理解为什么它不起作用,因为PHP手册指出,构造函数会在每个新对象实例上被激发,如果父类有一个构造函数,而子类没有覆盖它,则会自动调用父类构造函数
调用\u user\u func\u数组
不是自动启动父类构造函数,还是我完全误解了PHP构造函数?作为
PHP5允许开发人员为类声明构造函数方法。具有构造函数方法的类对每个新创建的对象调用此方法,因此它适用于对象在使用之前可能需要的任何初始化
注意:如果子类定义了构造函数,则不会隐式调用父构造函数。要运行父构造函数,需要在子构造函数中调用父::\u construct()。如果子类没有定义构造函数,那么它可以像普通类方法一样从父类继承(如果它没有声明为private)
示例#1使用新的统一构造函数
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
?>
编辑1
请参见以下示例:
class BaseClass {
protected function __construct() {
print "In BaseClass constructor<br />";
}
}
//class SubClass extends BaseClass {
// function __construct() {
// parent::__construct();
// print "In SubClass constructor<br />";
// }
//}
class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
function test(){
echo 'in test';
}
}
call_user_func_array(array('OtherSubClass', 'test'), array()); //
// In BaseClass constructor
$obj = new OtherSubClass(); //produce fatel error
因此,如果字符串give incall\u user\u func\u array
函数,那么它将生成out put,但带有严格的标准错误,并且在创建类的新对象时会产生致命错误。作为PHP文档
PHP5允许开发人员为类声明构造函数方法。具有构造函数方法的类对每个新创建的对象调用此方法,因此它适用于对象在使用之前可能需要的任何初始化
注意:如果子类定义了构造函数,则不会隐式调用父构造函数。要运行父构造函数,需要在子构造函数中调用父::\u construct()。如果子类没有定义构造函数,那么它可以像普通类方法一样从父类继承(如果它没有声明为private)
示例#1使用新的统一构造函数
<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
?>
编辑1
请参见以下示例:
class BaseClass {
protected function __construct() {
print "In BaseClass constructor<br />";
}
}
//class SubClass extends BaseClass {
// function __construct() {
// parent::__construct();
// print "In SubClass constructor<br />";
// }
//}
class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
function test(){
echo 'in test';
}
}
call_user_func_array(array('OtherSubClass', 'test'), array()); //
// In BaseClass constructor
$obj = new OtherSubClass(); //produce fatel error
因此,如果字符串give-incall\u user\u func\u array
函数,那么它会产生out-put,但有严格的标准错误,并且在创建类的新对象时会产生致命错误。我将在这里暗中试探一下,并说您实际上正在这样做:
call_user_func_array(array('AuthController', 'login'), $data);
换句话说,您没有将实例传递给call\u user\u func
,而是传递字符串'AuthController'
。这意味着您的方法将被静态调用。如果您启用了错误报告和/或严格的错误报告,您应该会看到一个通知,警告您静态调用非静态方法
问题是(可能)你从来没有实际实例化过你的类,所以从来没有运行过构造函数call\u user\u func
不会为您实例化它。您需要自己做这件事:
call_user_func_array(array(new $controller, $route['action']), $data);
// ^^^
我在这里暗中试探一下,说你实际上是在这样做的:
call_user_func_array(array('AuthController', 'login'), $data);
换句话说,您没有将实例传递给call\u user\u func
,而是传递字符串'AuthController'
。这意味着您的方法将被静态调用。如果您启用了错误报告和/或严格的错误报告,您应该会看到一个通知,警告您静态调用非静态方法
问题是(可能)你从来没有实际实例化过你的类,所以从来没有运行过构造函数call\u user\u func
不会为您实例化它。您需要自己做这件事:
call_user_func_array(array(new $controller, $route['action']), $data);
// ^^^
请记住,构造函数是在创建新对象时调用的特殊方法。不调用任何构造函数,因为它不创建任何新对象
call_user_func_array(array($controller, $route['action']), $data);
根据您的问题,我假设$controller
是AuthController
类型的对象。当您将它传递给call\u user\u func\u array()
时,它已经被创建。它的构造函数是在创建对象时调用的
但是等一下?什么构造器?类AuthController
未定义任何构造函数。它继承受保护的父类构造函数。因为它不是公共的,所以不能调用它,也不能创建对象;脚本抛出了一个