这是一个最佳实践问题,而不是一个特定的问题。我对 MVC 方法和 Yii 相当陌生,并且在应用程序上开发已经有一段时间了。我一直看到关于最佳实践以及将什么放入哪个文件(控制器、模型、视图、帮助程序等)的讨论,但我还没有找到任何具体的例子。
我目前有这样的调用:我的视图文件中的Model::function()
以及$var = app()->request->getParam(value, false);
我的控制器文件中有调用,例如 Model::function() 和 Model::model()->scope1()->scope2()->findAll() 我也认为我的控制器文件变得有点厚,但不确定如何以及在哪里放置一些膨胀,我一直在阅读有关 DRY 的信息,我认为我并没有完全 DRY 我的代码可以这么说。您能否更清楚地了解什么去哪里,以及为什么:)的建议或原因感谢任何建议,提前感谢。
下面是视图文件中的示例调用
<?php
$this->pageTitle = 'Edit Action';
$this->subTitle = '<i>for</i> <b>' . Vendors::getName($_GET['vendor']) . '</b>';
?>
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model' => $model)); ?>
</div>
getName 是我在模型中的函数,这是在视图中调用函数的好方法吗?
另一个示例视图文件:
<div class="wrapper">
<?php
if($this->action->id != 'create') {
$this->pageTitle = "New Media Contact";
echo $this->renderPartial('_form', array('model'=>$model));
} else {
$this->pageTitle = "New Vendor";
echo $this->renderPartial('_form', array('model'=>$model));
}
?>
</div>
$model在控制器中设置,类型为...同样的问题...这能做到吗..清洁工。。?在MVC和可重用性/DRY方面更好?
编辑在阅读了这里的一些回复后,尤其是@Simone我重构了我的代码,并想分享它现在的样子......
public function actionCreate() {
$model = new Vendors;
// Get and Set request params
$model->type = app()->request->getParam('type', Vendors::VENDOR_TYPE);
$vendorsForm = app()->request->getPost('Vendors', false);
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if ($vendorsForm) {
$model->attributes = $vendorsForm;
if ($model->save())
$this->redirect(array('/crm/vendors', array('type' => $model->type)));
}
$model->categories = Categories::getAllParents($model->type);
$this->pageTitle = 'New ' . Lookup::item('VendorType', $model->type);
$this->render('create', array(
'model' => $model,
));
}
和视图创建.php
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model'=>$model));?>
感谢所有回复
我对 Yii 框架不太熟悉,但可以就你提到的一些具体事情提供一些建议:
不要太纠结于"最佳实践",因为就像所有设计模式MVC都可以实现一样,在某些情况下,不同的开发人员可以以许多不同的方式进行解释。这是什么意思呢?这意味着尽可能多地阅读MVC,然后简单地试一试:o)当您遇到问题时,您很快就会发现哪些插槽在哪里以及为什么(这通常是沿着"这属于哪里,控制器或型号?..."的思路。
就什么去哪里而言,你可以谷歌/搜索stackoverflow或在无数的书中阅读许多关于应该做什么和去哪里的解释,但从你提供的代码片段中,我建议:
查看文件:(除非这是 Yii 特定的东西)在我看来,您的视图文件有点脏。您直接与模型交谈(这实际上是MVC的经典方法,而不是某些PHP应用程序采用"控制器是唯一允许与模型对话"的方法),但似乎您的视图正在尝试直接获取请求数据,对我来说,这不应该靠近视图。控制器应处理请求,使用模型进行验证,然后将输出传递到视图中。
模型:从小片段来看,这似乎没问题,但总的来说,要记住的一件重要事情是模型!=数据库(尽管有些人建议它是)。
控制器:从您的代码段来看似乎也很好,但是要解决控制器中的膨胀问题,如果没有看到您的控制器之一,很难提供建议。始终值得考虑的一件事是服务的使用。基本上,服务可用于通过封装大量重复/复杂的模型内容来大大简化您的控制器。因此,您不必在控制器中调用单独的验证和持久性模型,而只需实例化一个服务类,它可能只是调用一种方法(该方法通常返回一个布尔值以指示控制器操作的成功或失败),然后控制器只需要处理它最擅长(并且应该只执行)应用程序流的操作(即重定向到另一个页面, 显示错误等)。
我将向您展示一个重构代码的示例。这是你的代码
<div class="wrapper">
<?php
if($this->action->id != 'create') {
$this->pageTitle = "New Media Contact";
echo $this->renderPartial('_form', array('model'=>$model));
} else {
$this->pageTitle = "New Vendor";
echo $this->renderPartial('_form', array('model'=>$model));
}
?>
</div>
第一个问题是:为什么要用 renderPart 写两行相同的行?第一次重构:
<div class="wrapper">
<?php
if($this->action->id != 'create') {
$this->pageTitle = "New Media Contact";
} else {
$this->pageTitle = "New Vendor";
}
echo $this->renderPartial('_form', array('model'=>$model));
?>
</div>
现在第二步:
<?php $this->pageTitle = $this->action->id != 'create' ? "New Media Contact" "New Vendor"; ?>
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
</div>
对我来说更具可读性。我认为有很多最佳实践。但可能会成为在不良环境中使用的不良做法。所以。。。重写代码真的有用吗?对我来说是的!因为我的目标是代码的可维护性。易于阅读,易于管理。但是你需要找到你的标准或你的团队标准。另外,我更喜欢在控制器中移动任何类型的逻辑。例如,我可以在控制器中设置默认的 pageTitle,并在 actionCreate 方法中重新定义它:
class SomeController extends CController
{
public $pageTitle = "New Vendor";
function actionCreate ()
{
$this->setPageTitle("New Media Contact")
$this->render('view');
}
}
我的视图文件将变为:
<div class="wrapper">
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
</div>
我认为我们必须理解事物的责任:观点只是一种观点。
只需将视图视为仅显示数据的组件即可。它不应该执行数据库调用,与模型交互,创建新变量(或很少)等。如果要执行检查或使用某些数据等创建HTML块,请使用帮助程序来实现此目的。
视图将显示的数据将来自控制器。
控制器是大师,它将完成应用中的大部分工作:它将回答请求,在需要时向模型请求数据,将数据传递给视图并呈现它,等等。
在第一个示例中,只需将Vendors::getName($_GET['vendor'])
保存在控制器中的变量中,然后将其传递给视图。
此外,如果您不需要 model
的所有数据,请不要传递整个对象。
关于您的第二个代码段,首先您可以将echo
移出if
语句,因为它们是相同的。
一件好事是在控制器中执行检查if ($this->action->id != 'create')
,并为您的视图提供一个简单的布尔值:
if ($this->action->id != 'create') { // not sure if $this->action->id would remain the same, I don't know Yii
$media = true;
// or
// $page = 'media';
} else {
$media = false;
// or
// $page = 'vendor';
}
并根据控制器返回的值呈现部分。
在我看来,没有"最佳实践"。只要你不在一个团队中工作,或者想把你的脚本作为开源发布,几十个人必须使用它,就按照你喜欢和需要的方式使用框架。即使你和其他人一起处理代码,也没有"上帝赐予"的规则。
还有比问题更重要的事情,如果你"真的被允许"在你的视图中使用静态函数。