Реализует интерфейс, только если существует?

Реализует интерфейс, только если существует?

18.09.2019 06:38:52 Просмотров 51 Источник

Я пытаюсь найти способ реализовать интерфейс только тогда, когда этот интерфейс доступен.

Интерфейс в вопросе является

PrestaShop\PrestaShop\Core\Module\WidgetInterface

Из Престашопа. Он используется в модуле.

Дело в том, что для совместимости с несколькими версиями Prestashop код должен обрабатывать случай, когда WidgetInterfaceне существует.

Я думал в тестировании существования интерфейса и импортировать его после, как это:

if (interface_exists('PrestaShop\PrestaShop\Core\Module\WidgetInterface')) {
    use PrestaShop\PrestaShop\Core\Module\WidgetInterface
} else {
    interface WidgetInterface {}
}

Но, конечно, невозможно использовать useвнутри оператора if.

Затем я попытался сделать некоторые попытки / поймать, но это та же проблема (жаль, что это не Python).

Как я могу сделать, чтобы implements WidgetInterfaceтолько тогда, когда он доступен?

У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/57996429/implements-interface-only-if-exists#comment102399338_57996429
На ум приходит отражение.
https://stackoverflow.com/questions/57996429/implements-interface-only-if-exists#comment102399454_57996429
Да! Я немного растерялся. Я, конечно, не единственный в этой ситуации! ...

Ответы - Реализует интерфейс, только если существует? / Implements Interface only if exists?

Является ответом!
benJ

18.09.2019 07:10:33

Вы не можете реализовать интерфейс динамически, как вы говорите, но вы можете написать свой собственный интерфейс и requireего только в том случае, если другой не существует.

Ie: ваш интерфейс будет чем-то вроде 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
{
}

Затем, в вашем классе, вы можете сделать следующее:

<?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 one не существует.

Stephen Clouse

19.09.2019 05:29:28

Правда, вы не можете useвнутри блока if, но useпросто устанавливает псевдоним для класса. Он не пытается загрузить класс. Таким образом, он может безопасно находиться за пределами блока if.

И вы можете определить класс или сам интерфейс внутри if.

Вот как 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, если он доступен, или предоставляет свою собственную реализацию, а затем ваш класс наследует от этого.

Закрыть X