Last active
December 20, 2015 04:18
-
-
Save jsor/6069419 to your computer and use it in GitHub Desktop.
Interfaces for functions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require __DIR__.'/function_interfaces.php'; | |
interface foo {} | |
interface interfaces { | |
function my_function(); | |
function my_function2(callable $callable, $string, \Traversable $traversable, foo $foo, $constant = DIRECTORY_SEPARATOR); | |
} | |
// True | |
var_dump(function_interfaces\function_implements(function () { | |
}, 'interfaces::my_function')); | |
// True - Empty interfaces are _always_ implemented | |
var_dump(function_interfaces\function_implements(function ($param) { | |
}, 'interfaces::my_function')); | |
// False | |
var_dump(function_interfaces\function_implements(function () { | |
}, 'interfaces::my_function2')); | |
// True | |
var_dump(function_interfaces\function_implements(function (callable $callable, $string, \Traversable $traversable, foo $foo, $constant = DIRECTORY_SEPARATOR) { | |
}, 'interfaces::my_function2')); | |
// True - Parameter names don't matter | |
var_dump(function_interfaces\function_implements(function (callable $callable2, $string2, \Traversable $traversable2, foo $foo2, $constant2 = DIRECTORY_SEPARATOR) { | |
}, 'interfaces::my_function2')); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace function_interfaces; | |
// Inspired by https://github.com/ircmaxell/Protocol-Lib | |
function function_implements($function, $interface) | |
{ | |
$interfaceReflectionMethod = new \ReflectionMethod($interface); | |
$functionParameters = (new \ReflectionFunction($function))->getParameters(); | |
$checkParam = function($param1, $param2) { | |
foreach (array( | |
'isArray', | |
'isCallable', | |
'isDefaultValueAvailable', | |
'isDefaultValueConstant', | |
'isOptional', | |
'isPassedByReference', | |
'canBePassedByValue', | |
'getDefaultValue', | |
'getDefaultValueConstantName', | |
'allowsNull', | |
'getClass', | |
) as $check) { | |
try { | |
// Do loose comparision, otherwise ReflectionParameter::getClass | |
// check will return false | |
if ($param1->$check() != $param2->$check()) { | |
return false; | |
} | |
} catch (\ReflectionException $e) { | |
// Some methods throw exceptions when a parameter is typehinted | |
// with a internal class, array or callable. | |
// * ReflectionParameter::getDefaultValue | |
// * ReflectionParameter::getDefaultValueConstantName | |
// * ReflectionParameter::isDefaultValueConstant | |
// See: http://www.php.net/manual/en/reflectionparameter.getdefaultvalue.php#refsect1-reflectionparameter.getdefaultvalue-notes | |
if ('Internal error: Failed to retrieve the default value' !== $e->getMessage()) { | |
return false; | |
} | |
} | |
} | |
return true; | |
}; | |
foreach ($interfaceReflectionMethod->getParameters() as $key => $param) { | |
if (!isset($functionParameters[$key])) { | |
return false; | |
} | |
if (!$checkParam($param, $functionParameters[$key])) { | |
return false; | |
} | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment