note 118032 added to language.types.callable

From: Date: Mon, 21 Sep 2015 19:45:55 +0000
Subject: note 118032 added to language.types.callable
Groups: php.notes 
Request: Send a blank email to php-notes+get-203831@lists.php.net to get a copy of this message
I needed a function that would determine the type of callable being passed, and, eventually, normalized it to some extent. Here's what I came up with: <?php /** * The callable types and normalizations are given in the table below: * * Callable | Normalization | Type * ---------------------------------+---------------------------------+-------------- * function (...) use (...) {...} | function (...) use (...) {...} | 'closure' * $object | $object | 'invocable' * "function" | "function" | 'function' * "class::method" | ["class", "method"] | 'static' * ["class", "parent::method"] | ["parent of class", "method"] | 'static' * ["class", "self::method"] | ["class", "method"] | 'static' * ["class", "method"] | ["class", "method"] | 'static' * [$object, "parent::method"] | [$object, "parent::method"] | 'object' * [$object, "self::method"] | [$object, "method"] | 'object' * [$object, "method"] | [$object, "method"] | 'object' * ---------------------------------+---------------------------------+-------------- * other callable | idem | 'unknown' * ---------------------------------+---------------------------------+-------------- * not a callable | null | false * * If the "strict" parameter is set to true, additional checks are * performed, in particular: * - when a callable string of the form "class::method" or a callable array * of the form ["class", "method"] is given, the method must be a static one, * - when a callable array of the form [$object, "method"] is given, the * method must be a non-static one. * */ function callableType($callable, $strict = true, callable& $norm = null) { if (!is_callable($callable)) { switch (true) { case is_object($callable): $norm = $callable; return 'Closure' === get_class($callable) ? 'closure' : 'invocable'; case is_string($callable): $m = null; if (preg_match('~^(?<class>[a-z_][a-z0-9_]*)::(?<method>[a-z_][a-z0-9_]*)$~i', $callable, $m)) { list($left, $right) = [$m['class'], $m['method']]; if (!$strict || (new \ReflectionMethod($left, $right))->isStatic()) { $norm = [$left, $right]; return 'static'; } } else { $norm = $callable; return 'function'; } break; case is_array($callable): $m = null; if (preg_match('~^(:?(?<reference>self|parent)::)?(?<method>[a-z_][a-z0-9_]*)$~i', $callable[1], $m)) { if (is_string($callable[0])) { if ('parent' === strtolower($m['reference'])) { list($left, $right) = [get_parent_class($callable[0]), $m['method']]; } else { list($left, $right) = [$callable[0], $m['method']]; } if (!$strict || (new \ReflectionMethod($left, $right))->isStatic()) { $norm = [$left, $right]; return 'static'; } } else { if ('self' === strtolower($m['reference'])) { list($left, $right) = [$callable[0], $m['method']]; } else { list($left, $right) = $callable; } if (!$strict || !(new \ReflectionMethod($left, $right))->isStatic()) { $norm = [$left, $right]; return 'object'; } } } break; } $norm = $callable; return 'unknown'; } $norm = null; return false; } ?> Hope someone else finds it useful. ---- Server IP: 72.52.91.14 Probable Submitter: 201.231.251.179 ---- Manual Page -- http://php.net/manual/en/language.types.callable.php Edit -- https://master.php.net/note/edit/118032 Del: integrated -- https://master.php.net/note/delete/118032/integrated Del: useless -- https://master.php.net/note/delete/118032/useless Del: bad code -- https://master.php.net/note/delete/118032/bad+code Del: spam -- https://master.php.net/note/delete/118032/spam Del: non-english -- https://master.php.net/note/delete/118032/non-english Del: in docs -- https://master.php.net/note/delete/118032/in+docs Del: other reasons-- https://master.php.net/note/delete/118032 Reject -- https://master.php.net/note/reject/118032 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#203831) next »