Skip to content

call_user_func special function optimization unsound with strict_types #18591

Open

Description

@ndossche

Description

The following code:

<?php
declare(strict_types=1);

namespace Foo;

// strlen() will be called with strict_types=0, so this is legal.
var_dump(call_user_func('strlen', false));

// Called with strict_types=1
var_dump(\call_user_func('strlen', false));

Resulted in this output:

int(0)

Fatal error: Uncaught TypeError: strlen(): Argument #1 ($string) must be of type string, false given in /in/bcCZ4:10
Stack trace:
#0 /in/bcCZ4(10): strlen(false)
#1 {main}
  thrown in /in/bcCZ4 on line 10

But I expected this output instead:

Well, not sure, it should be consistent I suppose

PHP Version

8.3+

Operating System

No response

Activity

  1. mvorisek commented on May 19, 2025

    @mvorisek
    Contributor

    present since eternity - https://3v4l.org/kqsCu

    IMO the 1st behaviour is more correct is sense how strict_types are handled in other functions.

  2. Girgias commented on May 19, 2025

    @Girgias
    Member

    No, the consistent way is to use weak mode. As it is the engine performing the function call and those are always in weak mode.

  3. kkmuffme commented on Sep 3, 2025

    @kkmuffme

    Basically reported 7 years ago: https://bugs.php.net/bug.php?id=72248
    (with slight nuance/difference)

    IMO the 1st behaviour is more correct is sense how strict_types are handled in other functions.
    No, the consistent way is to use weak mode. As it is the engine performing the function call and those are always in weak mode.

    While it would make sense logically, it would rip huge holes into the type system, since call_user_func* doesn't do anything by itself, but is just a wrapper.
    I think treating it as if the original function is called directly instead of via call_user_func - which is how it works currently if no namespace is used - is the more sensible (and stricter) choice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions