Новый комментарий

Kirill.K 24.11.2018 в 20:50

bin/cli.php

if (get_parent_class($className) != 'MyProject\Cli\AbstractCommand' ) {
        throw new \MyProject\Exceptions\CliException('Class "' . $className . '" not a subclass of AbstractCommand');
    }
ivashkevich 24.11.2018 в 21:59

Хорошо, а если он является наследником через несколько классов? Подумайте в сторону PHP Reflection API.

Kirill.K 25.11.2018 в 14:34

Я думал над этим, долго) Но не мог понять как решить эту проблему, а с этой наводкой сделал моментально, мало ещё опыта, не все инструменты держатся в голове)
bin/cli.php

...
    $reflectionOfClassName = new ReflectionClass($className);

    if (!$reflectionOfClassName->isSubclassOf('MyProject\Cli\AbstractCommand')) {
        throw new \MyProject\Exceptions\CliException('Class "' . $className . '" not a subclass of AbstractCommand');
    }
...
ivashkevich 25.11.2018 в 17:25

Супер! Вместо строки 'MyProject\Cli\AbstractCommand' лучше использовать MyProject\Cli\AbstractCommand::class

Kirill.K 25.11.2018 в 18:14

Хорошо, буду знать и использовать)

dnldcode 25.03.2019 в 19:31
    if (in_array(\MyProject\Cli\AbstractCommand::class, class_parents($className))){
        throw new \MyProject\Exceptions\CliException('Class AbstractCommand is not a parent of class ' . $className);
    }
ivashkevich 27.03.2019 в 11:29

Исключение будет бросаться для всех наследников этого класса, а нужно наоборот.

Iliusha99 09.08.2019 в 18:21

$classReflector = new ReflectionClass($className);

if (!$classReflector->isSubclassOf(AbstractCommand::class)){
    throw new CliException("Некорректный класс");
}
Iliusha99 09.08.2019 в 18:24

Такой вопрос, можно как то вызвать методы класса ReflectionClass статически, без создания объекта?

ivashkevich 10.08.2019 в 07:23

Не знаю, почитайте документацию. Но непонятно для чего вам это.

ivashkevich 10.08.2019 в 07:22

Отлично

Metey 17.08.2019 в 15:03
$checkClassAbstract = new ReflectionClass($className);
    if (!$checkClassAbstract->isSubclassOf(MyProject\Cli\AbstractCommand::class)) {
        throw new \MyProject\Exceptions\CliException('Class "' . $className . '"is not subclass of AbstractCommand');
    }
ivashkevich 18.08.2019 в 06:52

Отлично

Moskva 17.08.2019 в 22:50
    $obj = new ReflectionClass($className);

    if(!$obj->isSubclassOf(MyProject\Cli\AbstractCommand::class)){
        throw new MyProject\Exceptions\CliException('Сlass '. $className . ' is not a descendant of the AbstractCommand class ');
    }
ivashkevich 18.08.2019 в 06:52

Отлично

andreskrip 25.02.2020 в 18:30

Спасибо за урок!

    // Проверяем, является ли класс подклассом AbstractCommand
    $obj = new ReflectionClass($className);
    if (!$obj->isSubclassOf(\MyProject\Cli\AbstractCommand::class)) {
        throw new \MyProject\Exceptions\CliException($className . ' not extend AbstractCommand');
    }
ivashkevich 26.02.2020 в 20:14

Отлично

OneMoreTime 01.04.2020 в 00:13
private function getParam(string $paramName)
    {
        return $this->params[$paramName] ?? null;
    }

    private function ensureParamExists(string $paramName)
    {
        if (!isset($this->params[$paramName])) {
            throw new CliException('Param with name "' . $paramName . '" is not set!');
        }
    }

Если устанавливать значение элемента массива в null, почему бы это не делать сразу в методе ensureParamExists?

private function ensureParamExists(string $paramName)
    {
        if (!isset($this->params[$paramName])) {
            $this->params[$paramName] = null;
            throw new CliException('Param with name "' . $paramName . '" is not set!');
        }
    }

А вообще, зачем эта установка в null? Ведь при проверке

(!isset($this->params[$paramName]))

в случае отсутствия этого элемента в массиве вылетит все равно исключение?

ivashkevich 01.04.2020 в 04:47

Речь идёт только о проверке только обязательных параметров, а не вообще всех. Метод, который называется ensure... Не должен менять состояние проверяемых данных, это сайд-эффект, никак не отражаемый в его названии.

Alexann 05.05.2020 в 17:35
$reflectionOfClass=new ReflectionClass($className);
    if (!$reflectionOfClass->isSubclassOf(MyProject\Cli\AbstractCommand::class)){
        throw new \MyProject\Exceptions\CliException('Класс '.$className.' не является наследником AbstractCommand');
    }
ivashkevich 06.05.2020 в 13:48

Отлично

dima1 15.06.2020 в 22:37
$reflectionClass = new ReflectionClass($className);

    if (!$reflectionClass->isSubclassOf(MyProject\Cli\AbstractCommand::class)) {
        throw new \MyProject\Exceptions\CliException('Class "' . $className . '" not a subclass of AbstractCommand');
    }
