Использовать все классы папки - PullRequest
0 голосов
/ 10 мая 2018

Я создал сервис в Symfony 4, который позволяет мне восстанавливать имя каждого класса PHP файла и создавать экземпляры каждого класса благодаря циклу.

Но у меня есть эта ошибка, которая логична, потому что я неНе используйте его «использовать» для каждого класса:

Попытка загрузить класс «MyClass» из глобального пространства имен.Вы забыли выражение "use" для "App \ Service \ Adapter \ MyClass"?

Мне бы хотелось, чтобы каждый файл моего файла автоматически использовался в моем сервисе.Возможно ли это?

Мой код:

<?php

declare(strict_types = 1);

namespace App\Service\Factory;

use App\Service\Adapter\AdapterInterface;
use Doctrine\ORM\EntityManagerInterface;
use function dump;
use function explode;
use function scandir;

/**
 * Class ArticleFactory
 *
 * @package App\Service\Factory
 */
class ArticleFactory
{
    /**
     * @var EntityManagerInterface
     */
    protected $entityManager;
    protected $pathService;

    /**
     * ArticleFactory constructor.
     *
     * @param EntityManagerInterface $entityManager
     * @param $pathService
     */
    public function __construct(EntityManagerInterface $entityManager, $pathService)
    {
        $this->entityManager = $entityManager;
        $this->pathService = $pathService;
    }

    public function adapters(): void
    {
        $scandir = scandir($this->pathService . '/Adapter', SCANDIR_SORT_NONE);
        $adapters = [];

        foreach ($scandir as $key => $value) {
            if ($value !== '.' && $value !== '..' && $value !== 'AdapterAbstract.php' && $value !== 'AdapterInterface.php') {
                $cuttedString = explode('.php', $value);
                $className = $cuttedString[0];

                $adapters[] = new $className($this->entityManager);
            }
        }

        foreach ($adapters as $adapter) {
            if ($adapter instanceof AdapterInterface) {
                $adapter->rss();
                $article = $adapter->adapt();

                foreach ($article as $item) {
                    $this->entityManager->persist($item);
                }
            }
        }
        $this->entityManager->flush();
    }
}

Я проверял это, но это не работает:

use App\Service\Adapter;

И:

use App\Service\Adapter\*;

А:

$className = '\\'.$cuttedString[0];
$adapters[] = new $className($this->entityManager);

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Сообщение об ошибке несколько вводит в заблуждение; use операторы являются сокращенной формой для имени класса в конкретном исходном файле и предназначены исключительно для удобства; вам никогда не нужно нуждаться в выражении use, и они не имеют никакого значения для имен классов, на которые ссылаются динамически, как вы делаете здесь.

Ваша настоящая проблема заключается в том, что когда вы находите файл Foo.php, вы пытаетесь загрузить класс с именем Foo (или, в одном из ваших попыток исправления, \Foo), когда фактическое имя класса App\Service\Adapter\Foo.

Исправление, следовательно, простое: используйте полное имя класса с префиксом пространства имен:

$className = 'App\Service\Adapter\\' . $cuttedString[0];

(Обратите внимание, что последний \ должен быть экранирован как \\, потому что даже в строке в одинарных кавычках \' действует как экранированный знак кавычки, так что вы можете написать 'foo\'s bar'.)

0 голосов
/ 10 мая 2018

Если файл (или класс) не использует пространство имен, он будет помещен в глобальное пространство имен.Вы можете создать эти классы с обратным слешем () в качестве префикса.Например:

$myClass = new \MyClass();
$datetime = new \DateTime();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...