Php 多个不相关接口的类型提示
php中有没有一种方法可以为两个不同的、不相关的接口键入提示?例如:Php 多个不相关接口的类型提示,php,oop,interface,type-hinting,Php,Oop,Interface,Type Hinting,php中有没有一种方法可以为两个不同的、不相关的接口键入提示?例如: interface errorable { function error($msg); } interface recordable { ssh_for_recorder(); } class uploader__module extends base__module implements errorable, recordable { public function ssh_for_recorder()
interface errorable {
function error($msg);
}
interface recordable {
ssh_for_recorder();
}
class uploader__module extends base__module implements errorable, recordable {
public function ssh_for_recorder() {
return new ssh2;
}
public function error($msg) {
$this->errors[] = $msg;
}
public function upload() {
$recorder = new recorder($this);
$recorder->run();
}
}
class recorder {
private $ssh2;
private $module;
private function upload() {
if (!$this->ssh2) {
$this->module->error("No SSH2 connection");
}
}
public function __construct({recordable,errorable} $module) {
$this->module = $module;
$this->ssh2 = $module->ssh_for_recorder();
}
}
正如您在上面的代码中所看到的,recorder类希望其模块能够同时运行error()
和ssh\u for\u recorder()
,但它们是由不同的接口定义的。errorable不需要记录,反之亦然
有这样做的最佳实践吗?我想创建一个从可记录和可出错扩展而来的接口,并让upload_u模块实现它,但我不知道该怎么称呼它。不,这在php中是不可能的
还有其他语言(大部分是功能性的)支持此功能,称为联合类型()。PHP中唯一的漏洞是帮助函数,它可以在方法中为您执行检查,如下所示:
function CheckInterfaces($object,array $interfaces)
{
foreach($interfaces as $i)
{
if(!is_a($object,$i))
{
return false;
}
}
return true;
}
然后在方法中执行以下操作:
public function Something($object)
{
if(CheckInterfaces($object,array("foo","bar")))
{
throw new ArgumentException(gat_class($object) . " Must be a member of foo,bar to be passed to Something");
}
}
围绕此问题的另一种方法是为您所需的接口创建联合接口,下面是一个快速示例
interface foobar extends foo,bar{}
然后你就可以要求使用
foobar
。我决定回答这个问题,即使你已经接受了一个答案,理由是给出的答案没有一个是真正可以接受的。虽然公认的答案在技术上是正确的,但还是有办法绕过它的。至于其他答案,他们的解决办法并不雅观,也不完全令人满意
public function __construct(recordable $recordable_module, errorable $errorable_module) {
if($recordable_module == $errorable_module){
$module = $recordable_module;
}
$this->module = $module;
$this->ssh2 = $module->ssh_for_recorder();
}
PHP支持一个相当模糊的特性,允许一个接口从另一个接口继承,事实上,一个接口能够从多个基本接口继承
例如,以下内容完全有效:
interface iFoo
{
public function doFoo ();
}
interface iBar
{
public function doBar ();
}
interface iBaz extends iFoo, iBar
{
// This interface implicitly has all the methods of iFoo and iBar
}
从语义上讲,如果您希望一个方法/函数只接受一个实现多个接口的参数,那么这就意味着您希望实现同一组多个接口的类实际上应该实现一个包含您希望参数符合的两个接口的接口
在您的情况下,如果您想要既可出错又可记录的内容,则只需添加以下接口:
interface RecordableErrorable extends Recordable, Errorable { }
然后,Recorder类的构造函数将简单地期望该接口作为其参数
public function __construct(RecordableErrorable $module) { }
一个可能的症结可能是,如果可记录和可出错这两个实现方法具有相同的名称。那里会有需要解决的冲突。我确实相信PHP中有处理这种情况的机制,尽管我无法告诉您它们是什么 这与类型暗示有什么关系?请参阅记录器的构造函数。我想同时输入可记录和可出错的提示。我认为@Hammish会感到困惑,PHP中的类型提示要求一个类是某种类型,其中@tandu需要检查多种类型的接口。你建议如何在PHP中解决这个问题?好吧,制作一个扩展可记录和可出错的新接口。但是,您必须更改实现这两个接口的类,以实现新的接口。我最终得到了可记录的extend errorable,因此在我的应用程序中也得到了解决。#1很有趣,但我认为它太过分了。我喜欢2号。不过,需要注意的是,接口扩展了其他接口,但没有实现它们。您的代码将导致语法错误。虽然这是唯一合理的解决方案,但我不喜欢2,因为我还必须更改类以实现联合接口,而不是单独的单独接口。它是#2。就是这样。