Yii框架学习笔记

1、Yii框架工作流程(MVC文件后缀都是php):
models文件夹下建模型,写AR类、对应数据库相关表、定义属性标签、写验证规则、保存表之前调用的方式,用于保存非表单获取的默认数据(如添加数据的时间等,此步如不需要可省略)->controllers文件夹下建控制器、写保存表单的动作->views文件夹下建模板,动态显示视图。

2、YII中各种类
模型中添加:

use yii\base\Model;
use yii\db\ActiveRecord;			//活动记录,简称AR,用于访问数据库,一个AR类关联一张数据表
use yii\web\IdentityInterface; 		//认证接口,登录(身份接口)

控制器中添加:

use yii\web\Controller;
use frontend\models\Test;			//引入前台模型中的AR类
use yii\helpers\Url;				//url助手类
use Yii;							//使用这个后,在控制器动作中的\Yii::$app可以直接写成Yii::$app
use backend\models\Product; 		//调用后台产品模型类
use yii\data\Pagination;			//分页类
use backend\models\UploadForm; 		//上传模型类
use yii\web\UploadedFile; 			//上传功能类
use yii\filters\AccessControl;		//授权类

视图中添加:

use yii\helpers\Url;				//url助手类,用于生成URL
use yii\widgets\ActiveForm;			//借助小部件,动态生成表单(创建表单类)
use yii\widgets\LinkPager;			//显示分页类
<?php
	$this->title="首页";				//定义页面title名称,用于布局中
	//$this->title = $info->title; 	//设置页面标题,同上方
    //<link rel="stylesheet" type="text/css" href="css/ssss.css"/>
    //$this->registerCssFile('css/ssss.css');	//添加css到布局中,布局中要有$this->head();meta标签和link标签, 需要调用此方法动态生成
    //<script src="js/aa.js"></script>
    //$this->registerJsFile('js/aa.js');		//加载到布局中$this->endBody()这个位置,</body>前
    /*
    添加关键词和简介标签
    <meta name="keywords" content="">
    <meta name="description" content="">
    */
    //$this->registerMetaTag(['name'=>'keywords','content'=>'网站关键字']);
    //$this->registerMetaTag(['name'=>'description','content'=>'简介']);
?>

3、使用布局-包含文件

public $layout = 'main';						//属性-使用布局-包含文件,不想使用布局设置false

4、视图中调用视图-相当于包含文件

<?= $this->render('/index/_leftlxwm'); ?>		//视图中调用视图

5、模型中的写法

<?php
    namespace frontend\models;
    use yii\db\ActiveRecord;
    //模型命名不用带有model和.class
    class Msg extends ActiveRecord {
        //设定对应表,如果此步省略, 代表表名和类名一致(表前缀,在配置中设置)
        public static function tableName() {
            return '{{%msg}}';						//return 'msg';表名,如果配置里设置了表前缀,那么{{%msg}}是给msg表加前缀的
        }
        //定义属性标签,固定函数
        public function attributeLabels() {
            return[
                'title' => '留言主题',
                'sex' => '性别',
                'tel' => '联系电话',
                'lxr' => '联系人',
                'content' => '留言内容'
            ];
        }
        
        //验证规则,固定函数
        public function rules() {
            return[
                [['title','sex','tel','lxr','content'],'required','message' => '{attribute}不能为空'],
                ['title','string','min' => 4,'max' => 30,'tooShort' => '{attribute}最小长度必须在4个字以上','tooLong' => '{attribute}最大长度必须在30个字以内'],
                ['tel','match','pattern' => '/^1[34578]\d{9}$/','message' => '手机格式不正确'],
                ['lxr','match','pattern' => '/^[\x{4e00}-\x{9fa5}]+$/u','message' => '{attribute}只能使用中文'],
                ['content','string','min' => 10,'max' => 140,'tooShort' => '{attribute}最小长度必须在10个字以上','tooLong' => '{attribute}最大长度必须在140个字以内']
            ];
        }
        //保存表之前调用的方式,用于保存非表单获取的默认数据,此步不需要时可省略
        public function beforeSave($insert) {
            if(parent::beforeSave($insert)) {
                if($insert) {										//插入,即新增
                    //属性对应表中字段
                    $this->status = 0;
                    $this->ip = \Yii::$app->request->getUserIP();	//获取访问者IP
                    $this->add_time = time();
                    return true;
                } else {											//修改
                    $this->edit_time = time();
                    return true;
                }
            } else {												//非添加和修改
                return false;
            }
        }
}

