doc-en icon indicating copy to clipboard operation
doc-en copied to clipboard

is_callable() does actually work for constructors in context

Open JakeQZ opened this issue 1 year ago • 1 comments

https://www.php.net/manual/en/function.is-callable.php says

is_callable() reports constructors as not being callable.

This is not true. At least not when called from a context where the constructor is callable, e.g. a child class constructor.

    <?php
      class ParentWithConstructor
      {
        public function __construct()
        {
          ?>
            ParentWithConstructor::__construct() was called<br/>
          <?php
        }
      }
      class ParentWithoutConstructor
      {
      }
      class ChildOfParentWithConstructor extends ParentWithConstructor
      {
        public function __construct()
        {
          $isCallable = \is_callable([parent::class, '__construct']);
          ?>
            <?=static::class?>::__construct() was called<br/>
            $isCallable = <?=$isCallable?><br />
          <?php
          if ($isCallable) {
            parent::__construct();
          }
        }
      }
      class ChildOfParentWithoutConstructor extends ParentWithoutConstructor
      {
        public function __construct()
        {
          $isCallable = \is_callable([parent::class, '__construct']);
          ?>
            <?=static::class?>::__construct() was called<br/>
            $isCallable = <?=$isCallable?><br />
          <?php
          if ($isCallable) {
            parent::__construct();
          }
        }
      }
    ?>
    <p>
      <?php
        new ChildOfParentWithConstructor();
      ?>
    </p>
    <p>
      <?php
        new ChildOfParentWithoutConstructor();
      ?>
    </p>
    <p>
      PHP version <?=PHP_VERSION?>
    </p>

The output was

ChildOfParentWithConstructor::__construct() was called $isCallable = 1 ParentWithConstructor::__construct() was called

ChildOfParentWithoutConstructor::__construct() was called $isCallable =

PHP version 7.3.11

This needs to be clarified, rather than having a blanket statement saying it does not work, when in fact it does in the right situations.

JakeQZ avatar Oct 07 '22 13:10 JakeQZ

Actually, the usefulness of that example is doubtful, especially since that as of PHP 8.0.0 that is to be expected (calling non-static functions statically is no longer supported). And of course, a constructor is callable when checked on an object of the respective type, and also in the cases you've mentioned (https://3v4l.org/rCodI).

cmb69 avatar Oct 07 '22 13:10 cmb69