Зареждане на интерфейси в конструктора

Направих го по заобиколен начин. С две думи сканирам дадена папка за файлове и така получавам класовете. Всичко работи получавам си точния клас, но проблема е че сканирам само в една папка. Как да го направя да е масив, демек да сканира повече папки? Ето кода.

Код:
//Interface Reflection --------------------------------------------------------------------

        if ($reflector -> isInterface()) {

            $name = $reflector -> getName();

            $folderName = 'controllers';
            
            $folderPath = realpath('..' . DIRECTORY_SEPARATOR . $folderName);

            if ($folderPath != FALSE && is_dir($folderPath) && is_readable($folderPath)) {

                $files = scandir($folderPath);

                $diff = array_diff($files, array('.', '..'));

                foreach ($diff as $iClass) {

                    $ex = explode('.php', $iClass);

                    $ex = array_diff($ex, array(''));

                    foreach ($ex as $e) {

                        $iClass = $folderName . DIRECTORY_SEPARATOR . $e;

                        if (in_array($name, class_implements($iClass))) {

                            $interface = $iClass;

                            break;
                        }
                    }
                }
            }

            $iReflector = new \ReflectionClass($interface);

            $iStaticProperties = $iReflector -> getStaticProperties();

            if ($iStaticProperties) {

                foreach ($iStaticProperties as $k => $v) {

                    if ($k == '_instance' && $v === NULL) {

                        return $interface::getInstance();
                    }
                }
            }

            if (!$iReflector -> isInstantiable()) {

                throw new \Exception('This Class ' . $interface . ' Is Not Instantiable In: ' . __METHOD__, 500);
            }

            $iConstructor = $iReflector -> getConstructor();

            if (is_null($iConstructor)) {

                return new $interface;
            }

            $iParameters = $iConstructor -> getParameters();

            $iDependencies = $this -> getDependencies($iParameters);

            return $iReflector -> newInstanceArgs($iDependencies);
        }

        //End Of Interface Reflection --------------------------------------------------------------------
 
Всъщност с предния пост се оправих, сега ме интересува как мога да проверя дали един клас се имплементира от повече от един интерфейс?
 
teroristd каза:
дали един клас се имплементира от повече от един интерфейс?
Нещо са се разместили думите...

Дали един клас имплеметира 2+ интерфейса? (http://php.net/manual/en/function.class-implements.php)
или
Дали един интерфейс е имплементиран от 2+ класа? (това май-го имаше по-горе - http://stackoverflow.com/questions/3993759/php-how-to-get-a-list-of-classes-that-implement-certain-interface)
 
anonimen каза:
teroristd каза:
дали един клас се имплементира от повече от един интерфейс?
Нещо са се разместили думите...

Дали един клас имплеметира 2+ интерфейса? (http://php.net/manual/en/function.class-implements.php)
или
Дали един интерфейс е имплементиран от 2+ класа? (това май-го имаше по-горе - http://stackoverflow.com/questions/3993759/php-how-to-get-a-list-of-classes-that-implement-certain-interface)

Въпросът беше дали един интерфейс е имплементиран от 2+ класа? По горния начин не става, защото навсякъде ползват функцията get_declared_classes(), която не връща всички класове, и в частност не връща точно тези които ми трябват.

Но с 300 мъки успях да направя и това. С две думи вкарвам в един масив, имената на останалите интерфейси, след пресяването и после ги броя. Вече имам проверката и всичко е точно, но тука ми изникна един проблем. Трябва да сетна $iClass с класа който искам да ползвам, но не мога да измисля къде и как.

Код:
$iClass = $folderName . DIRECTORY_SEPARATOR . $e;

if (in_array($name, class_implements($iClass), TRUE)) {

$repeatingInterfaceArr[] = $name;

$count = array_count_values($repeatingInterfaceArr);

if ($count[$name] > 1) {

              $iClass = 

      }
}
 
По горния начин не става, защото навсякъде ползват функцията get_declared_classes(), която не връща всички класове, и в частност не връща точно тези които ми трябват.
Това изглежда доста странно... едва ли е бъг в рhр...
Сложи някви echo-та около класовете, които не се зареждат; а там, където ти трябват, принтни get_classes и после в outputа виж дали класовете са заредени преди или след извикването на get_classes.
 
anonimen каза:
По горния начин не става, защото навсякъде ползват функцията get_declared_classes(), която не връща всички класове, и в частност не връща точно тези които ми трябват.
Това изглежда доста странно... едва ли е бъг в рhр...
Сложи някви echo-та около класовете, които не се зареждат; а там, където ти трябват, принтни get_classes и после в outputа виж дали класовете са заредени преди или след извикването на get_classes.

Пробвал съм навсякъде не става. Но отново казвам вече имам проверката и сега проблемът е друг.

Нека го обясня така. Инжектирам интерфейс в конструктора и след проверката виждам че той е имплементиран от 2+ класа. Целта е някъде да сетна кой от тези класове искам да ползвам в случая. Ето и пример.
Контейнера вижда че този интерфейс се имплементира от Class_1 и Class_2. Трябва някъде да му кажа кой клас да ползва. Естествено в други контролери класовете ще са различни. Как да стане това?

Код:
namespace controllers;

use application\interfaces\TestInterface;

class Test {

    public $_testInterface;

    public function __construct(TestInterface $testInterface) {

        $this -> _testInterface = $testInterface;
    }

    public function run() {

        $this -> _testInterface -> callSomeMethod();
    }


Нека продължа с обяснението. Ето това ми е тази част от контейнера, която отговаря за гореописаното.
Променливата $name държи пълния неймспейс на интерфейса. В горния пример ще е application\interfaces\TestInterface, в друг клас ще е друго.

Масива _settings[] държи неймспейсовете на класовете, които имплементират $name. В горния пример controllers\Class_1 и controllers\Class_2. В друг клас ще са други.

След проверката $count[$name] > 1 трябва да се каже на кой клас ще е равна променливата $iClass. Ако я задам ръчно и кажа $iClass = 'controllers\Class_1'; горният пример ще сработи, но както казах в други контролери ще са други интерфейси с други имлементиращи ги класове. С две думи променливата $iClass ще трябва да е различна според случая. Надявам се разбирате къде е проблема. Как да сетвам $iClass?

Код:
$iClass = $folderName . DIRECTORY_SEPARATOR . $e;

if (in_array($name, class_implements($iClass), TRUE)) {

$repeatingInterfaceArr[] = $name;

$count = array_count_values($repeatingInterfaceArr);

$this -> _settings[] = $iClass;

if ($count[$name] > 1) {

              $iClass = 

      }
}
 

Back
Горе