drodata
从你写的代码来看,你似乎是想在 userInfo 数据写入前,通过检查 SQL 语句的方式判断前面的赋值操作是否都正确。但是 insert/update 都属于 Non-SELECT 操作,不使用 yii\db\Query 构建查询,因此不能使用 createCommand(),也没有 getSql() 这一说。AR 模型
执行写入操作的代码见这里。- drodata 回复了话题 让 where() 链式操作可以不被覆盖
Yii 其中一个特点是高度可定制,任何一个核心类都可以经过自定义,变得适合自己的项目或操作习惯。例如你觉得默认的 where() 不好用,那就自己改一下,让它用着更加顺手。
这是Yii2设计的不太好的一个方面。干嘛不把where()的功能弄的再强大点
我认为这见仁见智吧。如前所述,Yii 已经提供了让核心类“变强大”的方式,像 where() 这种使用频率高、基础的方法,更多考虑的是如何设计得足够通用,就像《迷你世界》里面的石块一样,使用同
一个的石块,不同的玩家可以发挥想象力,盖出各种漂亮的建筑。最后简单一个我日常使用 ActiveQuery 的习惯,抛砖引玉,仅供参考:
常用的查询条件尽可能在 AcriveQuery 内以方法的形式定义
以楼主举的学生、老师模型为例,可以在 StudtentQuery 内定义如下常用方法:
public function youngerThan($age) { return $this->andWhere(['<', '{{%student}}.age', $age]); } public function male() { return $this->andWhere(['{{%student}}.sex' => 1]); } public function toughtBy($teacherIds) { return $this->andWhere(['{{%teacher}}.id' => $teacherIds]); }
方法只要定义得恰当,构建 AcriveQuery 时可以少用甚至不用 where() , andWhere() 或 orWhere(). 例如,我想查一下所有年龄小于 18 岁、同时被张三和李四两位老师教的男同学,就可以这样写:
$students = Student::find()->joinWith(['teacher'])->youngerThan(18)->taughtBy([3, 5])->male()->all();
- drodata 回答了问题 文章置顶排序错了,麻烦大佬来帮忙下,谢谢
orderBy() 用错了。
public function orderBy($columns) { // 注意这里是直接赋值 $this->orderBy = $this->normalizeOrderBy($columns); return $this; }
https://github.com/yiisoft/yii2/blob/master/framework/db/QueryTrait.php#L323
从上面的代码可以看出, orderBy() 不能像 andWhere() 那样使用链式操作,你的写法会导致第一个 orderBy() 被覆盖。正确的写法:
->orderBy([ 'FIND_IN_SET(`a`, `attr`)' => SORT_DESC, // SORT_DESC 是 PHP 内置常量 'date' => SORT_DESC, ])
Tip:如果查询语句返回的结果与自己期望的不相符,可以借助
yii\db\Command
的rawSql
属性返回原生的 SQL 语句,通过 SQL 语句判断构建的 ActiveQuery 是否有问题。拿你遇到的这个问题来说,当你发现文章的排序有问题后,首先可以做的就是使用:echo Article::find() ->select(...) ->where((...)) ->orderBy((...)) ->orderBy((...)) ->createCommand()->rawSql;
返回 SQL 语句,看看构建的语句是否存在问题。一看 SQL 中 order by 从句是
order by date DESC
, 就会立刻意识到问题出在 orderBy() 那里了。 - drodata 回答了问题 类似于访问的东西求解答
上图是 GridView 中 ActionColumn 中的一个截图,可以根据用户的权限决定链接是否可以点击,和你要的效果类似。通过配置 DataColumn
buttons
可以实现,例如:[ 'class' => 'drodata\grid\ActionColumn', 'template' => '{view}', 'buttons' => [ 'view' => function ($url, $model, $key) { if (in_array($model->id, [1, 3, 5]) { echo Html::a('view', '#'); } else { echo 禁用图标 } }, ], ]
AdminLTE 默认使用 FontAwesome, 哪些图标能用跟 Bootstrap, Yii 无关。直接到 https://fontawesome.com/icons 查找即可。
@高飞龙 FontAwesome 官网默认是 5.0 版本,图标不能用说明版本不一致。确认一下你的 AdminLTE 里 FontAwesome 的版本号,根据版本号到对应版本的文档内查图标。
AdminLTE 默认使用 FontAwesome, 哪些图标能用跟 Bootstrap, Yii 无关。直接到 https://fontawesome.com/icons 查找即可。
你用会话模型构建 dataProvider 就能同时把会话和反馈两个模型的所有列显示在一张表内。否则只能在反馈表格内通过新建一个虚拟列手动拼装了。