我想将两个函数组合在一起,以合并代码,并根据其使用方式进行动态调整。我不知道这是否可能。
首先,让我们介绍一下基本用途。在我的示例中,我有Post和PostCategory模型(以及构建的CRUD)。创建一个类别,然后创建一个新帖子并将其分配给该类别。帖子可以是enabled
或disabled
。从本质上讲,你可以创建一些新的帖子,让最终用户在你准备好之前看不到它们。一个用例是滴注系统,您可以添加100个帖子,并每x天切换到enabled
。这超出了这个范围。
views''post_form.php
<div class="post-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'category_id')->dropDownList(
$model->getPostCategoryConst(),
['prompt'=> '- Category -']
)->label('Category')
?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'text')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'status')->dropDownList(
$model->getPostStatusConst(),
['prompt'=> '- Status -']
) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
注意category_id
和status
的下拉列表以及它们调用的函数
''common''models''Post.php
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
public function getCategory()
{
return $this->hasOne(PostCategory::className(), ['id' => 'category_id']);
}
/* -- Added -- */
public function getPostCategoryConst()
{
return ArrayHelper::map(PostCategory::find()->orderBy('name DESC')->all(), 'id', 'name');
}
public function getPostStatusConst()
{
return [
self::STATUS_DISABLED => 'Disabled',
self::STATUS_ENABLED => 'Enabled',
];
}
现在这很好:)然而,我不喜欢像在getPostStatusConst()
中那样使用get
,因为它不像$model->postStatusConst
那样访问,类似于与"getter"的关系。
不过,我也想把这些作为"getter"。在索引和视图中,最好也调用相同的函数。不返回数组,而是返回一个"漂亮的名称",如"Enabled"或"Disabled"
出于这个原因,我不会重命名函数,因为我不想再添加任何混乱。
views''post''view.php
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'category.name',
'name',
'text:ntext',
'postStatusConst', // <-- Calls getPostStatusConst()
'created_at:datetime',
'updated_at:datetime',
],
]) ?>
请注意,postStatusConst
与_form
中用于创建操作的函数相同。在_form中,它需要为下拉列表返回一个数组。在我们看来,它只需要返回一个不错的名称,如Enabled
或Disabled
。
我试过了
我在Post模型中尝试了这个功能:
public function getPostStatusConst()
{
if ( isset($this) ) {
return ($this->status === self::STATUS_ENABLED) ? 'Enabled' : 'Disabled';
}
return [
self::STATUS_DISABLED => 'Disabled',
self::STATUS_ENABLED => 'Enabled',
];
}
这显然不起作用:)我没想到会这样,因为我知道$this
在类中引用了自己。它只是表明了我的目标。
在关系中,hasOne()
似乎知道我们是将其用作直接调用(Post::getCategory)还是内联调用($model->category->name)。。
问题
有可能让getPostStatusConst()
也这样做吗?使用作为$model->postStatusConst
可以很好地显示Enabled
或Disabled
,或者使用作为Post::getPostStatusConst()
可以获得下拉列表的数组。
这是可能的,但实际上不值得对代码进行所有更改。您必须重写magic __get()
方法,并考虑在一个结构中存储和访问两个返回的方法。
我会将getPostStatusConst()
保留为当前状态名称,并将其他方法(甚至是静态方法)添加为下拉列表的状态列表。
我非常接近。我没有想到PHP OOP行,而是更多的Yii。在谷歌上搜索了几次,我拍了拍额头。使用框架时,有时甚至会忘记用PHP编写;)
public function getPostStatus()
{
if ( isset($this) && get_class($this) == __CLASS__) {
// not static
return ($this->status === self::STATUS_ENABLED) ? 'Enabled' : 'Disabled';
}
return [
self::STATUS_DISABLED => 'Disabled',
self::STATUS_ENABLED => 'Enabled',
];
}
我重命名了这个函数,使它更有意义。
它在任何地方都有效。让我们看看我的CRUD:的索引
views''post''index.php
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii'grid'SerialColumn'],
'id',
'category.name',
'name',
//'text:ntext',
'postStatus',
// 'created_at',
// 'updated_at',
['class' => 'yii'grid'ActionColumn'],
],
]); ?>
views''post''view.php
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'category.name',
'name',
'text:ntext',
'postStatus',
'created_at:datetime',
'updated_at:datetime',
],
]) ?>
和views''post_form.php
<?= $form->field($model, 'status')->dropDownList(
Post::getPostStatus(),
['prompt'=> '- Status -']
) ?>
所有这些案子似乎都很管用。有人有任何情况不起作用吗?