Я пишу REST API и должен проверять погоду, что данное имя модели существует или нет в каталоге.
1 – http://example.com/RestApi/index.php/api/posts/
2 – http://example.com/RestApi/index.php/api/post/
из этих двух URL-адрес 1 неверен, а URL 2 – правильно (сообщение). поэтому я беру этот параметр и выполняю поиск следующим образом,
$model = $m::model()->findAll($criteria); $m = TK::get('model');
когда $ m неверно, PHP warning include (posts.php): не удалось открыть поток: такой файл или каталог не будет запущен.
поэтому, чтобы этого не произошло, я написал функцию как modelExists () и использовал ее, как показано ниже.
If (!TK::modelExists($m)) $this->sendResponse(false, 1003);
тело функции, как показано ниже,
/** * Checks for a given model name * @param string $modelName is the name of the model that is used to search against the directory. * @return String $result, the name of Model. if doesnt exist NULL; */ public static function modelExists($modelName) { $result = null; $basePath = Yii::getPathOfAlias('application').DIRECTORY_SEPARATOR; $modelsDir = 'models'.DIRECTORY_SEPARATOR; $modelName = strtolower($modelName).'.php'; $generalModelDir = scandir($basePath.$modelsDir); foreach ($generalModelDir as $entry) { // Searching in General model directory if ($modelName == strtolower($entry)) { $temp = explode('.', $entry); // array('User','php') $result = $temp[0]; break; } } if (!$result) { $modulePath = $basePath.'modules'.DIRECTORY_SEPARATOR; $moduleDirectory = scandir($modulePath); foreach ($moduleDirectory as $dir) { $subModuleDirectory = scandir($modulePath.$dir); foreach ($subModuleDirectory as $entry) { if (is_dir($modulePath.$dir.DIRECTORY_SEPARATOR.$entry)) { $directories = scandir($modulePath.$dir.DIRECTORY_SEPARATOR.$entry); foreach ($directories as $subDir) { if ($modelName == strtolower($subDir)) { $temp = explode('.', $subDir); // array('User','php') $result = $temp[0]; break; } } } } } } return $result; }
Мой вопрос : может ли это вызвать какие-либо проблемы с производительностью, так как я проверяю это для каждого вызова API?
Почему бы просто не иметь карту всех классов в вашем проекте. Таким образом, вы можете использовать это, а не постоянно смотреть на диск.
Взгляните на композитора . Да, я знаю, что это менеджер зависимостей, но он также отличный генератор автозагрузки .
Если вы правильно добавили композитор.json, например:
"autoload": { "classmap": [ "protected/", ] }
в нем он автоматически генерирует полный массив классов, который вы можете загрузить с поставщика / композитора / autoload_classmap.php. Все, что вам нужно сделать, это убедиться, что ключи массива находятся в нижнем регистре, и вы можете сопоставить 1 на 1. Просто не забудьте вспомнить вызов «компоновщик-дамп-автозагрузка», если вы добавите новые классы .
Если вы делаете это так, подумайте о загрузке всего автозагрузчика (vendor / autoload.php), поскольку это поможет Yii в целом ограничить поиск на диске. Получите Yii еще больше от этого:
$loader = require(__DIR__ . '/../vendor/autoload.php'); Yii::$classMap = $loader->getClassMap();
В index.php перед вызовом функции run (). Таким образом, Yii может просто посмотреть класс в массиве.
Для вашей проблемы просто вызовите функцию $ loader-> getClassMap () второй раз и введите строчные ключи массива для вашей таблицы поиска.
Поскольку в вашем коде есть некоторые связанные с файловой системой функции внутри циклов, штраф за производительность будет значительным из-за всех выпущенных системных вызовов. Вы должны по крайней мере кэшировать результат вашего метода.
Еще лучшим методом может быть это решение, предложенное разработчиком ядра Yii 🙂