GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Downloads
  • Documentation
  • Get Involved
  • Help
  • Getting Started
  • Introduction
  • A simple tutorial
  • Language Reference
  • Basic syntax
  • Types
  • Variables
  • Constants
  • Expressions
  • Operators

This view

  • Original page
  • New address

GeezerVison is showing www.php.net — PHP: Closure::fromCallable - Manual

PHP 8.6.0 RC5 available for testing
    Closure::getCurrent »
    « Closure::call
    • Preface
    • Language Reference
    • Predefined Interfaces and Classes
    • Closure

    Closure::fromCallable

    (PHP 7 >= 7.1.0)

    Closure::fromCallable — Converts a callable into a closure

    Description

    public static function Closure::fromCallable(callable $callback): Closure

    Create and return a new anonymous function from given callback using the current scope. This method checks if the callback is callable in the current scope and throws a TypeError if it is not.

    Note:

    As of PHP 8.1.0, First class callable syntax has the same semantics as this method.

    Parameters

    callback

    The callable to convert.

    Return Values

    Returns the newly created Closure or throws a TypeError if the callback is not callable in the current scope.

    See Also

    • Anonymous functions
    • First class callable syntax

    Found A Problem?

    Learn How To Improve This Page • Submit a Pull Request • Report a Bug
    +add a note

    User Contributed Notes 3 notes

    up
    down
    11
    igorchernin at yahoo dot com ¶
    9 years ago
    It seems that the result of the "fromCallable" behaves a little bit different then an original Lambda function.
    
    class A {
        private $name;
        public function __construct($name)
        {
            $this->name = $name;
        }
    }
    
    // test callable
    function getName()
    {
          return $this->name;
    }
    $bob = new A("Bob");
    
    $cl1 = Closure::fromCallable("getName");
    $cl1 = $cl1->bindTo($bob, 'A');
    
    //This will retrieve: Uncaught Error: Cannot access private property A::$name 
    $result = $cl1();
    echo $result;
    
    //But for a Lambda function
    $cl2 = function() {
        return $this->name;
    };
    $cl2 = $cl2->bindTo($bob, 'A');
    $result = $cl2();
    
    // This will print Bob
    echo $result;
    up
    down
    6
    4-lom at live dot de ¶
    8 years ago
    Sadly, your comparison is incorrect.
    
    // The equivalent to
    $cl1 = Closure::fromCallable("getName");
    $cl1 = $cl1->bindTo($bob, 'A');
    
    // is most likely this
    $cl2 = function() {
        return call_user_func_array("getName", func_get_args());
    };
    $cl2 = $cl2->bindTo($bob, 'A');
    
    Executing one or the other Closure should result in the same access violation error you already postet.
    
    ----
    A simple PHP 7.0 polyfill could look like this:
    ----
    
    namespace YourPackage;
    
    /**
     * Class Closure
     *
     * @see \Closure
     */
    class Closure
    {
        /**
         * @see \Closure::fromCallable()
         * @param callable $callable
         * @return \Closure
         */
        public static function fromCallable(callable $callable)
        {
            // In case we've got it native, let's use that native one!
            if(method_exists(\Closure::class, 'fromCallable')) {
                return \Closure::fromCallable($callable);
            }
    
            return function () use ($callable) {
                return call_user_func_array($callable, func_get_args());
            };
        }
    }
    up
    down
    4
    nakerlund at gmail dot com ¶
    8 years ago
    I have two points:
    
    It is possible to use Closure::fromCallable to convert private/protected methods to closures and use them outside the class.
    
    Closure::fromCallable accepts late dynamic bindings using the keyword static if provided as a string. 
    
    My code below demonstrate how a private static method can be used as a callback in a function outside the class.
    
    <?php
    function myCustomMapper ( Callable $callable, string $str ): string {
      return join(' ', array_map( $callable, explode(' ', $str) ) );
    }
    
    class MyClass {
    
        public static function mapUCFirst ( string $str ): string {
            $privateMethod = 'static::mapper';
            $mapper = Closure::fromCallable( $privateMethod );
            return myCustomMapper( $mapper, $str );
        }
        private static function mapper ( string $str ): string {
            return ucfirst( $str );
        }
    
    }
    
    echo MyClass::mapUCFirst('four little uncapitalized words');
    // Prints: Four Little Uncapitalized Words
    ?>
    +add a note
    • Closure
      • _​_​construct
      • bind
      • bindTo
      • call
      • fromCallable
      • getCurrent
    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.