3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace Translatable { interface Translatable {} } namespace Translatable\Impl { use Translatable\Translatable; class Translatable1 implements Translatable {} class Translatable2 implements Translatable {} class Translatable3 implements Translatable {} } namespace Translation { use Translatable\Translatable; interface Translator { public static function canTranslateBetween(Translatable $translatable1, Translatable $translatable2): bool; } class TranslatorFactory { /** @var string[] */ private $translatorClasses; public function __construct(array $translatorClasses) { $this->translatorClasses = $translatorClasses; } public function createTranslator(Translatable $a, Translatable $b): Translator { foreach ($this->translatorClasses as $translatorClass) { if ($translatorClass::canTranslateBetween($a, $b)) { return new $translatorClass; } } throw new \RuntimeException('Could not find translator.'); } } } namespace Translation\Impl { use Translatable\Impl\Translatable1; use Translatable\Impl\Translatable3; use Translatable\Translatable; use Translation\Translator; abstract class BaseTranslator implements Translator {} class Translator1 extends BaseTranslator { public static function canTranslateBetween(Translatable $translatable1, Translatable $translatable2): bool { return $translatable1 instanceof Translatable1 && $translatable2 instanceof Translatable3; } } class Translator2 extends BaseTranslator { public static function canTranslateBetween(Translatable $translatable1, Translatable $translatable2): bool { return false; } } class Translator3 extends BaseTranslator { public static function canTranslateBetween(Translatable $translatable1, Translatable $translatable2): bool { return false; } } } namespace { use Translatable\Impl\Translatable1; use Translatable\Impl\Translatable3; use Translation\Impl\Translator1; use Translation\Impl\Translator2; use Translation\Impl\Translator3; use Translation\TranslatorFactory; $translatorFactory = new TranslatorFactory([ Translator1::class, Translator2::class, Translator3::class ]); $translatable1 = new Translatable1(); $translatable3 = new Translatable3(); $translator = $translatorFactory->createTranslator($translatable1, $translatable3); var_dump($translator); }

preferences:
34.87 ms | 404 KiB | 5 Q