ivashkevich 17.06.2020 в 07:01

Отлично!

littleprogramer 01.07.2020 в 12:29
if (!class_exists($className)) {
    throw new \MyProject\Exceptions\CliException('Class "' . $className . '" not found');
}

Как избавиться от ошибок (Warning и Fatal error), если вводишь не правильный класс?

ivashkevich 01.07.2020 в 19:52

А смысл от них избавляться?

littleprogramer 02.07.2020 в 12:27

описание картинки Хм, думаю я не корректно написал. Почему не срабатывает throw new Exception, когда мы ввели не правильно класс, а появляются ошибок Warning и Fatal. После я понял что class_exists запускает автозагрузку (class_exists ( string $class_name [, bool $autoload = TRUE ] ) : bool), но если я ставлю в false, ругается на каждый класс. Хотя автозагрузка в bin/cli.php уже есть и файлы подключены, осталось только проверить существует ли класс? )). Хочу просто получать корректную ошибку: 'Class Summat not found', а не ошибки (Warning и Fatal error). Пока что я переписал, так что у меня один класс и методы(команды) которые проверяю (method_exists) и если команды нет, то просто вывожу 'Операция Summat не найдена'. Еще можно добавить --help (c инструкцией и операциями )

ivashkevich 03.07.2020 в 09:09

Ну так это в автозагрузчике дело. Он почему-то делает require сразу, хотя сначала должен проверить сущетсвование файла

studentDev 20.07.2020 в 14:34
try {
    unset($argv[0]);

    if(file_exists(__DIR__ . '/../src/MyProject/Cli/' . $argv[1] . '.php') == false) {
        echo 'Not Found';
        return;
    }

    // Регистрируем функцию автозагрузки
    spl_autoload_register(function (string $className) {
        require_once __DIR__ . '/../src/' . $className . '.php';
    });

    $className = '\\MyProject\\Cli\\' . array_shift($argv);
    // Подготавливаем список аргументов
    $params = [];
    foreach ($argv as $argument) {
        preg_match('/^-(.+)=(.+)$/', $argument, $matches);
        if (!empty($matches)) {
            $paramName = $matches[1];
            $paramValue = $matches[2];

            $params[$paramName] = $paramValue;
        }
    }

    if(!is_subclass_of(new $className($params), 'AbstractCommand') == null) {
        throw new MyProject\Exceptions\CliException('Экземпляр' . $className . ' не принадлежит классу AbstractCommmand!');
    }

    // Создаём экземпляр класса, передав параметры и вызываем метод execute()
    $class = new $className($params);
    $class->execute();
} catch (\MyProject\Exceptions\CliException $e) {
    echo 'Error: ' . $e->getMessage();
}
ivashkevich 21.07.2020 в 12:01

Отлично!

VitaliyB 22.09.2020 в 09:51

Думаю, можно обойтись без рефлексии. И кода меньше...

 if (!is_subclass_of($className, AbstractCommand::class)) {
        throw new \MyProject\Exceptions\CliException('Class "' . $className . '" is not subclass of AbstractCommand');
    }
ivashkevich 27.09.2020 в 17:10

Хорошее решение

pixel 12.02.2021 в 19:45

Классное решение!

Larisa 27.01.2021 в 22:33

cli.php

$reflectionClass=new ReflectionClass($className);

    if (!$reflectionClass->isSubclassOf(MyProject\Cli\AbstractCommand::class)) {
        throw new MyProject\Exceptions\CliException('Class "' . $className . '" is not inherited AbstractCommand' );
    }
ivashkevich 28.01.2021 в 07:52

Отлично!

Djem 16.11.2021 в 18:33

bin/cli.php

if (!is_subclass_of($className, '\\MyProject\\Cli\\AbstractCommand')) {
        throw new \MyProject\Exceptions\CliException('Class "' . $className . '" not extends AbstractCommand');
    }
ivashkevich 01.12.2021 в 04:48

Норм, хотя ожидал применение instanceof

Vladimir96 15.03.2022 в 13:29
$parentClasses = class_parents($className);
if (!in_array('MyProject\\Cli\\AbstractCommand', $parentClasses)) {
    throw new MyProject\Exceptions\CliException('Class "' . $className . '" не имеет родителя');
}
ivashkevich 11.04.2022 в 09:59

Норм!

Dram 29.06.2022 в 22:43

Извините, я немного затупил, понял что нужно использовать get_parent_class($className) но почему то ловил вывод в функции spl_autoload_register и теперь мне непонятно почему в ней var_dump(get_parent_class($className)); выдает - bool(false)?

И второй вопрос, а разве CLI это продвинутый уровень PHP? Я еще тот говнокодер, но уже написал уже несколько сотен скриптов и парсеров на фрилансе, и постоянно запускаю скрипты из консоли, но только пару раз мне приходилось их запускать с параметрами. В реальной работе разве это нужно?

ivashkevich 24.07.2022 в 19:16

Смотрим доку
If the object does not have a parent or the class given does not exist false will be returned.

В реальной работе разве это нужно?

Нужно :)

Логические задачи с собеседований