/*
 * 上传模型类
 */
<?php
    namespace backend\models;
    use yii\base\Model;
    class UploadForm extends Model {
        //定义属性,表单中上传控件名
        public $img;
        public function attributeLabels() {
            return [
                'img' => '上传图片'
            ];
        }
        public function rules() {
            return [
                ['img', 'file', 'extensions' => 'png, jpg'],	//上传文件扩展名
                ['img', 'file', 'mimeTypes' => 'image/jpeg, image/png'],	//上传文件类型
                ['img', 'file', 'minSize' => '30720', 'tooSmall' => '{attribute}不能小于30Kb'],	//单位字节
                ['img', 'file', 'maxSize' => '512000', 'tooBig' => '{attribute}不能大于500Kb'],
            ];
        }
}

    /*
     * 登陆模型类
     */
<?php
    namespace backend\models;
    use yii\db\ActiveRecord;
    use yii\web\IdentityInterface; 					//认证接口
    class Login extends ActiveRecord implements IdentityInterface {
        //定义属性对应表单(表中不存在的字段,临时使用的)
        public $rel = true; 						//记住我,默认勾选
        public $_user; 								//保存查询的用户信息
        public static function tableName() {
            return 'user';
        }
        public function attributeLabels() {
            return [
                'username' => '用户名',
                'pwd' => '密码',
                'rel' => '记住我'
            ];
        }
        public function rules() {
            return [
                [['username','rel', 'pwd'], 'required', 'message' => '{attribute}不能为空'],
                ['pwd', 'checkLogin']				//调用方法实现验证用户+密码
            ];
        }
        //checkLogin方法(验证用户名和密码是否正确($attribute对应值为pwd))
        public function checkLogin($attribute) {	//self::即当前类
            $this->_user = self::findOne(['username' => $this->username, 'pwd' => md5($this->pwd), 'status' => 0]); 	//查询,保存查询结果
            if ($this->_user) {						//登陆成功
                //记录上次登录时间
                \Yii::$app->session->set('login_time', $this->_user->login_time); 	//使用session
                //更新数据,登录时间,登录次数,登录IP
                self::updateAll(['login_time' => time(), 'login_num' => ($this->_user->login_num + 1), 'ip' => \Yii::$app->request->getUserIP()], ['username' => $this->username]);
            } else {
                $this->addError($attribute, '用户名或密码错误!');
            }
        }
        //验证登录信息,保存登录状态
        public function login() {
            if ($this->validate()) {				//使用rules定义的规则进行验证
                //保存登录信息(有效期1个月)
                return \Yii::$app->user->login($this->_user, $this->rel ? 3600 * 24 * 30 : 0); //参数:用户对象,有效期单位秒
            } else {								//验证失败
                return false;
            }
        }
        
        //以下就是固定格式,必须在验证模型中,实现接口中定义的方法
        /**
         * @return int|string 当前用户ID
         */
        public function getId() {
            return $this->id;
        }
        /**
         * 根据给到的ID查询身份。
         *
         * @param string|integer $id 被查询的ID
         * @return IdentityInterface|null 通过ID匹配到的身份对象
         */
        public static function findIdentity($id) {
            return static::findOne($id);
        }
        /**
         * 根据 token 查询身份。不使用token认证,方法体内代码可以删除 
         *
         * @param string $token 被查询的 token
         * @return IdentityInterface|null 通过 token 得到的身份对象
         */
        public static function findIdentityByAccessToken($token, $type = null) {
            return static::findOne(['access_token' => $token]);
        }
        /**
         * 表中要有auth_key字段(值随机生成),用于加密cookie使用
         * @return string 当前用户的(cookie)认证密钥,
         */
        public function getAuthKey() {
            return $this->auth_key;
        }
        /**
         * @param string $authKey
         * @return boolean 判断当前认证秘钥是否过期
         */
        public function validateAuthKey($authKey) {
            return $this->getAuthKey() === $authKey;
        }
    }

