Как проверить, существует ли модель с CakePHP?

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

Как проверить, существует ли модель?

Что-то вроде:

if($this->modelexists($type) { $this->loadModel($type); } else { return "xxx"; } 

Поскольку вы не указали свою версию, я разделил свой ответ на два, один для 1.3 и один для 2.0.

CakePHP 1.3

Метод loadModel() возвращает false, если он не может найти модель, см. Документацию API . Так что просто проверьте, не возвращает ли false:

 if(!$this->loadModel($type)) { return "xxx"; } 

CakePHP 2.0

Если класс модели не существует, метод MissingModelException loadModel() будет генерировать MissingModelException , поэтому просто поймайте его.

См. Документы API по этому вопросу.

Пример:

 try { $this->loadModel($type); } catch(MissingModelException $e) { // Model not found! echo $e->getMessage(); } 

CakePHP 2.x

 function model_exists($type){ $model_list = array_flip(App::objects('model')); return isset($model_list[$type]); } 

Вы можете добавить это в AppController и использовать в сочетании с & __ get () для автоматической загрузки модели, если хотите. В этом случае вы можете использовать переменную-член (например, $ this-> model_list), чтобы сохранить список, поэтому вам не нужно каждый раз вызывать App :: objects ().

Я сделал небольшую настройку для функции Адама, чтобы также включить плагины:

  public function modelExists($modelClass, $plugin=null){ $object = 'model'; if($plugin){ $object = $plugin.'.'.$object; } $model_list = array_flip(App::objects($object)); return isset($model_list[$modelClass]); } 

Остается одна проблема. Кажется, он не забирает модели в каталоге Lib / Model.

Пока этого не удалось. Будет ли обновлять пост, если найду решение.


Я просто добавил поддержку каталогов lib

Я также объединил модули plugin и modelClass (их можно назвать массивом или строкой для удобства)

Вот новая функция:

  public function modelExists($modelClass, $checkLoaded=true){ $modelClass = !is_array($modelClass)?$modelClass:implode('.', $modelClass);//implode if is array list($plugin, $modelClass) = pluginSplit($modelClass, true); $plugin=rtrim($plugin,'.'); $object = 'model'; if($plugin){ if($checkLoaded){ if(!CakePlugin::loaded($plugin)){ return false; } } $object = $plugin.'.'.$object; $libPaths = App::path("Lib/Plugin/$plugin"); } else { $libPaths = App::path('Lib'); } $list = App::objects($object, null, false); foreach($libPaths as $path){ $libModels = App::objects('lib.'.$object, $path.'Model'.DS, false ); if(is_array($libModels)){ $list = Hash::merge($list, $libModels); } } if(in_array($modelClass, $list)){ return true; } return false; } 

Применение:

его можно назвать так:

$ This-> modelExists ( 'SomeModel');

$ This-> modelExists ( 'Plugin.SomeModel');

$ This-> modelExists ([ 'SomeModel']);

$ this-> modelExists (['Plugin', 'SomeModel']);

// Обратите внимание на использование array () вместо [], если вы планируете развернуть версию php <5.4

для 1.3 вы можете использовать

 App::import('Model', 'ModelName'); 

который возвращает false, если он не существует

Для 2.x я еще не нашел рабочего решения

это работает для меня, как для торта 2

 if (in_array($model, App::objects('Model'))) { $this->loadModel($model); } else { return 'error'; } 

by App::objects('Model') возвращает все имена моделей в виде массива