Как вызвать функции из папки по очереди? PHP: class CommandsController { private static $dir = 'src/Commands'; public static function execute(array $object) { $files = scandir(self::$dir, 0); $count_files = count($files); for($i = 2; $i < $count_files; $i++) { if( $files[$i] != 'CommandsController.php' ) { $class = (string) explode('.', $files[$i])[0]; (new $class($object))->execute(); } } } } Но выдает, что class not found, хотя если сделать new <Class>(), то все работает отлично
Вы не включаете файл с классом, а сразу же его создаёте. Поэтому он не находится. Сделайте сперва require_once($dir . '/' . $files[$i]); И autoload прокачайте, видимо, он у вас кривой. Дадите код в студию - подскажу, что можно сделать.
Ну это так, привычка у меня такая... в данном случае вероятность повторного включения нулевая, поэтому необязательно.
Админы, это точно вопрос для профи? Чтобы странная задумка работала, надо проверить две вещи: - реальное имя класса в переменной $class, содержит ли оно неймспейс; - как настроена автозагрузка классов. если пользуешься composer (!!!), то в секции "autoload" можно маппинг по неймспейсам задать.
Затем, что spl PHP: spl_autoload_register ( function ( $name ) { $replaces = [ '\\' => DIRECTORY_SEPARATOR, 'Aero\\Database\\' => 'src\\Lerma\\Database\\', 'TestingMethods' => 'TestingMethods\\TestingMethods' ]; include strtr ( $name, $replaces ) . '.php'; } ); Регистрирует NAMESPACE + NAME класса и больше не загружает файл по новому. Это для единой точки, всей системы сайта.
Я думаю проблема именно в неймспейсе. Когда ты находясь в namespace Foo, делаешь new Bar(), то реально происходит new \Foo\Bar() !!!!!!1111111расрас Но это НЕ работает внутри хитровыделанных фокусов с переменными и функциями. В них подстановка текущего неймспейса не работает. Надо явно писать $class = "Foo\Bar" (лидирующий \ можно не писать) чтобы сработал new $class()
Подозрение ещё вызывает вот это: Начинаю думать, что explode что-то не то выдаёт. И делать (string) там, где возвращается строка, тоже незачем.
@mike4ip при чём тут explode . Класс не найден потому что напутано с пространством имён. Инфа 100%. См. моё объяснение в предыдущем каменте. Допустим у нас есть классы Foo\Bar и Foo\Baz, которые нормально мапятся неважно в какие папки, главное автолоадер их находит ))) И мы хотим обратиться из одного класса к другому: PHP: <?php namespace Foo; class Baz { public function hello() { // $class = 'Bar'; new $class(); -- так будет ошибка "класс не найден", потому что неймспейс не указан // при том, что new Bar() работает нормально, потому что здесь PHP учитывает "текущее пространство имён" // но если имя класса в переменной, то текушее пространство игрорируется. делай так: $class = 'Foo\\Bar'; // а вот так сработает! $bar = new $class(); $barHello = $bar->hello(); return 'It\'s not "'.$barHello.'" but "Hello from ' . self::class.'"'; } } Проверочка в консоли Код (Text): $ php index.php Hello from Foo\Bar It's not "Hello from Foo\Bar" but "Hello from Foo\Baz"
Это тебе кажется. Какой-то автолоадер у него работает, он это указал в посте. Моя демка в приаттаченном ариве. Можешь поиграть с комментированием/раскомментированием и намотать инфу на ус. Не забываем ставить лайки!
У меня инфа про аутолоадеры и неймспейсы давно намотана уже. Просто автор вопроса не удосужился дать полную картину, теперь приходится перебирать все возможные варианты.
@Danil005 ты бы ещё разик вывел содержимое массива после scandir(). А вдруг там не то, что ты думаешь! Например '.' и '..' — ты их тоже как имена классов будешь обрабатывать? Слушай var_dump() используй, да! Надо отладкой пользоваться прежде чем спрашивать "профи".
Это понятно. Просто ТС не упоминал неймспейсы, в приведённом коде класса его тоже не было. Поэтому и не подумал, что дело может быть в этом.
Все было сделано на composer лоаде, все настроено правильно. PHP: <?php namespace Roma\Commands; class CommandsController { private static $dir = 'src/Commands'; public static function execute(array $object) { $files = scandir(self::$dir, 0); for($i = 2; $i < count($files); $i++) { if( $files[$i] != 'CommandsController.php' ) { $class = 'Roma\Commands\\' . (string) explode('.', $files[$i])[0]; (new $class($object))->execute(); } } } } Вот решение. --- Добавлено --- А это я делал для того, чтобы класс по типу 1.php, был стрингом (это бот просто).
Ну вот, я был прав про упущенный неймспейс. @mike4ip Дополнительно я бы рекомендовал непонятные for ($i=2;...) и explode('.',...) заменить на более надёжное: PHP: $files = scandir(__DIR__); foreach ($files as $file) { if (pathinfo($file, PATHINFO_EXTENSION) !== 'php' || $file === 'CommandsController.php') { continue; } $class = __NAMESPACE__ . '\\' . basename($file, '.php'); // ... }