6、控制器中的原生与Yii框架写法

<?php
    namespace frontend\controllers;
    use yii\web\Controller;
    use frontend\models\Test;//引入AR类
    echo "<meta charset='utf-8'/>";
	class TestController extends Controller{
        //行为方法,用于授权,写法固定
        public function behaviors() {
            return [
                'access' => [					//访问控制
                    'class' => AccessControl::className(),
                    'rules' => [				//规则
                        [
                            'allow' => false,	//false是拒绝
                            'roles' => ['?'],	// 匹配访客用户(未经认证)
                        ],
                        [
                            'allow' => true,	//true是允许
                            'roles' => ['@'],	//匹配已认证用户
                        ],
                    ],
                ],
            ];
        }
        //显示新闻列表
        public function actionNews($keyword = null, $typeid = 0) {
            $news = News::find();							//相当于连接这个模型的对应表,类似于TP框架中的M('News');
            //添加搜索条件
            if (!empty($keyword)) {							//添加模糊搜索
                $news->andWhere(['like','title',$keyword]);	//添加一个条件用And拼接,orWhere/或
            }
            if (!empty($typeid)) {							//添加分类
                $news->andWhere(['typeid' => $typeid]);		//添加一个条件用And拼接
            }
            //分页
            $count = $news->count();						//表总记录数
            $page = new Pagination(['totalCount' => $count, 'pageSize' => 2]);	//分页类,计算limit
            $list = $news->orderBy('newsid desc')
                    ->offset($page->offset)					//偏移量,从哪行开始取limit(0,2)
                    ->limit($page->limit)					//取几行
                    ->all();
            //加载视图,传递数据给视图使用
            return $this->render('news',['list' => $list, 'page' => $page, 'keyword' => $keyword, 'typeid' => $typeid]);
        }
        //执行原生SQL
        public function actionTestdb($id = 1){
            //添加数据,直接在浏览器地址栏输入控制器及动作即可添加到数据库,以下相同
            //echo \Yii::$app->db->createCommand("insert into msg(title,sex,tel,lxr,content,ip,status,add_time) values('标题','先生','17245678944','张三','留言内容123','127.0.0.1','0','".time()."')")->execute();
            //修改数据
            //echo \Yii::$app->db->createCommand("update msg set lxr='熊二' where msgid=5")->execute();
            //删除数据
            //echo \Yii::$app->db->createCommand("delete from msg where msgid=11")->execute();
            //查询数据
            //$list = \Yii::$app->db->createCommand("select * from msg")->queryAll();	//查询所有数据,返回二维数组
            //$list = \Yii::$app->db->createCommand("select * from msg where msgid=5")->queryOne();	//查询一条数据,返回一维数组
            $list = \Yii::$app->db->createCommand("select * from msg where msgid>:id")->bindValue(':id',$id)->queryAll();	//绑定参数,为了防止SQL注入攻击,可以使用此方式
            var_dump($list);
        }
        
        //测试AR模型
        public function actionTestAR(){
//       	 $model = new Test();								//头部namespace下需要加use frontend\models\Test;
//            //写入数据
//            //属性对应表中字段
//            $model->title = '主题';
//            $model->sex = '女士';
//            $model->tel = '1324567899';
//            $model->lxr = '熊三';
//            $model->content = '1111内容';
//            $model->ip = '127.0.0.1';
//            $model->status = '0';
//            $model->add_time = time();
//            $model->save();									//保存数据,同$model->insert()
            
//            //修改数据
//            $model1 = Test::findOne(1);						//修改一条数据,主键=1。
//            $model1->title = '主题';
//            $model1->save();									//保存数据,同$model->update()
            
//            Test::updateAll(['title' => '主题'],'msgid > 1');	//修改多条数据
            
//            //删除数据
//            Test::findOne(5)->delete();						//删除一条数据
//            Test::deleteAll("msgid IN(10,16)");				//删除所有符合条件的数据
            
//            //查询数据
//            $msg = Test::find()->where(['status' => 0])->orderBy('msgid desc')->all();//查询所有符合条件的数据
//            var_dump($msg);
//            $msg = Test::find()->where(['status' => 0])->orderBy('msgid desc')->one();//查询一条数据
//            var_dump($msg);
              $msg = Test::find()								//查询
                    ->select(['msgid','title'])					//选择显示字段
                    ->where('status=:status',[':status' => 0])	//条件绑定方式
                    ->limit(2)									//取数
                    ->orderBy('msgid desc')						//排序
                    ->asArray()									//以数组方式返回结果
                    ->all();									//获取所有符合条件的数组
            var_dump($msg);
        }
        //产品列表及分页
        public function actionProduct() {
            $product = Product::find();
            $count = $product->count();
            $page = new Pagination(['totalCount' => $count, 'pageSize' => 6]);
            $list = $product->orderBy('id desc')
                    ->offset($page->offset)						//偏移量
                    ->limit($page->limit)
                    ->all();
            return $this->render('product', ['list' => $list, 'page' => $page]);
        }
        //产品详细
        public function actionInfo($id = 0) {
            $info = Product::findOne($id);
            if (empty($info)) {
                return $this->goHome();
            }
            //更新数量
            $info->updateCounters(['show_num' => 1]);
            return $this->render('product_show', ['info' => $info]);
        }
}

