Я динамически загружаю модели в функцию общего назначения, и я заметил, что иногда я хочу пропускать модели загрузки, потому что он вызывает ошибку 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')
возвращает все имена моделей в виде массива