Model exists or not in YII using a custom function - Performance

I am writing a REST API and should check the weather that the given model name exists or not in the directory.

1 - http://example.com/RestApi/index.php/api/posts/

2 - http://example.com/RestApi/index.php/api/post/

of these two, URL 1 is incorrect and URL 2 is correct (message). therefore, I take this parameter and search as follows:

$model = $m::model()->findAll($criteria); $m = TK::get('model'); 

when $ m is incorrect, PHP warning include (posts.php): could not open the stream: such a file or directory will not be launched.

so that this would not happen, I wrote a function as modelExists () and used it as shown below.

 If (!TK::modelExists($m)) $this->sendResponse(false, 1003); 

function body as below

 /** * 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; } 

My question is . Could this cause any performance issues as I check this for every API call?

+1
source share
2 answers

Why not just have a map of all the classes in your project. This way you can use this rather than constantly looking at the disk.

Take a look at composer . Yes, I know that it is a dependency manager, but it also works as an autoloader .

If you added composer.json correctly, for example:

 "autoload": { "classmap": [ "protected/", ] } 

it will automatically generate a full array of classes, which you can download from the provider / composer / autoload_classmap.php. All you have to do is make sure the keys of the array are lowercase and you can match 1 to 1. Just remember to remember the linker-dump-autoloader call if you add new classes .

If you do this like this, consider downloading the entire autoloader (vendor / autoload.php), as this will help Yii generally limit the search for files. Get Yii even more from this by doing:

 $loader = require(__DIR__ . '/../vendor/autoload.php'); Yii::$classMap = $loader->getClassMap(); 

In your index.php before calling the run () function. That way, Yii can just look at the class in the array.

For your problem, just call the $ loader-> getClassMap () function a second time and enter the lowercase array keys for your lookup table.

+1
source

Since your code has some file system related functions inside loops, the performance penalty will be significant due to all issued system calls. You should at least cache the result of your method.

An even better method might be the solution proposed by the Core iii core :)

+1
source

Source: https://habr.com/ru/post/958536/


All Articles