alexeyyashin / ducktyping
PHP 的简单鸭子类型实现
v1.0.1
2020-12-02 12:42 UTC
Requires
- php: >=7.0
This package is auto-updated.
Last update: 2024-09-29 05:29:15 UTC
README
ducktyping 是一个简单的基于反射的 PHP 鸭子类型实现
如果它像鸭子走路,它像鸭子嘎嘎叫,那么它一定是只鸭子
安装
使用 Composer
composer require alexeyyashin/ducktyping
不使用 Composer
- 将仓库文件复制到您需要的地方
- 包含 autoload.php
include_once 'ducktyping-master/autoload.php';
基本用法
检查方法实现
duck_check(Duck::class)->implementing(Bird::class);
如果类 Duck
实现了类 Bird
中存在的所有方法(考虑到 "静态" 修饰符),则返回 true
注意,您可以在 duck_check
函数和 implementing
方法中同时使用类名(作为 string
)或 object
$duck = new Duck; $bird = new Bird; duck_check($duck)->implementing($bird);
检查单个方法的存在性
duck_check(Duck::class)->hasMethod('fly', $check_static)
解释
让我们从一个基本独立类开始
class Animal { public function run() {} } class Plant { public function growLeaves() {} }
然后添加一些子类
class Bird extends Animal { public function fly() {} }
很明显
var_dump(new Bird instanceof Animal); // bool(true)
但是如果我们添加一些独立类
class Duck { public function run() {} public function fly() {} public function quackle() {} }
我们会得到
var_dump(new Duck instanceof Bird); // bool(false)
尽管它既会 "跑" 也会 "飞",但这只是因为类 Duck
没有继承类 Bird
。
要检查这一点,我们可以通过 duck typing 来查看类 Duck
是否拥有类 Bird
中的所有方法
var_dump(duck_check(Duck::class)->implementing(Bird::class)); // bool(true) // BUT, Duck does not have "growLeaves" method, so var_dump(duck_check(Duck::class)->implementing(Plant::class)) // bool(false)
多重类实现附加功能
class Bulbasaur extends Pokemon { public static $link = "https://en.wikipedia.org/wiki/Bulbasaur"; public function run() {} public function growLeaves() {} public function fight() {} } $check = duck_check(new Bulbasaur); $check->implementing(Pokemon::class) // true - because of inheritance $check->implementing(Animal::class) // true - because of "run" method $check->implementing(Plant::class) // true - because of "growLeaves" method $check->implementing(Bird::class) // false - because of "fly" method absence
进一步
我想知道我们是否也应该检查测试类/对象中的公共属性。所以我需要取消注释那一行或删除它。
也许可以添加方法签名检查。