根据有关Strict Typing的PHP文档here
默认情况下,如果可能,PHP会将错误类型的值强制转换为预期的标量类型。例如,为需要字符串的参数赋予整数的函数将获得string类型的变量。
我很好奇是否有办法覆盖此功能以自定义强制执行的方式。
例如
function getResponse() : \Namespace\Response {
return []; // Ideally, this would be coerced into a Response object.
}
. . .
namespace Namespace;
class Response {
public $data;
public function __construct(array $arr)
{
$this->data = $arr;
}
public static function __coerce($value)
{
if (! is_array($value)) {
throw new \TypeError('Wrong type during coercion.');
}
return new self($value);
}
}
答案 0 :(得分:0)
这是不可能的,因为这是编译时语言级别的评估值。
您唯一能做的就是覆盖父回复类型:
public function getResponse(): [] // though parent has "Reponse" type
{
return [];
}
答案 1 :(得分:0)
我已经编写了自己的实现来在PHP中执行此操作,因为不存在。这是它的工作原理。
这是两个基本功能。
multiReturnFunction
函数。(用于调用全局函数和函数)
/**
* Call a global function and use type coercion
* for non-registered return types.
*
* @param closure $closure The function to execute.
* @param string $returnType The registered return type.
* @param array $params The parameters to pass to the function.
*
* @return mixed The result of the function to execute.
*/
function multiReturnFunction($closure, $returnType, ...$params)
{
$val = $closure(...$params);
if (gettype($val) === 'object') {
if (get_class($val) != $returnType) {
if (method_exists($returnType, '__coerce')) {
$val = $returnType::__coerce($val);
} else {
throw new \Exception(
'Returned value does not match the return type defined, '.
'and no __coerce function is visible.'
);
}
}
} else if (gettype($val) != $returnType) {
if (method_exists($returnType, '__coerce')) {
$val = $returnType::__coerce($val);
} else {
throw new \Exception(
'Returned value does not match the return type defined, '.
'and no __coerce function is visible.'
);
}
}
return $val;
}
如果结果返回类型不匹配,multiReturnFunction
函数将调用一个闭包并使用返回类型类的__coerce
函数来强制返回类型。
multiReturnFunction
功能
定义我们将要使用的类,并确保为其提供__coerce
函数。
注意:
__coerce
函数为我们将尝试强制转换为此类类型的对象采用单个变量。该函数必须声明为static。
class MyClass
{
private $data;
public function __construct(array $value)
{
$this->data = $value;
}
public static function __coerce($value)
{
if (! is_array($value)) {
throw new \Exception(
'Returned value does not match the return type defined.'
);
}
return new self($value);
}
}
接下来,您需要使用您的班级和匿名函数调用multiReturnFunction
函数。
$resultingMyClass = multiReturnFunction (
// Multi return type function.
function($name, $age) {
// Here you can return either a MyClass instance, or an array.
// All other types will throw an exception.
return [$name, $age];
},
// Return Type, any other type will be coerced through this class.
MyClass::class,
// Function parameters.
'Nathan', 23
);
multiReturnMethod
函数。(用于调用类方法)
/*
* Call a class method and use type coercion
* for non-registered return types.
*
* @param object $obj The object to call the method on.
* @param string $method The method to call on the object.
* @param string $returnType The registered return type.
* @param array $params The parameters to pass to the method.
*
* @return mixed The result of the method to execute.
*/
function multiReturnMethod($obj, $method, $returnType, ...$params)
{
$val = $obj->{$method}(...$params);
if (gettype($val) === 'object') {
if (get_class($val) != $returnType) {
if (method_exists($returnType, '__coerce')) {
$val = $returnType::__coerce($val);
} else {
throw new \Exception(
'Returned value does not match the return type defined, '.
'and no __coerce function is visible.'
);
}
}
} else if (gettype($val) != $returnType) {
if (method_exists($returnType, '__coerce')) {
$val = $returnType::__coerce($val);
} else {
throw new \Exception(
'Returned value does not match the return type defined, '.
'and no __coerce function is visible.'
);
}
}
return $val;
}
如果结果返回类型不匹配,multiReturnMethod
函数将调用一个类方法并使用返回类型类的__cooerce
函数来强制返回类型。
multiReturnMethod
功能
注意:我们将使用之前创建的
MyClass
类作为返回类型。
定义一个我们可以用来调用类方法的类。
class MRFClass {
function callMe($name)
{
return [$name, 1, 2, 3];
}
}
使用您的班级和匿名函数调用multiReturnMethod
函数。
$resultingMyClass = multiReturnMethod (
// The object that we will be calling the
// class method on.
new MRFClass(),
// The class method to call, by name.
'callMe',
// The return type to coerce to.
MyClass::class,
// The function parameters.
'Nathan'
);
这两个方法都可以用来强制严格的返回类型函数,它接受多个返回类型,可以强制转换为每类实现的返回类型。