Php 使用call\u user\u func\u数组调用子类时未激发扩展类构造函数

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类中,我有一个构造函数,用于设置数据库连接(我添加

我有一个非常奇怪的问题,我不知道这是否是由于调用用户函数数组引起的

PHP5.4上的测试

当前设置

例如,我有一个
AuthController
类,它扩展了名为
controller
的基本控制器:

类AuthController扩展控制器
{
公共函数登录(){
返回响应::json(数组('error'=>false,'message'=>I'm inAuthController@login'));
}
}
在extended
Controller
类中,我有一个构造函数,用于设置数据库连接(我添加了一个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 in
call\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-in
call\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
未定义任何构造函数。它继承受保护的父类构造函数。因为它不是公共的,所以不能调用它,也不能创建对象;脚本抛出了一个