Php 在MVC中直接从控制器使用ORM类,这种做法不好吗?

Php 在MVC中直接从控制器使用ORM类,这种做法不好吗?,php,orm,doctrine,propel,Php,Orm,Doctrine,Propel,我最近深入研究了在我的CodeIgniter应用程序中使用ORM,其中一个是Propel。现在,这给了我基本上使用Propels类作为“模型”的能力,但是这是一个糟糕的实践吗 因此,我的控制器代码如下: <?php class Page extends Controller { function __construct() { parent::__construct(); } function in

我最近深入研究了在我的CodeIgniter应用程序中使用ORM,其中一个是Propel。现在,这给了我基本上使用Propels类作为“模型”的能力,但是这是一个糟糕的实践吗

因此,我的控制器代码如下:

<?php
    class Page extends Controller {
        function __construct() {
            parent::__construct();  
        }   

        function index() {
            $foo = FooQuery::create()->limit(10)->find();
            $data['content'] = array('foo'=>$foo);
            $this->load->view('home', $foo);    
        }
    }
?>

我想在继续开发我的应用程序之前解决这个问题。如果你认为这是不好的练习,那么我应该如何做这一点会很有帮助。


提前谢谢

是的,这是一种坏习惯

模型应该包含所有数据逻辑,并将其从程序的其余部分抽象出来。对于应用程序的其余部分来说,模型应该看起来像从中获取数据的黑匣子。如果您使用ORM作为您的模型,那么您可以将控制器与数据层紧密耦合


相反,创建您的模型,并在其中处理ORM。这样,如果您需要调整数据模型,您只需在一个地方(模型层)更改它,就可以知道抽象将保持不变。

我发现,当您的ORM遵循此模式时,这是一个偶尔必要的问题

我经常遇到的问题是,模型只表示数据结构的单个实例。将集合检索方法添加到模型中是没有意义的


这就是我过去使用服务层处理拉入模型集合的地方。尽管老实说,最近我只编写了一个控制器助手对象,它只是抽象了我的表对象。

随着现在使用的
查询
类,我认为与更“正式”的模型的区别越来越小。如果这将成为一个您发布到世界上的库,那么拥有一个抽象层将是一个优势,这样您就可以拥有不同的后端,但是如果它是一个内部应用程序,我只会使用
查询
类作为您的模型

但是请记住,
Query
类被创建为感觉像一个实际的对象,并且它们尽可能地隐藏关系部分。你可以利用这个优势。检查一下,特别是第三个答案:越来越多地进入
查询
类,这样您的控制器就不会觉得它使用了数据库

// Instead of this code in your controller,
// tightly coupled to your database logic
$books = BookQuery::create()
   ->filterByTitle('%war%')
   ->filterByPrice(array('max' => 10)
   ->filterByPublishedAt(array('max' => time()))
   ->leftJoin('Book.Author')
     ->where('Author.Name > ?', $fameTreshold);

// You would use this code in your controller
// and create small methods with the business logic in the BookQuery class
$books = BookQuery::create()
  ->titleContainsWord('war')
  ->cheap()
  ->published()
  ->writtenByFamousAuthors();

这在很大程度上取决于你在做什么以及为什么。在本例中,您将在查询中放入一个limit子句—这是业务逻辑还是显示逻辑?从我的角度来看,很难说这是业务逻辑——我得到的10个元素与模型无关——这就是我认为在一个页面中使用多少元素是有意义的。如果希望该规则在控制器之间保持一致,可以设置一些配置值来强制一致性。但是把它放在模型中只会使模型变得不必要的大(肥胖模型和肥胖模型之间有区别)

我想说的是,限制、订单和补偿通常不是业务逻辑。即使是一个简单的例子,也可能取决于具体情况。如果有一个连接,这是一个信号,有问题

简·法布里的例子大部分都很好。FilterBytle在我看来和TitleContaine剑术差不多。filterByPublishedAt(数组('max'=>time())比->published()差得多。通常,控制器对内部数据结构的了解越少越好

记住,最糟糕的“坏习惯”是一致性的缺失,但事实上确实如此。:-)检查:这对你来说应该是一本有趣的书。除了,Propel还有一本关于模型集合的书