php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #49203 call_user_func_array when calling a parent constructor not from a user class
Submitted: 2009-08-10 03:57 UTC Modified: 2013-02-18 00:33 UTC
From: magicaltux@php.net Assigned:
Status: No Feedback Package: Scripting Engine problem
PHP Version: 5.3.0 OS: Linux x86_64
Private report: No CVE-ID: None
 [2009-08-10 03:57 UTC] magicaltux@php.net
Description:
------------
When using:

call_user_func_array(array('parent', '__construct'), $var);

This works if the parent is a user-defined class, but not if it's an extension-provided class (the extended constructor gets called twice).

This is not easy to explain, see attached reproduce code for more details.


My initial code was (in a class extending mysqli):

        private function __construct($params) {
                call_user_func_array(array('parent', '__construct'), $params);
                $this->set_charset('utf8');
        }

Using this instead awfully fixes the problem:
parent::__construct($params[0], $params[1], $params[2], $params[3]);

Note that this wasn't possible in PHP 5.2.x

Warning: call_user_func_array(): First argument is expected to be a valid callback, 'parent::__construct' was given in foo.php on line 5


Reproduce code:
---------------
<?php

class B extends mysqli {
	public function __construct($var) {
		echo "here\n";
		call_user_func_array(array('parent', '__construct'), $var);
	}
}

$x = new B(array('localhost', 'root'));


Expected result:
----------------
here

Actual result:
--------------
here
here

Warning: call_user_func_array() expects parameter 2 to be array, string given in foo.php on line 6


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-08-10 07:48 UTC] colder@php.net
The problem is not about internal classes, but classes not defining a __construct:

class A {

}
class B extends A {
    public function __construct() {
        echo "here\n";
        call_user_func(array('parent', '__construct'));
    }
}

$x = new B;

seems like is_callable() returns true on array('parent', '__construct') and shouldn't.
 [2009-08-10 08:29 UTC] magicaltux@php.net
Ok, mysqli's contructor is not named "__construct"

    Method [ <internal:mysqli, ctor> public method mysqli ] {
    }

Still, one would expect that calling call_user_func_array(array('parent', '__construct'), ...) acts the same as parent::__construct(...) (which works). I guess somewhere the call to __construct must be redirected to the ctor...
 [2011-01-01 22:47 UTC] jani@php.net
-Status: Open +Status: Feedback -Package: Feature/Change Request +Package: Scripting Engine problem
 [2011-01-01 22:47 UTC] jani@php.net
What is the FR here? Re-type if this is actually a bug. And rewrite the summary, it isn't very informative. And update PHP version if this is still an issue.
 [2011-01-01 22:57 UTC] magicaltux@php.net
Rather simple: if a given class's constructor is named with the class name (and 
not "__construct"), and is extended, then from the extending class:

- calling parent::__construct() will work
- calling call_user_func_array(array('parent', '__construct'), array()) won't

The behaviour would usually be assumed to be the same, but it is not.
 [2013-02-18 00:33 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 14:01:32 2024 UTC