如何使用CakePHP检查模型是否存在?

如何使用CakePHP检查模型是否存在?,php,cakephp,Php,Cakephp,我在一个通用函数中动态加载模型,我注意到有时我想跳过加载模型,因为它会引发404错误 如何检查模型是否存在 比如: if($this->modelexists($type) { $this->loadModel($type); } else { return "xxx"; } 对于1.3,您可以使用 App::import('Model', 'ModelName'); 如果不存在,则返回false 对于2.x,我还没有找到一个有效的解决方案,因为您还没有指定您的版本,所以

我在一个通用函数中动态加载模型,我注意到有时我想跳过加载模型,因为它会引发404错误

如何检查模型是否存在

比如:

if($this->modelexists($type) {
  $this->loadModel($type);
} else {
  return "xxx";
}
对于1.3,您可以使用

App::import('Model', 'ModelName');
如果不存在,则返回false


对于2.x,我还没有找到一个有效的解决方案,因为您还没有指定您的版本,所以我将我的答案分成两部分,一部分用于1.3,另一部分用于2.0

CakePHP 1.3

loadModel()
方法如果找不到模型,将返回false,请参阅。所以只需检查它是否返回false,如:

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

如果模型类不存在,
loadModel()
方法将抛出一个
missingmodeleexception
,因此只需捕获它即可

看这上面的图片

例如:

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

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

您可以将其添加到AppController中,并与&\uu get()结合使用,以根据需要自动加载模型。在这种情况下,您可能需要使用一个成员变量(例如$this->model_list)来保存列表,这样您就不必每次都调用App::objects()。

我对Adam的函数做了一个小调整,以允许使用插件:

  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目录的支持

我还合并了插件和模型类变量(为了方便起见,可以称为数组或字符串)

以下是新功能:

  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'])


//注意:如果希望在php版本<5.4

上部署,请使用array()而不是[]这对我来说和cake 2一样有效

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

通过
App::objects('Model')
它将所有模型名称返回为array

您正在运行的CakePHP的哪个版本?这并不能解决问题,因为如果我尝试初始化一个不存在的模型,它仍然返回一个404,我只需通过models dir检查文件是否存在:)与类_existi结合使用我认为这不是最安全的方法,但我会考虑它注意,
loadModel()
仅存在于控制器中。在其他任何地方,请使用下面的标记回答的
App::import()
。这在2.x中不起作用,尽管文档中说它起作用。这里的文档:假设抛出异常,$this->loadModel()将返回false。然而,在进一步的检查中,我发现了一个与此相关的Cake PHP问题,它说文档是错误的:文档是错误的,因为在没有模型文件的情况下,CakePHP会动态生成模型。就我个人而言,我觉得这很烦人。在许多情况下,您可以通过捕获
MissingTableException
来解决此问题。