如何将参数传递给 Yii 中的场景?

How to pass a parameter to a scenario in Yii?

如何将$id传递给搜索场景?也许在模型中看起来像这样,所以我可以在控制器中像这样调用:

$model = new job('search',$id);

我认为这将简单地完成工作而不需要任何场景

$model = new job;   
$model->search($id); 

但是如果我没能理解你的问题那么你也可以试试这个

$model = new job('search');
$model->search($id);

将场景视为可以在模型中使用的特殊变量。

$userModel = new User("register");
$userModel->setId = 10;

哪个是一样的

$userModel = new User();
$userModel->scenario = 10
$userModel->setId = 10;

在你的模型中

class Manufacturer extends CActiveRecord
{
        // :
   if ($this->scenario == 'register')  ...
        // :

}

我认为您正在尝试进行搜索。搜索是一回事,"scenario" 是另一回事。

场景用于验证规则,以便能够以多种方式验证同一模型,具体取决于您inserting/adding 或搜索数据的位置。

还有一个叫做'search'的场景被模型的search()方法使用了,但是我告诉你为什么:

有几种方法可以使用 Yii 在数据库中搜索内容,我会提到两种:

1) 通过使用 ClassName::model()->findCommandHere

还有几个:

ClassName::model()->findByPk($id);
ClassName::model()->findAll("id=$id");
ClassName::model()->findByAttributes(array('id'=>$id));

等等,更多在这里:http://www.yiiframework.com/doc/guide/1.1/en/database.ar#reading-record

2) 通过使用模型的 search() 方法

这种查找数据的方式主要用于轻松创建搜索页面并与数据网格结合使用。

如果您使用 GII 代码生成工具生成 CRUD 代码,它将为您生成所有部分,但我将解释每个部分的工作原理。

此代码来自 Yii 文件中的博客演示:

在控制器中,它定义了一个 $model 使用 Post class 和 'search' 作为场景。

$model=new Post('search');
if(isset($_GET['Post']))  // <- checks if there are search params in the URL
    $model->attributes=$_GET['Post']; // <- assigns all search params masively to the model (later you'll see why)
$this->render('admin',array(
    'model'=>$model,
));

这里的 'search' 场景告诉 Yii 在直接从 $_GET (URL) 分配搜索参数时使用什么验证规则。

您可以看到大量分配了参数以减少编写的代码,但$model->attributes=$_GET['Post']它与这样做相同:

$model->title=$_GET['Post']['title'];
$model->status=$_GET['Post']['status'];

在 Post 模型中,您可以找到搜索场景的验证规则。告诉 Yii 分配标题和状态字段是安全的,以便稍后在搜索中使用它们。

public function rules()
{
    return array(
        // ... //

        array('title, status', 'safe', 'on'=>'search'), 
    );
}

然后在 Post 模型中,您还可以看到 search() 实际用于获取数据的方法:

public function search()
{
    $criteria=new CDbCriteria;

    $criteria->compare('title',$this->title,true);

    $criteria->compare('status',$this->status);

    return new CActiveDataProvider('Post', array(
        'criteria'=>$criteria,
        'sort'=>array(
            'defaultOrder'=>'status, update_time DESC',
        ),
    ));
}

搜索方法创建一个 "criteria" 并使用您之前分配给该模型的值应用所需的过滤方式。请参阅 $this->title 它来自您在控制器中使用的 $model->attributes=$_GET['Post']

标准可以直接在模型上使用,例如Post::model()->findAll($criteria),但在这种情况下search()方法使用不同的东西,"data provider".

数据提供程序是一件好事,因为它在一个地方为您提供了很多工具,它 returns 您可以提供数据,还可以进行分页和排序,因此您不必为此手动定义更多代码(CPaginationCSort)。

最后,在视图 admin.php 中,在这种情况下,它将使用网格视图显示结果:

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        array(
            'name'=>'title',
            'type'=>'raw',
            'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'
        ),
        array(
            'name'=>'status',
            'value'=>'Lookup::item("PostStatus",$data->status)',
            'filter'=>Lookup::items('PostStatus'),
        ),

    ),
)); 

现在你可以看到在网格的配置中它传递了$model->search()方法作为网格应该使用的dataProvider

现在网格可以访问其余的 dataProvider 元素,例如排序、分页并将它们显示在页面上。

如果您不想使用 CGridView 因为它是一个非常基本的 table 而您想创建自己的 html 标记,您还可以检索 dataProvider 及其组件一一放置在您的 HTML 代码中并根据需要显示数据:

$dataProvider=$model->search(); // get the dataprovider from search method
$models=$dataProvider->getData(); // actually get the data (rows) and assign them to a $models variable that you can put in a foreach loop

// show pagination somewhere
$this->widget('CLinkPager', array(
              'pages' => $dataProvider->pagination,
          ));

// create sort links
echo $dataProvider->sort->link('title', 'Title');

所以我希望它能解决您对如何使用 Yii 处理 displaying/searching 数据的一些疑问。

建议你阅读官方手册:http://www.yiiframework.com/doc/guide/1.1/en/index

我还建议查看 API 并在那里搜索所有 Yii 组件以查看它们具有哪些方法和参数:http://www.yiiframework.com/doc/api/

手动探索框架代码库也是一种很好的学习方式。如果您不知道 CActiveDataProvider 是如何工作的,那么在代码中找到 CActiveDataProvider class 文件,您将看到它使用的所有方法和属性,所以对所有内容都这样做你不明白它是如何工作的。

另外,对于初学者,我建议使用一个很好的 IDE,即 auto-completes 代码,并允许您按住 Ctrl 键并单击 class 名称,它将找到原始文件的定义位置.我将 NetBeans 用于 PHP,在创建项目后,我将 Yii 框架文件添加到项目的包含路径中,这样 NetBeans 就知道如何找到 auto-complete 和 ctrl+click 的框架文件。

是的,您可以使用参数定义场景,但这包含在模型的 class 构造函数中

$model = new Job('search'); // creating a model with scenario search

如果你想包含更多参数,那么你需要使用createComponent - 记住,所有都是一个组件

$model = Yii::createComponent(array('class'=>'Job','scenario'=>'search'));