Yii2.0学习笔记完全版
Yii2.0学习笔记
1.搭建环境及目录结构
1.1搭建环境
参考1:Yii2.0框架下载安装- Yii中文网https://www.360docs.net/doc/c986306.html,/post/detail/35.html
参考2:yii2.0-advanced 高级版项目搭建(一)https://www.360docs.net/doc/c986306.html,/post/detail/1.html 1.2.目录结构
basic/ 应用根目录
composer.json Composer 配置文件, 描述包信息
config/ 包含应用配置及其它配置
console.php 控制台应用配置信息
web.php Web 应用配置信息
commands/ 包含控制台命令类
controllers/ 包含控制器类
models/ 包含模型类
runtime/ 包含Yii 在运行时生成的文件,例如日志和缓存文件
vendor/ 包含已经安装的Composer 包,包括Yii 框架自身
views/ 包含视图文件
web/ Web 应用根目录,包含Web 入口文件
assets/ 包含Yii 发布的资源文件(javascript 和css)
index.php 应用入口文件
yii Yii 控制台命令执行脚本
2.一些常规配置
2.1框架源的设置
在配置文件web.php中如下配置
$config = [
'vendorPath' => 'D:\xampp\htdocs\www\yii2-vendor',] 2.2设置默认布局
2)在所在的控制器中加入,
public $layout="mymain";
2.3设置默认控制器
在yii2-vendor\yiisoft\yii2\web. Application.php中
public $defaultRoute = 'index';//默认路由
2.4设置默认首页
在配置文件web.php中如下配置,
$config = [
'defaultRoute'=>'index',//设置默认路由]
2.5数据库连接配置
在配置文件db.php中如下配置,本人数据库为wxj,用户名root,密码为空
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=wxj',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];
2.6配置虚拟主机
1)修改虚拟主机配置文件:xampp\apache\conf\extra\httpd-vhosts.conf。给定相应的域名和地址
DocumentRoot "D:\xampp\htdocs\www\SQproject\WeixinPay\web"
ServerName https://www.360docs.net/doc/c986306.html,
ErrorLog "logs/https://www.360docs.net/doc/c986306.html,-error.log"
CustomLog "logs/https://www.360docs.net/doc/c986306.html,-access.log" common
2)找到C:\Windows\System32\drivers\etc\hosts
添加127.0.0.1 https://www.360docs.net/doc/c986306.html,
3)在URL地址中直接输入https://www.360docs.net/doc/c986306.html,
3.数据模型model
3.1 model格式
Model 类也是更多高级模型如Active Record 活动记录的基类,模型并不强制一定要继承yii\base\Model,但是由于很多组件支持yii\base\Model,最好使用它做为模型基类。
在model中主要是指定相应的表名和相应的规则
3.2 model数据库连接
在配置文件db.php中
return [
'class' =>'yii\db\Connection',
'dsn' =>'mysql:host=localhost;dbname=wxj',
'username' =>'root',
'password' =>'',
'charset' =>'utf8',
];
3.3model中的增删改查
在做增删改查是要引用数据模型use WeixinPay\models\WpUsers;
3.3.1添加数据
$model = newUser();
$model->username = 'username';
$model->age = '20';
$model->insert();
3.3.2删除数据
User::deleteAll('name = 小伙儿'); 删除name = 小伙儿的数据;
User::findOne($id)->delete(); 删除主键为$id变量值的数据库;
User::deleteAll('age > :age AND sex = :sex', [':age' => '20', ':sex' => '1']); 删除符合条件的数据;
3.3.3修改数据
先查询到用户名与密码匹配的数据—>再修改其密码- 执行写入动作
$rel = WpUsers::findOne(['username' =>$username, 'password' =>$oldpassword]);
$rel->password = $password;
if ($rel->save())
3.3.4查询
单表查询
User::find()->orderBy('id DESC')->all(); 此方法是排序查询;
User::findBySql('SELECT * FROM user')->all(); 此方法是用sql 语句查询user 表里面的所有数据;
User::find()->andWhere(['sex' => '男', 'age' => '24'])->count('id'); 统计符合条件的总条数;User::findOne($id); //返回主键id=1 的一条数据;
User::find()->where(['name' => 'ttt'])->one(); //返回['name' => 'ttt'] 的一条数据;
在用户表中以姓名为查询条件
$info = WpUsers::find()->where(['username'
=>$username])->asArray()->all();
在用户表中以姓名和密码为查询条件
$re = WpUsers::find()->where(['username' =>$username, 'password' =>$password])->asArray()->all();
多表联合查询查询
如要多表查询,先确定主表:如下主表(Relation关系表)
如下子表(programmer程序员表)
如下子表(project项目表)
1)在主表的model中引用需要关联的表即usemodel,然后在主表model中写需要关联表的方法;如下程序写法:以下为Relation为主表,其余为关联子表
public function getProgrammer()
{
// 第一个参数为要关联的子表模型类名,
// 第二个参数指定关联子表的id字段=>主表的uid,
return $this->hasOne(Programmer::className(), ['id' => 'uid']);
}
public function getProject()
{
// 第一个参数为要关联的子表模型类名,
// 第二个参数指定关联子表的id字段=>主表的pid
return $this->hasOne(Project::className(), ['id' =>
'pid']);
}
以下为project为主表,其余为关联子表
public function getProgrammer()
{
// 第一个参数为要关联的子表模型类名,
// 第二个参数指定子表的id =>关联主表的charge字段,
return $this->hasOne(Programmer::className(), ['id' =>'charge']); }
2)在控制器中引用该主表mode,在方法中如下写查询方法
两表查询如下:其中project是主表
Project::find()->joinWith('programmer')->asArray()->all();
如需条件过滤则:
Project::find()->joinWith('programmer')->where(['project.id'
=>$key])->asArray()->all();
如需联合3表查询则:注意表名小写
Relation::find()->joinWith('programmer')->joinWith('Project')->as Array()->all();
3.4数据验证
在model中写一个rules方法进行验证,
public function rules()
{
return [
[
['teacher_id', 'name', 'price', 'address', 'class_time', 'limit_num', 'description'],
'required',
'message' =>"请输入{attribute}",
'on' => ['create', 'update']
],
[['limit_num', 'teacher_id'], 'number', 'message' =>'请填入正确的{attribute}', 'on' => ['create', 'update']],
['class_time', 'compare_time', 'message' =>'{attribute}不能小于当前时间', 'on' => ['create', 'update']],
[
'limit_num',
'compare',
'compareValue' =>$this->use_num,
'operator' =>'>',
'message' =>'{attribute}不能大于已招人数,已招人数为:' . $this->use_num, 'on' =>'update'
],
['description', 'safe']
];
}
注意,有些验证类型不支持message,
['mobile', 'string', 'min' =>11, 'max' =>11, 'tooShort'
=>'{attribute}位数为11位', 'tooLong' =>'{attribute}位数为11位', 'on' => ['create', 'update']],
}
消息提示在tooShort和tooLong上面
4.视图层view
4.1格式
在views文件夹下建与控制器中的方法同名文件夹(所有文件夹名称小写)
视图文件为php文件,视图文件与1.1版本类似
4.2注册CSS或JS方法:
方法一:
1)因在asset/AppAset.php中封装了一个类如下:
namespace app\assets;
use yii\web\AssetBundle;
/**
* @author Qiang Xue
* @since 2.0
*/
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
'css/bootstrap.min.css',//布局
'css/font-awesome.min.css',//小图标
'css/ace-fonts.css',//字体
'css/ace.min.css',//公共部分
];
public $js = [
'js/jquery-2.0.3.min.js',
'js/bootstrap.min.js',
'js/ace.min.js',
'js/ace-extra.min.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
2)即在视图文件中只需引用该类
use app\assets\AppAsset;
AppAsset::register($this);
即可调用公共的类文件
3)如需个性化调用
方法二:
1)类似方法一,在asset/AppAset.php中封装了一个类如下封装的注册js方法public static function initJsAssets($js = '',$position = 3){ if(is_array($js) && !empty($js)){
foreach ($js as $key =>$value) {
if(!is_array($value['js'])){
self::initJsAssets($value['js'],$value['position']);
}
}
}
self::$obj->registerJsFile(self::$appAsset->baseUrl.'/js/'.$js .'?v='.Yii::getAlias('@webStaticJsVersion'),
['position'=>$position]);
}
2)在视图文件中先引用该类:如此便可以加载公共文件
use WeixinPay\assets\AppAsset;
AppAsset::initAssets($this);
3)如需个性化加载
use WeixinPay\assets\AppAsset;
AppAsset::initCssAssets('ace-skins.min.css',$this::POS_HEAD );
beginPage() ?>
head() ?>
beginBody(); ?>
endBody(); ?>
endPage() ?>
5.控制器层controller
5.1控制器格式
1)与1.1版本类似控制器名采用大驼峰式命名,注意使用命名空间;方法名采用小驼峰命名
2)如需使用自定义的布局public $layout = 'common';如果某方法
下不采用布局文件,可在方法内:$this->layout = false;
清除公共布局也可写一个方法控制:如下代码(指定login与rest页面布局不生效)
/**清除公共布局
* (non-PHPdoc)
* @see \yii\web\Controller::beforeAction()
*/
public function beforeAction($action)
{
if (!parent::beforeAction($action)) {
return false;
}
if ($action->id == 'login' or $action->id == 'r eset') {
$this->layout = false;
}
return true;
}
5.2 模板显示并传值
return $this->render('login');
return $this->render('sigleinfo', ['info' =>$info]);
return $this->redirect(Url::toRoute('wp-users/updatepwd')); 5.3页面提示消息
1)在控制器中
成功:
$session->set('username', yii::$app->request->post('username') );
失败:\Yii::$app->getSession()->setFlash('error', '您的用户名或密码输入错误');
2)在views中
先使用use yii\bootstrap\Alert;
再写提示信息
if (Yii::$app->getSession()->hasFlash('success')) {
echo Alert::widget([
'options' => [
'class' => 'alert-success', //这里是提示框的class ],
'body' => Yii::$app->getSession()->getFlash('succes s'), //消息体
]);
}
if (Yii::$app->getSession()->hasFlash('error')) {
echo Alert::widget([
'options' => [
'class' => 'alert-error',
],
'body' => Yii::$app->getSession()->getFlash('error' ),
]);
}
?>
5.4 post,get,session的使用
yii::$app->request->post('password');
yii::$app->session->get('username');
//打开session
use yii\web\Session;
$session = Yii::$app->session;
$session->open();
//设置session
$session = Yii::$app->session;
$session->set('user_id', '1234');
//销毁session
$session = Yii::$app->session;
$session->remove('user_id');
$session = yii::$app->session;
$session->open();
$session->set('username',yii::$app->request->post('username');
(yii::$app->session->get('username'))
6.gii的使用
6.1gii的配置
1)在config/web.php配置文件中
if (YII_ENV_DEV) {
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' =>'yii\gii\Module',
// 'allowedIPs' => ['127.0.0.1'], // 按需调整这里
];
}
2)在入口文件index.php中
defined('YII_ENV') or define('YII_ENV', 'dev');
3)通过URL 访问Gii:
http://localhost/index.php?r=gii
6.2用Gii 去生成数据表操作的增查改删(CRUD)代码
CRUD 代表增,查,改,删操作,这是绝大多数Web 站点常用的数据处理方式。选择Gii 中的“CRUD Generator” (点击Gii 首页的链接)去创建CRUD 功能。之前的“product” 例子需要像这样填写表单:
Model Class:app\models\Product
Search Model Class: app\models\ ProductSearch
Controller Class: app\controllers\ ProductController
如果你之前创建过controllers/ProductController.php和views/product/index.php文件选
中“overwrite” 下的复选框覆写它们(之前的文件没能全部支持CRUD)。
http://hostname/index.php?r=product/index
可以看到一个栅格显示着从数据表中获取的数据。支持在列头对数据进行排序,输入筛选条件进行筛选。
可以浏览详情,编辑,或删除栅格中的每个产品。还可以点击栅格上方的“Create Product” 按钮通过表单创建新商品。
总结:gii功能强大,使用Gii 生成代码把Web 开发中多数繁杂的过程转化为仅仅填写几个表单就行。
7.几个重要应用模块
7.1分页
7.1.1 Pagination
1) 引用分页类use yii\data\Pagination;
2)获取总条数$total = Myuser::find()->count();
3)实例化分页类并给参数
$pages = new Pagination(['totalCount' => $total, 'pageSize' => '2']);
4)获取数
$rows=Myuser::find()->offset($pages->offset)->limit($pages->limit)->asArray() ->all();
5) 显示模板并传值return $this->render('oper', ['rows' => $rows, 'pages' => $pages,]);
6)模板显示= \yii\widgets\LinkPager::widget(['pagination' => $pages]); ?>
7.1.2ActiveDataProvider(gii方法)
1)namespace app\controllers;
2)use yii\data\ActiveDataProvider;
3)$model = new Myuser();
$dataProvider = new ActiveDataProvider([
'query' => $model->find(),
'pagination' => [
'pagesize' => '10',//若是用gii自动生成的则在此改
]
]);
//$this->load($params);
return $dataProvider;
return $this->render('oper', ['model' => $model, 'dataPr ovider' => $dataProvider,]);
7.1.3代码实例
在控制器中查询总条数,实例化分页类,给定总条数及每页显示记录数,传值给模板
use yii\data\Pagination;
。。。。
$total = WpOrder::find()->where($where)->count();
$pages = new Pagination(['totalCount' =>$total, 'pageSize'
=>'10']);
$rows =
WpOrder::find()->where($where)->offset($pages->offset)->limit( $pages->limit)->asArray()->all();
return $this->render('index', ['rows' =>$rows, 'pages' =>$pages, 'state' => yii::$app->request->get('status'),
'id' => yii::$app->request->get('mch_id'),
'Merchant'=>$Merchant
]);
在视图显示中,设置显示效果(首页,末页…)
'pagination' =>$pages,
'firstPageLabel' =>'首页',
'lastPageLabel' =>'末页',
'prevPageLabel' =>'上一页',
'nextPageLabel' =>'下一页',
]); ?>
7.2.文件上传
7.2.1单文件上传
NewsController中
public function actionCreate()
{
$model = new News();
$rootPath = "uploads/";
$thumbPath = "thumb/";
if (isset($_POST['News'])) {
$model->attributes = $_POST['News'];
$image = UploadedFile::getInstance($model, 'image'); $ext = $image->getExtension();//获取扩展名
$randName = time() . rand(1000, 9999) . "." . $ext; $path = date('Y-m-d');
$rootPath = $rootPath . $path . "/";
$thumbPath = $thumbPath . $path . "/";
//echo $rootPath;exit();
if (!file_exists($rootPath)) {
mkdir($rootPath, true, 0777);
}
if (!file_exists($thumbPath)) {
mkdir($thumbPath, true);
}
$re = $image->saveAs($rootPath . $randName);//返回bool值$imageInfo = $model->image = $rootPath . $randName; $model->image = $imageInfo;
if (!$model->save()) {
print_r($model->getErrors());
}
if ($re) {
$this->redirect(Url::toRoute('create'));
}
} else {
return $this->render('create', ['model' =>$model,]);
}
}
验证规则如下(New.php)
public function rules()
{
return [
[['title', 'image', 'content'], 'required'],
[['content'], 'string'],
[['title'], 'string', 'max' =>50],
//[['image'], 'string', 'max' => 100],
[['image'],'file','extensions'=>'png,jpg','mimeTypes'=>'image/ png,image/jpeg',]
];
}
7.2.2多文件上传
更改之处_Form.php中
= $form->field($model,
'image[]')->fileInput(['multiple'=>true]) ?>
NewsController中
public function actionCreate()
{
$model = new News();
$rootPath = "uploads/";
$thumbPath = "thumb/";
if (isset($_POST['News'])) {
$model->attributes = $_POST['News'];
$images = $model->file = UploadedFile::getInstances($model,
'image');
// $ext = $this->file->extension;
$path = date('Y-m-d');
$rootPath = $rootPath . $path . "/";
$thumbPath = $thumbPath . $path . "/";
//echo $rootPath;exit();
if (!file_exists($rootPath)) {
mkdir($rootPath, false, 0777);
}
if (!file_exists($thumbPath)) {
mkdir($thumbPath, false);
}
foreach ($images as $image) {
$ext = $image->getExtension();//获取扩展名
$randName = time() . rand(1000, 9999) . "." . $ext;
$re = $image->saveAs($rootPath . $randName);//返回bool值$imageInfo = $model->image = $rootPath . $randName;
$model->image = $imageInfo;
if (!$model->save()) {
print_r($model->getErrors());
}
if ($re) {
$this->redirect(Url::toRoute('create'));
}
}
} else {
return $this->render('create', ['model' =>$model,]);
}
}
7.3验证码
1)创建数据表,在表中写验证规则
/**
* 验证码验证规则
* @return array
*/
public function rules()
{
return [
[ 'verify','captcha']
];
2)控制器
php
namespace app\controllers;
use app\models\Myuser;
use Yii;
use yii\helpers\Url;
use yii\web\Controller;
use yii\data\Pagination;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
class UserController extends Controller
{
public $verify;
public $layout = "mymain";
public $enableCsrfValidation = false;//清除Unable to verify your data submission.
// public $layout = false;//清除布局
public function action()
{
return [
'error' => [
'class' =>'yii\web\ErrorAction',
],
'captcha' => [
'class' =>'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
'backColor' =>0x000000,//背景颜色
'maxLength' =>6, //最大显示个数
'minLength' =>5,//最少显示个数
'padding' =>5,//间距
'height' =>40,//高度
'width' =>130,//宽度
'foreColor' =>0xffffff,//字体颜色
'offset' =>4,//设置字符偏移量有效果
],
];
}
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
// 'class' => 'yii\captcha\CaptchaAction',
'only' => ['logout', 'signup', 'login'],//这里一定要加
'rules' => [
[
'actions' => ['login', 'captcha'],
'allow' =>true,
'roles' => ['?'],
],
[
'actions' => [
'logout',
'edit',
'add',
'del',
'users',
'thumb',
'upload',
'cutpic',
'follow',
'nofollow'
],
'allow' =>true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
public function actionIndex()
{
$model = new Myuser();
if (Yii::$app->request->isPost) {
$userName = Yii::$app->request->post('userName');
$passWord = Yii::$app->request->post('password');
$re = Myuser::find()->where(['userName' =>$userName, 'password' =>$passWord])->one();
//$re = Myuser::find()->where(['userName' => $userName, 'password' => $passWord])->asArray()->one();
// var_dump($re);exit();
if ($re != null) {
echo "登录成功";
$this->redirect(Url::toRoute('index/index'));
//echo Url::toRoute('index / index');
} else {
echo "登录失败";
}
}
return $this->render('index', ['model' =>$model]);
}
由于是在原来的基础上改的,因此部分input是自己写的
php
use yii\helpers\Url;
use yii\widgets\ActiveForm;
use yii\captcha\Captcha;
?>
'id' =>'user-form'
]) ?>
user:
pwd :
field($model,
'verify')->textInput(['maxlength' =>30]) ?>
=>'captchaimg', 'imageOptions' => [
'id' =>'captchaimg',
'captchaAction' =>'login/captcha',
'title' =>'换一个',
'alt' =>'换一个',
'style' =>'cursor:pointer;margin-left:25px;'
], 'template' =>'{image}']);?>
7.4 Url美化
a期望路径格式:http://localhost/user/index.html
b在config/web.php中改配置,具体如下
//开启重写功能
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'suffix'=>'.html',//即以.html结尾
'rules'=>[
],
],
c.在/basic/web下面添加.htaccess文件
至此成功设置可访问首页测试
具体可访问网址:https://www.360docs.net/doc/c986306.html,/post/detail/5.html
7.5 发送邮件
1)配置参数,在配置文件(main.php)中
'components' => [ ]里
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => 'https://www.360docs.net/doc/c986306.html,',
'username' => '155********@https://www.360docs.net/doc/c986306.html,',
'password' => 'wangxiaojun21269',
'port' => '25',
'encryption' => 'tls',
]
],
其中host=>即为用于发邮件的用户名,password=>不是邮箱密码,而是授权码,port=>是邮箱端口号,
2)获取授权码
登录邮箱后在导航条中-->设置-->常规设置下有:POP3/SMTP/IMAP/-->在此获取授权码并开启服务
3)在控制器
public function actionSendemail(){
if(yii::$app->request->isPost){
$sendmail=yii::$app->request->post('email');
$body="http://paycenter.ka.social-t https://www.360docs.net/doc/c986306.html,:31080/wp-users/reset";
$mail= \Yii::$app->mailer->compose();
$mail->setTo($sendmail);
$mail->setSubject("找回密码");
$mail->setHtmlBody($body);