7、视图中的写法
循环输出及跳转并传值:

    <ul>
        <?php foreach ($list as $val) { ?>
            <li><a href="<?= Url::to(['info', 'id' => $val->id]) ?>"><s><img src="<?= $val->pic ?>"  /></s><span><?= mb_substr($val->title, 0, 15, 'utf-8'); ?></span></a></li>
        <?php } ?>	
	</ul>

分页:

<div class="message">共<i class="blue"><?= $page->totalCount; ?></i>条记录,当前显示第&nbsp;<i class="blue"><?= $page->getPage()+1; ?>/<?= $page->getPageCount(); ?>&nbsp;</i>页</div>
<?= LinkPager::widget(['pagination' => $page, 'maxButtonCount' => 6, 'nextPageLabel' => '下一页', 'prevPageLabel' => '上一页', 'firstPageLabel' => '首页', 'lastPageLabel' => '尾页']); ?>

获取所有分类(视图中也可直接查询):

$cat = backend\models\Category::find()->all();

Ajax为post类型时必须带令牌:

        <script>
            $(function () {
	            $('#selectAll').click(function() {
	            	$('#list').find('input[type=checkbox]').attr('checked', $(this).prop('checked'));
	            });
	            //提交删除
	            $('#selectdel').click(function () {
	            	var valArr = new Array;
	            	$('#list :checkbox[checked]').each(function (i) {
	            		valArr[i] = $(this).val();
	            	});
		            var vals = valArr.join(','); 			// 方法用于把数组中的所有元素放入一个字符串。//1,2,3
		            if (vals == ''){
		                alert('id未获取到');
		                return;
		            }
		            //AJAX提交到PHP中处理
		            $.ajax({
		                url: '<?= Url::to(['news/select-del']); ?>',
		                type: 'post',
		                data: {'ids': vals, '<?= \Yii::$app->request->csrfParam; ?>':'<?= \Yii::$app->request->csrfToken; ?>'}, 					//post需要加令牌
		                dataType: 'text',
		                success: function (d) {
		                    if (d == 1) {					//删除成功
		                    	window.location.reload(); 	//刷新当前页 
		                    } else if (d == 2) {			//删除失败
		                    	alert('删除失败');
		                    } else if (d == 3) {			//未登录
		                    	window.location.href = 'login.html';
		                    }
		                }
		            });
	            });
            });
        </script> 

猜你喜欢

转载自blog.csdn.net/qq_38882327/article/details/89067129