新手刚看到定义控制器中独立操作那,请问定义独立操作的文件应放在哪个目录下?
@wenyudengdeng 哪里都可以,给定义个namespace 就可以了
问题好抽象,可以具体点不?
在和config
文件夹平行的一层新建一个actions
文件夹,然后你在里面新建类就行了。名称空间写namespace app\actions;
然后引用的时候就use app\actions\XXX
不就行了,我觉得文档说的挺明白的啊。
新手刚看到定义控制器中独立操作那,请问定义独立操作的文件应放在哪个目录下?
@wenyudengdeng 哪里都可以,给定义个namespace 就可以了
问题好抽象,可以具体点不?
在和config
文件夹平行的一层新建一个actions
文件夹,然后你在里面新建类就行了。名称空间写namespace app\actions;
然后引用的时候就use app\actions\XXX
不就行了,我觉得文档说的挺明白的啊。
经常这样使用
Page::findOne([
'a' => 'aa',
'b' => 'bb',
]);
生成的sql也是 where a = aa and b = bb
这次想使用
Page::findOne([
'a >' => 'aa',
'b <' => 'bb',
]);
这样不行,有啥好的方式实现吗?
Page::find()->where(['>', 'a', 'aa'])->andWhere(['<', 'b', 'bb'])->all();
再修改一个clistview的代码,代码如下
<?php $this->widget(
'zii.widgets.CListView',
array(
'dataProvider' => $courseDataProvider,
'itemView' => '_item_course',
'template' => '{items}',
'emptyText' => '<div class="col-sm-9">该分类暂时未有课程</div>'
)
); ?>
想请问一下在最后显示_item_course的页面元素中为什会出现在
<div id="yw0" class="list-view">
<div class="items">
......
</div>
</div>
导致该页面有些东西出现不正常
对啊,自动生成的东西会有这个存在的
如果不想要的话,不妨继承底层类重写过这个东西呢?
请问自己在本机上用compsoer安装的工程可以正常跑,但是放上github后在服务器clone下来后提示确实vendor文件,有人告诉我需要用composer安装,我不太理解,请问具体应该怎么做呢,另外,其中的机制是什么,为什么直接把工程clone下来不是应该具备所有需要的文件了吗,谢谢
vendor
目录都是一样的 而且原则上不允许任何手动修改,所以完全没有必要纳入版本控制(在.gitignore
里配置)。只需要知道composer.json
就能知道vendor
下都有什么,所以你克隆下代码后要安装vendor
。如果你怕本地安装的插件和服务器上的插件版本有差异导致bug,那么composer.lock
文件就可以起作用了,它记录了你当时安装插件的具体版本,团队其他小伙伴也可以根据lock文件安装和你完全一样版本的插件(包括yii2核心文件)。
因为.gitignore把vendor忽略掉了,你的情况,可以这样处理:
将根目录的.gitignore打开,注释掉对/vendor的忽略
在vendor目录写个shell删除vendor中的所有.gitignore文件,每次执行过composer对vendor目录中的内容有更新,就执行一下这个shell,这样保证所有vendor的文件都能放到git库。比如clean.sh,内容如下:
BTW,人家这样设计.gitignore是因为人家网速快,部署服务器的时候,执行一下composer update –prefer-dist即可得到vendor的文件。
帮忙顶下!
有忽略的文件。还得装忽略的文件
确定clone的根目录下有composer.json
和 composer.lock
;
安装好composer后到命令行到你的根目录下执行:
然后vendor就回来了。
请问如何输出连贯操作的sql语句?
比如 find()->all()
使用的什么sql语句?
如果你是想打印本次的Sql的话,可以用 $model->find()->createCommand()->getRawSql();
可以在网页底部的debugger看到,点击log可以看到你执行的sql语言(也就是连贯操作的sql语句);
比如在controller里面你执行 $query= ReleaseForm::find()->where(['type'=>1])->all();
注:源代码是这些:
在网页里你点击底部的log就可以看到:
这样就知道你执行了什么sql语句了
开启dev debug,然后URL:http://yourDomain/debug
echo $query->createCommand()->sql;
真 tm 难用
也可以不用getSql();
在updateAll这个方法上点进去:
转到这段代码:
再点击execute()方法进去,转到
然后在这一行打个断点: $rawSql = $this->getRawSql();
这里的$rawSql 就是原生sql;
这个对于增删改查都是实用的,还是要从原理出发哦
没配置路由之前可以正常打开 http://127.0.0.1:8000/word/backend/web/index.php?r=gii
配置了路由之后 同样的路径 打不开了
http://127.0.0.1:8000/word/backend/web/gii.html
能访问不?
路由配置为path模式,试试:http://127.0.0.1:8000/word/backend/web/index.php/gii
你的路由怎么设置的?代码贴出来。
http://127.0.0.1:8000/word/backend/web/gii
使用 showScriptName
需要你的 服务器 开启了 相应模块,比如 apache 的
详见 http://www.yiiframework.com/doc-2.0/guide-start-installation.html
gii是一个模块,你自己看看你改了路由之后是什么怎么访问模块的
http://127.0.0.1:8000/word/backend/gii.php
<?php
use yii\helpers\Html;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
use app\assets\AppAsset;
/* @var $this \yii\web\View */
/* @var $content string */
AppAsset::register($this);
?>
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
他是如何引入资源文件的?
用的yii2basic的layout/main.php
一切尽在Controller的render方法中,只有在控制器中render才会加载layout,在View的render方法中是不会自动加载layout
layout怎么引用进来我们已经知道了,那么在视图文件中怎么把资源注入到layout的头部或者底部呢?
每个Asset中都会用到以上这些资源注入方法,而在Layout中会有View::head()、View::beginBody()、View::endBody() 这些标记,在页面的输出<![CDATA[YII-BLOCK-HEAD]]>
就这一串这样子的字符。在View::endPage()的时候就会把注入的资源全部替换到页面上的每一个标记中。至于要指定注入到某一个标记中,需要指定上面的注入资源函数的第二个参数。AppAsset::register($this);
可以追踪下源码。大体是通过layout
里的$this->head()
$this->endBody()
这些方法添加进去的
刚刚研究出来,是如何引入资源文件,不过已经有高手解答了,哈哈
use app\controllers\SiteController;
$s = 'SiteController';
$model = new $s();
$s->index();
想把类名用变量代替 应该怎么写呢?
上面写法提醒没有这个类 Class 'SiteController' not found
不用use,尝试以下写法:
你不应该是使用$model->index();
来调用么
<form action="index.php?r=model" method="post">
Name:<input name="name"><br>
ID:<input name="id"><br>
Sex:<input name="sex"><br>
Age:<input name="age"><br>
<input type="submit" value="submit">
</form>
表单视图是这样的
public function actionIndex(){
$student = new Student();
if($student->load(Yii::$app->request->post())){
return $this->render('student_info',['student'=>$student]);
}else{
return $this->render('student');
}
}
控制器里面是这样的。为什么load返回的是false,属性名和表单名是相同的
load方法会读取键为类名的数组,并绑定到AR对象,所以你的表单name应该这样写:
你也可以使用yii自带的wiget
,或者yii\helpers\Html
下的active
系列方法生成表单。
表单文本框name不对, 应该是Student[name] Student[sex] 这样才可以
用yii提供的方法建立表单
他们都说了你表单错了,确实也错了。但你还可以修改load的参数来实现
Yii::$app->request->post 他这个方法,会自动都model的rule验证嘛?
自定义表单,第二个参数为空,要加上
$student->load(Yii::$app->request->post(), ”)
public function actionIndex(){
$student = new Student();
if($student->load(Yii::$app->request->post())){
return $this->render('student_info',['student'=>$student]);
}else{
return $this->render('student');
}
}
这是Controller里面的代码,post()返回的数组我查看了是有值的,load方法也执行过了,但是student对象的属性查看了依然为null,这是为什么?
发出你视图的代码,这样看不出什么问题
我也遇到了这个问题,研究了很长时间,后来决定看源代码。
打开 vendor/yiisoft/yii2/base/Model.php
load()方法调用了setAttributes($values, $safeOnly = true)。
$values就是我们post过来的数据,$safeOnly没有理解,默认true,但是load()在调用setAttributes()没有传递$safeOnly参数,导致默认$safeOnly等于true
setAttributes()方法中有这样一句
$attributes = array_flip($safeOnly ? $this->safeAttributes() : $this->attributes());
入托$safeOnly = true 调用 $this->safeAttributes(),否则调用$this->attributes()
这两个方法应该都是返回当前model所定义的字段数组,但是$this->safeAttributes()始终为[],我试了一下$this->attributes()可以正常返回字段数组。
所以解决办法:
在load()调用setAttributes()时,传递第二个参数$safeOnly为false,一共两处。
再测试成功了。 🙂
我一直在使用Laravel这个框架,非常的好用,而且感觉非常专业bug极少(目前我还没遇到过)。我也是刚接触yii这个框架,第一天就卡在了这里,看着官方教程做的。瞬间对这个框架没什么信心了。
我也一直在查是啥原因,感谢!!
应该是没用对吧
load()方法是考虑安全性的,所以load赋值成功的前提是你的model有rules,而且你的属性加了相关的rule
例如
这个问题 也可能是设置了 scenario 后, 但是Model里没有写需要验证的字段