php / doc-en

English PHP documentation
508 stars 739 forks source link

What is the meaning of the second code example in the description of the `is_callable()` function #4147

Open mmalferov opened 1 day ago

mmalferov commented 1 day ago

The page say:

is_callable() reports constructors as not being callable.

And the code verify callability the __construct() through static callable-expression:

<?php

class Foo
{
    public function __construct() {}

    public function foo() {}
}

var_dump(
    is_callable(['Foo', '__construct']), // The static callable expression, as first entry is not object context
    is_callable(['Foo', 'foo'])
);

At the same time, the __construct() is callable actually:

<?php

class Foo
{
    public function __construct() {}

    public function foo() {}
}

var_dump(
    is_callable([new Foo(), '__construct']), // true
);
damianwadley commented 12 hours ago

The example is probably trying to say that you cannot use is_callable(["Foo", "__construct"]) as a way of knowing if the class can be created with new.

if (is_callable(["Foo", "__construct"])) { // always false
    $object = new Foo(); // will never happen
}

(instead, to know if a class can be constructed, you need to use reflection)

I agree that what it says now is confusing.

mmalferov commented 11 hours ago

Wow! How unpredictable human thought is :)

Maybe the example is trying to say that despite the fact that the value that the function returns in the in-out parameter callable_name when specifying the arguments $syntax_only = true and $callable_name, although it looks like indicating the availability of the method for static invocation, it does not actually allow the method to be called statically?

And the example should just be supplemented, for example, like this:

<?php

class Foo
{
    public function __construct() {}

    public function foo() {}
}

var_dump(
    // Verify, if the '__construct' might be a callable
    is_callable(['Foo', '__construct'], true, $callable_name), // true

    // Get the __construct() callable name
    $callable_name, // Returns "Foo::__construct", that looks like callable static method

    // Verify, if the '__construct' is available as callable static method
    is_callable(['Foo', '__construct']), // false

    // The same with the foo() non-static method
    is_callable(['Foo', 'foo'], true, $callable_name), // true
    $callable_name, // Foo::foo
    is_callable(['Foo', 'foo']), // Return false with static callable expression

    // Opposite the static callable expression, the non-static methods are callables
    is_callable([new Foo(), '__construct']), // true
    is_callable([new Foo(), 'foo']), // true
);

If this is the purpose of the second example, then the title of the example should be changed to something like: is_callable() with $syntax_only example.

Anyway, the example should be changed so that it becomes clear and specific, and directly says "why" it appeared on the page ;)