只有存在时才实现接口?
Implements Interface only if exists?
我正在尝试找到一种仅在该接口可用时才实现该接口的方法。
有问题的接口是
PrestaShop\PrestaShop\Core\Module\WidgetInterface
来自 Prestashop。它在模块中使用。
问题是,为了与多个版本的 Prestashop 兼容,代码必须处理 WidgetInterface
不存在的情况。
我在想测试接口是否存在,然后导入它,像这样:
if (interface_exists('PrestaShop\PrestaShop\Core\Module\WidgetInterface')) {
use PrestaShop\PrestaShop\Core\Module\WidgetInterface
} else {
interface WidgetInterface {}
}
当然,在 if 语句中使用 use
是不可能的。
然后我尝试做一些 try/catch,但这是同样的问题(可惜不是 Python)。
如何才能 implements WidgetInterface
仅在可用时?
你不能像你说的那样动态实现接口,但你可以编写自己的接口,并且 require
如果另一个接口不存在,则只使用它。
即:您的界面将类似于 widget_interface.php
,或者您想要的任何名称,只要它不符合 PSR-0/4 或以您通常使用的任何方式自动加载即可。
<?php
namespace PrestaShop\PrestaShop\Core\Module;
/**
* This is the replacement interface, using the same namespace as the Prestashop one
*/
interface WidgetInterface
{
}
然后,在您的 class 中,您可以执行以下操作:
<?php
namespace App;
if (!interface_exists('\PrestaShop\PrestaShop\Core\Module\WidgetInterface')) {
require __DIR__ . '/path/to/widget_interface.php';
}
class WhateverClass implements \PrestaShop\PrestaShop\Core\Module\WidgetInterface
{
}
仅当 Prestashop 界面不存在时才会加载您的替换界面。
是的,您不能将 use
放在 if
块中,但是 use
只是为 class 设置了一个别名。它不会尝试加载 class。因此它可以安全地位于 if
块之外。
并且您可以在if
.
中定义class或接口本身
This 是 Symfony 处理这个确切问题的方式,继承自一个可能不存在的接口:
namespace Symfony\Contracts\EventDispatcher;
use Psr\EventDispatcher\EventDispatcherInterface as PsrEventDispatcherInterface;
if (interface_exists(PsrEventDispatcherInterface::class)) {
interface EventDispatcherInterface extends PsrEventDispatcherInterface
{
public function dispatch($event);
}
} else {
interface EventDispatcherInterface
{
public function dispatch($event);
}
}
就个人而言,为了保持整洁并包含在一个地方,我会像这样定义你自己的接口,如果可用的话,它继承自 PrestaShop
接口,或者提供自己的实现,然后让你的 class 继承自那个。
我正在尝试找到一种仅在该接口可用时才实现该接口的方法。
有问题的接口是
PrestaShop\PrestaShop\Core\Module\WidgetInterface
来自 Prestashop。它在模块中使用。
问题是,为了与多个版本的 Prestashop 兼容,代码必须处理 WidgetInterface
不存在的情况。
我在想测试接口是否存在,然后导入它,像这样:
if (interface_exists('PrestaShop\PrestaShop\Core\Module\WidgetInterface')) {
use PrestaShop\PrestaShop\Core\Module\WidgetInterface
} else {
interface WidgetInterface {}
}
当然,在 if 语句中使用 use
是不可能的。
然后我尝试做一些 try/catch,但这是同样的问题(可惜不是 Python)。
如何才能 implements WidgetInterface
仅在可用时?
你不能像你说的那样动态实现接口,但你可以编写自己的接口,并且 require
如果另一个接口不存在,则只使用它。
即:您的界面将类似于 widget_interface.php
,或者您想要的任何名称,只要它不符合 PSR-0/4 或以您通常使用的任何方式自动加载即可。
<?php
namespace PrestaShop\PrestaShop\Core\Module;
/**
* This is the replacement interface, using the same namespace as the Prestashop one
*/
interface WidgetInterface
{
}
然后,在您的 class 中,您可以执行以下操作:
<?php
namespace App;
if (!interface_exists('\PrestaShop\PrestaShop\Core\Module\WidgetInterface')) {
require __DIR__ . '/path/to/widget_interface.php';
}
class WhateverClass implements \PrestaShop\PrestaShop\Core\Module\WidgetInterface
{
}
仅当 Prestashop 界面不存在时才会加载您的替换界面。
是的,您不能将 use
放在 if
块中,但是 use
只是为 class 设置了一个别名。它不会尝试加载 class。因此它可以安全地位于 if
块之外。
并且您可以在if
.
This 是 Symfony 处理这个确切问题的方式,继承自一个可能不存在的接口:
namespace Symfony\Contracts\EventDispatcher;
use Psr\EventDispatcher\EventDispatcherInterface as PsrEventDispatcherInterface;
if (interface_exists(PsrEventDispatcherInterface::class)) {
interface EventDispatcherInterface extends PsrEventDispatcherInterface
{
public function dispatch($event);
}
} else {
interface EventDispatcherInterface
{
public function dispatch($event);
}
}
就个人而言,为了保持整洁并包含在一个地方,我会像这样定义你自己的接口,如果可用的话,它继承自 PrestaShop
接口,或者提供自己的实现,然后让你的 class 继承自那个。