Check if model exists

For a project I need to check if a particular model exists before I call it. Example:




$class = "foobar";

$model = $class::model()->findByPk($id);



If $class for some reason is referring to a model that does not exists I get a PHP error that it fails to open a file.




include(foobar.php) [<a  href='function.include'>function.include</a>]: failed to open  stream: No such file or directory	



How can I first check if the model exists before I try to call methods on it?

Is this really such a weird question?

I can think of a work-around but surely there must be a Yii way?

if (class_exists(‘foobar’))?

Thanks, but that won’t kick-in the autoload.

maybe use yii::import(‘application.models’ . $foobar, true) in a try catch block?

Check the documentation for class_exists() - http://php.net/manual/en/function.class-exists.php

It has a second parameter "autoload" that is true by default… .and you can set it false so that autoload is not fired

Assumption is the mother of…

Thanks! I’ll give it a try. I just realized something, the models directory is being pre-loaded by default in Yii. Which is what you meant by turning autoload to false.

What I meant is to use


class_exists('foobar', false);

this way you prevent the autoloading of the class

Worked as a charm. Thank you very much.

Sorry, just found out it does not!

Apparently the model I used to test was already used somewhere else on the website. yii::import() will also not work; all the models are already on the import list.

I just need the Yii autoload feature to throw an exception if I try to load in a model that does not exist; instead of throwing a PHP error about failing to include a file. I cannot handle the PHP error, but I can handle the exception.

Do you have a suggestion?

Why do you have to call a model that does not exists?

Don’t understand why you need to check if class exists or not, yii do it for you using reflection… why do it manually ?

Instead you should think more about the design…

If you have to check every time that model exists, your website structure very bad

I have a good reason.

I think I’ll do a feature request instead. Thanks everyone for your help.

If you want to make a feature request… you can do it… but at least you need to specify a good reason as why to add this feature… because if it’s something that only you need and only for one project… there is no point in adding this to the framework… so when you make the feature request think about this and give some good reasons :D

As for your problem… if I got it right… you don’t need to check if the class exist - as this means that the class is loaded… (this is what clas_exists() checks)

you need to know if the file exists… so that it can be included for the first time…

Problem is that there is no way to make a fast solution for this as the class can be in any folder or subfolder… so all folders would need to be checked…

Maybe you can get a compromise… like keeping all those classes in one folder… then you can just test with file_exist() to see if there is a file with the class name… as in Yii one class is one file with the same name…

I wanted to suggest to try to do the file_includes just like it’s doing right now. If all of them fail; throw an exception.

I havent looked at the code yet, but my guesstimate is that it should be quite easy to implement. I’ll have another look at this in a few days. Thanks for your feedback mdomba!

I have same problems.

I have the project with many subprojects. Subprojects use common models, which i store my system.common.models directory. One common model have many children from subproject’s models, when I inizialize from subproject my common model I want check what models I have in children by class_exists function, and I need use autoload.

But I got error failed to open strem: No such file or directory, if I try check not exists children className.

Well, check_class will be check out of class exists, but generate error. It’s not logical.

I found solution for my needs: instead of class_exists I use

class Helper {

public static function class_exists($className) {

return file_exists(Yii::getPathOfAlias('application.models').DIRECTORY_SEPARATOR.&#036;className.'.php');

}

}

I know this post is outdated, but I was stuck on this and as it turns out the solution as of PHP 5.3.2 is pretty straightforward, posting here just for reference


stream_resolve_include_path('ClassName.php');

http://www.php.net/s...ve_include_path

That’s only suitable if all your classes are located in a predetermined location - application.models, in your example. If you use modules then this is not good.

If anyone else is going to get stuck on this, I stumbled upon the same problem and I’ve noted down my solution in a wiki article.