c语言编程笔录

首页 >   > 笔记大全

笔记大全

php7类型约束的意义

更新时间:2023-10-02

php7类型约束的意义

什么是php7类型约束

PHP 7在函数参数中引入了类型约束。类型约束可以强制要求函数参数必须是某个类的实例对象、某种接口、一种特定的类或是一个标量类型(指整型、浮点型、布尔型或字符串型)。

类型约束优势

类型约束可以方便消除函数调用时的错误。使用类型约束可以约束输入参数和返回值的类型,从而保证编写出更加健壮的代码。

//示例1:标量类型约束
function add(int $a, int $b): int {
    return $a + $b;
}

echo add(1, 2); //3
echo add(1.5, 2.5); //Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type integer, float given

//示例2:类类型约束
class Person {
    private $name;
    public function __construct(string $name) {
        $this->name=$name;
    }
    public function getName(): string {
        return $this->name;
    }
}

function sayHello(Person $person) {
    echo "Hello, " . $person->getName();
}

$p=new Person("Tom");
sayHello($p); //Hello, Tom
sayHello("Tom"); //Fatal error: Uncaught TypeError: Argument 1 passed to sayHello() must be an instance of Person, string given

类型约束的缺陷

虽然类型约束可以减少编程错误,但是如果我们使用不当,也会带来很多问题。如果函数参数类型过于严格,阻止了一些可能成功的转换,导致代码变得很难维护。如下示例:

//示例3:类型约束过于严格,导致调用者必须传入对象
class Controller {
    public function __construct(User $user, Request $request) {
        //do something
    }
}

//在使用此Controller时必须传入User和Request的实例对象
//这将迫使我们在使用Controller时保证用户已经登录,且请求的方式正确
$user=new User();
$request=new Request();
$c=new Controller($user, $request);

//如果希望每一次使用Controller时都要传入相应的对象,我们可以使用服务容器模式 ServiceProvider
class ServiceProvider {
    private $provider;
    public function __construct(callable $provider) {
        $this->provider=$provider;
    }
    public function __invoke() {
        return $this->provider->__invoke();
    }
}

$provider=new ServiceProvider(function(){
    return new Controller(new User(), new Request());
});

//若用户已登录,我们就使用Controller
if($loggedIn) {
    $c=$provider();
}

总结

PHP 7.0引入了类型约束功能,可以强制要求函数输入参数或者返回值必须是某个类型或者类的实例对象。类型约束可以简化代码验证逻辑,减少潜在的编译时错误,提高代码的可读性。

但我们并不应该对类型变量过度依赖。如果刻意忽略明显的转换,使用类型约束可能会导致编写的代码非常难以维护。