composer create-project --prefer-dist yiisoft/yii2-app-basic basic
composer install
composer update
composer require [options] [--] [vendor/packages]...
Yii的数据库读取对象,在PDO之上,DAO后有了Query Builder和AR
$conn = Yii::$app->db;
Yii::$app->db->createCommand("SELECT * FROM `user`");
Yii::$app->db->createCommand("SELECT * FROM `user` WHERE uid=:uid",[":uid"=>1]);
Yii::$app->db->createCommand("SELECT * FROM `user` WHERE uid=:uid")->addValue([":uid"=>1]);
Yii::$app->db
->createCommand('INSERT INTO user (email, password) VALUES("test3@example.com", "test3");')->execute();
Yii::$app->db->createCommand()->insert('user', [
'email' => 'test4@example.com',
'password' => 'changeme7',
'first_name' => 'Test'
])->execute();
Yii::$app->db->createCommand()->batchInsert('user', ['email', 'password', 'first_name'],
[
['james.franklin@example.com', 'changeme7', 'James'],
['linda.marks@example.com', 'changeme7', 'Linda']
['roger.martin@example.com', 'changeme7']
])->execute();
Yii::$app->db->createCommand()->update('user', ['updated_at' => time()], 'id = 2')->execute();
Yii::$app->db->createCommand()->delete('user', 'id = 3')->execute();
Yii::$app->db->createCommand("SELECT * FROM `user`")->queryAll();
Yii::$app->db->createCommand("SELECT * FROM `user` WHERE id = 1")->queryOne();
Yii::$app->db->createCommand("SELECT count(*) AS total FROM `user` WHERE id = 1")->queryScalar();
Yii::$app->db->createCommand("SELECT username FROM `user`")->queryColumn();
日志功能
Yii::trace($message,$category)
Yii::info($message,$category)
Yii::warning($message,$category)
Yii::error($message,$category)
数据验证,最常用于模型的rules()函数
["username",'required']
[["username","email"],'required']
[["username"],'required',"message"=>"{attribute}必须填写"]
[["username"],'required','requiredValue'=>"abei"] // 用户填写的值必须等于requiredValue才能通过验证。
["email",'email']
[["email","work_email"],'email']
['sex', 'boolean', 'trueValue' => true, 'falseValue' => false, 'strict' => true];// 可以认为置顶 true / false 值。
['verificationCode', 'captcha'];
['username', 'compare', 'compareAttribute' => 'province','message'=>'username和province必须一样'] //错误信息将提示给username
['age', 'compare', 'compareValue' => 30, 'operator' => '>=','type' => 'number'];//compareValue:比较常量值 operator:比较操作符 type为值类型,默认为string,会一个每个字符对比,若为number则直接判断数值
// operator 待选值==、===、!=、!==、>、>=、<、<=
["birth","date","format"=>"Y-m-d"]
['age','default','value'=>null] // 当age为空的时候设置为null
['country','default','value'=>'USA'] // 当 country为空时设置为USA
/* 如果from为空,则=今天+3天,如果to为空,则=今天+6天 */
[['from','to'],'default','value'=>function($model,$attribute){
return date('Y-m-d', strtotime($attribute === 'to' ? '+3 days' : '+6 days'));
}]
['v','double'] // 判断v是否为数字
['v','double','max'=>90,'min'=>1]//判断v是否为数字且大于等于1、小于等于90
/* 要求验证的元素必须为数组,否则会返回假并报错 */
["categoryIds","each","rule"=>['integer']]
/* 所谓对存在的检查实质为where的与操作,必须同时瞒住的记录存在方可。兄弟们可以研究下,exist是对sql语句EXISTS的应用*/
["username","exist"] // username输入的值已经存在
["username","exist","targetAttribute"=>"province"] // username的输入值必须在province列存在
["username","exist",'targetAttribute' => ['username', 'province']] // username的输入值必须在username和province中存在
[["username","province"],"exist",'targetAttribute' => ['username', 'province']] // username和province的输入值必须在username和province中存在
/* maxFiles代表一次最多传几个,mimeTypes代表上传文件类型 */
['primaryImage', 'file', 'extensions' => ['png', 'jpg', 'gif'],'mimeTypes'=>["image/*"], 'maxSize' => 1024*1024,'minSize'=>100*1024,'maxFiles'=>6,'checkExtensionByMimeType'=>true],
[['username', 'email'], 'filter', 'filter' => 'trim', 'skipOnArray' => true],
['phone', 'filter', 'filter' => function ($value) {
// normalize phone input here
return $value;
}],
/* 上传png/jpg格式,最大宽度不能超过1000px,最小宽度不能低于100px,最大高度不能高于1000px。最小高度不能低于100px */
['primaryImage', 'image', 'extensions' => 'png, jpg','minWidth' => 100, 'maxWidth' => 1000,'minHeight' => 100, 'maxHeight' => 1000]
["ip_addess","ip"]
["level","in","range"=>[1,2,3]]
["age",'integer'];
["age","integer","max"=>90,"min"=>1]
["username","match","pattern"=>"/^[a-z]\w*$/i"]
["description","safe"]
["username","string","length"=>[4,24]];
["username","string","min"=>4];
["username","string","max"=>32];
["username","string","encoding"=>"UTF-8"];
["username","unique"]
["username","unique","targetAttribute"=>"province"]
["website","url"]
["website","url","validSchemes"=>["http","https"]]
字符串
StringHelper::countWords("hello world");//2
StringHelper::basename("/path/hello.txt",".txt"); // hello
StringHelper::dirname("/home/path/hello.txt");// /home/path
StringHelper::truncate("hello world",7,'...'); //hello w...
StringHelper::truncate("hello world",7,'...',null,true);//hello w...
StringHelper::truncateWords('This is a test sentance', 4, '...') //This is a test ...
StringHelper::truncateWords('This is a test for a sentance', 5, '...',true) //This is a test for...
StringHelper::startsWith("hello world","he");//true
StringHelper::endsWith("hello world","ald");//false
StringHelper::explode('It, is, a first, test'));//['It','is','a first','test']
StringHelper::explode("a@b@c","@");['a','b','c']
StringHelper::explode("a, b ,c ");['a','b','c']
Session被封装成一个应用组件,直接通过Yii::$app->session来访问;Cookie通过Request和Response来操作。
$session = Yii::$app->session;
Yii::$app->session->isActive
Yii::$app->session->open()
Yii::$app->session->close();
Yii::$app->session->destroy();
/* 以下三种方法效果等同 */
$language = $session->get('language');
$language = $session['language'];
$language = isset($_SESSION['language']) ? $_SESSION['language'] : null;
/* 以下三种方法效果等同 */
$session->set('language', 'en-US');
$session['language'] = 'en-US';
$_SESSION['language'] = 'en-US';
/* 下面三种方法效果等同 */
$session->remove('language');
unset($session['language']);
unset($_SESSION['language']);
/* 以下三种方法效果一致 */
if ($session->has('language')) ...
if (isset($session['language'])) ...
if (isset($_SESSION['language'])) ...
$cookies = Yii::$app->request->cookies;
$cookies = Yii::$app->response->cookies;
$language = $cookies->getValue('language', 'en');// 如果获取language失败,则返回"en"代替
if (($cookie = $cookies->get('language')) !== null) {
$language = $cookie->value;
}
if (isset($cookies['language'])) {
$language = $cookies['language']->value;
}
if ($cookies->has('language')) ...
if (isset($cookies['language'])) ...
$cookies->add(new \yii\web\Cookie([
'name' => 'language',
'value' => 'zh-CN',
]));
$cookies->remove('language');
unset($cookies['language']);
Request 被配置为一个应用组件,我们可以通过Yii::$app->request访问它。
Yii::$app->request->getAbsoluteUrl();
Yii::$app->request->getHostInfo();
Yii::$app->request->getQueryString()
Yii::$app->request->getServerPort();
Yii::$app->request-> getAcceptableContentTypes ();// Header Accept
Yii::$app->request-> getAcceptableLanguages(); // Header Accept-Language
Yii::$app->request->get();
Yii::$app->request->get("id");
Yii::$app->request->POST();
Yii::$app->request->POST("username");
Yii::$app->request->isAjax // 判断是否为ajax请求
Yii::$app->request->isConsoleRequest // 判断是否为控制发起的请求
Yii::$app->request->isDelete // 判断是否为DELETE请求
Yii::$app->request->isGet // 判断是否为GET请求
Yii::$app->request->isPost // 判断是否为POST请求
Yii::$app->request->isPjax // 判断是否为isPjax请求
Yii::$app->request->getUserIP();
和Request一样,Response被封装成Yii的一个组件,你可以通过Yii::$app->response轻松的访问它。
Yii::$app->response->statusCode = 200;
yii\web\BadRequestHttpException: status code 400.
yii\web\ConflictHttpException: status code 409.
yii\web\ForbiddenHttpException: status code 403.
yii\web\GoneHttpException: status code 410.
yii\web\MethodNotAllowedHttpException: status code 405.
yii\web\NotAcceptableHttpException: status code 406.
yii\web\NotFoundHttpException: status code 404.
yii\web\ServerErrorHttpException: status code 500.
yii\web\TooManyRequestsHttpException: status code 429.
yii\web\UnauthorizedHttpException: status code 401.
yii\web\UnsupportedMediaTypeHttpException: status code 415.
throw new \yii\web\HttpException(402); // 如果系统没有,可以通过HttpException自己写状态码
throw new \yii\web\HttpException(402,"message");
$headers = Yii::$app->response->headers;
// add a Pragma header. Existing Pragma headers will NOT be overwritten.
$headers->add('Pragma', 'no-cache');
// set a Pragma header. Any existing Pragma headers will be discarded.
$headers->set('Pragma', 'no-cache');
// remove Pragma header(s) and return the removed Pragma header values in an array
$values = $headers->remove('Pragma');
Yii::$app->response->content = 'hello world!';
控制器,可在action内直接用$this调用。
$this->render('index',['model'=>$model])
$this->renderPartial('index',['model'=>$model])
// 注入所有注册的JS/CSS脚本和文件,通常使用在响应AJAX网页请求的情况下
$this->renderAjax('index',['model'=>$model])
$this->renderContent($content);
重点!列出最常用的ActiveForm方法。
$form = ActiveForm::begin([
'enableClientValidation'=>false
]);
$form = ActiveForm::begin([
'enableClientScript'=>false
]);
$form = ActiveForm::begin([
"action"=>$url
])
$form = ActiveForm::begin([
"method"=>"POST"
]);
$form = ActiveForm::begin([
'options'=>["class"=>"f","data-name"=>"xxx"]
]);
$form->field($model, 'date')->textInput(["key"=>"value"]);
$form->field($model, 'date')->textarea(["key"=>"value"]);
$form->field($model,'sex')->radioList($arr,["key"=>"value"]);
$form->field($model,"password")->passwordInput();
$form->field($model,"city_id")->checkboxList($arr);
$form->field($model,"image")->fileInput();
$form->field($model,"name")->hiddenInput();
几个常用也好用的文件帮助方法
FileHelper::findFiles('/path/to/search/');
FileHelper::findFiles('.', ['only' => ['*.php', '*.txt']]); // 只返回php和txt文件
FileHelper::findFiles('.', ['except' => ['*.php', '*.txt']]); // 排除php和txt文件
FileHelper::getMimeType('/path/to/img.jpeg');
FileHelper::copyDirectory($src, $dst, $options = [])
FileHelper::removeDirectory($dir, $options = [])
FileHelper::createDirectory($path, $mode = 0775, $recursive = true)
上传文件帮助类
$file = UploadedFile::getInstance($model,'avatar')
$files = UploadedFile::getInstances($model,'avatar')
//view $form->field($model,'avatar[]')->fileInput()
$file = UploadedFile::getInstanceByName('avatar');
$file = UploadedFile::getInstancesByName('avatar');
// view Html::fileInput('avatar[]')
$file->saveAs(Yii::getAlias("@webroot").'/data/test.jpg');
$file->getBaseName();//test.jpg ===> test
$file->getExtension();// 是png、不是image/png
$file->name;//test.jpg
$file->type;// image/png
$file->tempName;
$file->size;// 21744
通过Html类的一些静态方法生成Html标签。
Html::a('链接的文本', $url);
Html::a('链接文本', Url::to(['/site/index'], true));
Html::a('链接文本', Yii::$app->urlManager->createUrl(['/site/index']));
Html::img("/images/logo.png",['class'=>'img']);
Html::button("按钮文本",['class'=>'button-action']);
Html::mailto("阿北",'abei@nai8.me',$options);
$list = ['china','usa'];
Html::ol($list);
$list = ['china','usa','japan'];
Html::ul($list);
Html::script("alert('hello world');")
Html::style("color:#F60");
Html::style(".list {background:#FFF;}");
Html::cssFile("http://baidu.com/style.css",[]);
Html::jsFile($url,[]);
Html::encode($html);
Html::decode($string);
Yii::setAlias('@baidu', 'http://www.baidu.com');
Yii::getAlias($name);
Yii::getAlias('@yii')
Yii::getAlias('@app')
Yii::getAlias("@vendor")
Yii::getAlias("@bower");
Yii::getAlias("@npm");
Yii::getAlias("@runtime");
Yii::getAlias("@webroot");
Yii::getAlias("@web");
Yii::getAlias("@common");
Yii::getAlias("@frontend");
Yii::getAlias("@backend");
Yii::getAlias("@console");
主要解决DAO在查询语句上的繁琐问题,无需输入原生SQL语句就可以完成数据库检索。
$query = (new \yii\db\Query()); // yii2使用Query对象来采集SQL的各个部分,然后由Query Builder组成SQL语句后由DAO发给数据库获得请求。
$query->select("id,username");// 字符串形式
$query->select(['id','username']); // 数组形式
$query->select(["userId"=>"id","fName"=>"user.frist_name"]); // 起别名
$query->select(["full_name"=>"CONCAT(id,'-',username)"]); // 支持MYSQL函数
$query->from("user"); // 字符串形式
$query->from(["u"=>"user"]); // 数据表别名
$query->select("username")->distinct()->from("user"); // distinct
/* 传递字符串 */
$query->where("id = 1");
$query->where("id = :id")->addParams([":id"=>1]);
$query->where("id = :id",[":id"=>1]);
/* 传递数组 */
$query->where(["username"=>"abei","age"=>[20,19,26]])->from("user");// select * from user where username="abei" AND age in (20,19,26)
/* 操作符 */
$query->where([">","id",10]);// id > 10
$query->where(["<","id",10]); // id < 10
$query->where(["<>","id",10]); // id <> 10
$query->where(["in","id",[10,12]]);// id in (10,20)
$query->where(["not in","id",[10,12]]);// id not in (10,20)
$query->where(["and","id=1","id=2"]); id=1 AND id=2
$query->where(['or', ['type' => [7, 8, 9]], ['id' => [1, 2, 3]]]); // (type IN (7, 8, 9) OR (id IN (1, 2, 3)))
$query->where(["between", 'id', 1, 10]);// id between 1 AND 10
$query->where(["not",["id"=>5]]);// not (id=5)
$query->where(["not between","id",1,10]);// id not between 1 AND 10
$query->where(["like","username","abei"]); // username like "%abei%"
$query->where([['like', 'username', ['abei', 'liuhuan']]]); // username like "%abei%" AND username like "%liuhuan%"
$query->where(['like', 'username', '%abei', false]); // username like "%abei"
$query->where(["or like", 'username', ['abei', 'liuhuan']]);// username like "%abei%" OR username like "%liuhuan%",只作用于范围为数组的形式
$query->where(["not like",xxxxx]);// 与like用法一致
$query->where(["or not like",xxx])// 与not like用法一致
/* EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False */
$query->where(['exists', (new Query())->select('id')->from('user')->where(['id' => 1])]);
$query->orderBy("id DESC");
$query->orderBy(["id"=>SORT_DESC]);
$query->orderBy(["id"=>SORT_DESC,'create_time'=>SORT_ASC]);
$query->groupBy(["username"]);
$query->groupBy(["id"])->having([">",'id',20]);
$query->createCommand()->sql;
$query->all();// 二位数组
$query->one();
(new \yii\db\Query)->from('user')->exists();
$query->count();
$query->scalar();
$query->column();// 一位数组
$query = new \yii\db\Query;
$query->from("user");
$query->select(["fname"=>"username"]);
$query->where([">",'id',10]);
$query->all();
数据库迁移工具
./yii migrate/create script_name // script_name为脚本名字(需要英文格式)
./yii migrate
./yii migrate/up
./yii migrate/up 脚本名 // 不用含有扩展名
Asset资源管理
$basePath // 资源文件所在的web服务器目录路径,一般为@webroot
$baseUrl // js和css文件相对url基地址
$css // asset bundle 所包含的css文件数组
$cssOptions // 对link标签的属性控制
$js // asset bundle 所包含的js文件数组
$jsOptions // 对script标签的属性控制
$publishOptions // 发布操作
$sourcePath // 当资源网络不可以访问,则必须指定此目录。
'appendTimestamp' => true // 在web.php里的components - assetManager
public $publishOptions = [
'only' => [
'fonts/*',
'css/*',
'test.js'
],
'except'=>[
'img'
],
];
public $jsOptions = ['position' => \yii\web\View::POS_HEAD];//js文件发布到head标签内
public $jsOptions = ['position' => \yii\web\View::POS_END];//js文件发布到body标签底部
public $jsOptions = ['position' => \yii\web\View::POS_BEGIN];//js文件放到body标签开始处
public $cssOptions = ['condition' => 'IE 11'];// 代表兼容ie11
'linkAssets' => true // 在web.php里的components - assetManager
// 在web.php里的components - assetManager,配置自定义的也可以
'bundles' => [
'yii/web/YiiAsset'=>[
'js'=>[],
......
]
]
有关事件的所有,系统自带事件通通给你。
Application::EVENT_BEFORE_REQUEST
Application::EVENT_AFTER_REQUEST
Controller::EVENT_BEFORE_ACTION
Controller::EVENT_AFTER_ACTION
Model::EVENT_BEFORE_VALIDATE
Model::EVENT_AFTER_VALIDATE
Module::EVENT_BEFORE_ACTION
Module::EVENT_AFTER_ACTION
View::EVENT_BEGIN_PAGE
View::EVENT_END_PAGE
View::EVENT_BEFORE_RENDER
View::EVENT_AFTER_RENDER
View::EVENT_BEGIN_BODY
View::EVENT_END_BODY
Widget::EVENT_INIT
Widget::EVENT_BEFORE_RUN
Widget::EVENT_AFTER_RUN
ActiveQuery::EVENT_INIT
BaseActiveRecord::EVENT_INIT
BaseActiveRecord::EVENT_AFTER_FIND
BaseActiveRecord::EVENT_BEFORE_INSERT
BaseActiveRecord::EVENT_AFTER_INSERT
BaseActiveRecord::EVENT_BEFORE_UPDATE
BaseActiveRecord::EVENT_AFTER_UPDATE
BaseActiveRecord::EVENT_BEFORE_DELETE
BaseActiveRecord::EVENT_AFTER_DELETE
BaseActiveRecord::EVENT_AFTER_REFRESH
Connection::EVENT_AFTER_OPEN
Connection::EVENT_BEGIN_TRANSACTION
Connection::EVENT_COMMIT_TRANSACTION
Connection::EVENT_ROLLBACK_TRANSACTION
Response::EVENT_BEFORE_SEND
Response::EVENT_AFTER_SEND
Response::EVENT_AFTER_PREPARE
User::EVENT_BEFORE_LOGIN
User::EVENT_AFTER_LOGIN
User::EVENT_BEFORE_LOGOUT
User::EVENT_AFTER_LOGOUT
路由管理
// conf/web.php
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'suffix'=>'.html',// 统一后缀名,若不需要则无需配置
'enableStrictParsing'=>false,//默认为false,是否采用严格解析
'rules' => [
],
]
// Apache需要支持url重写其AllowOverride为all
AllowOverride:all
//web目录下增加.htaccess,隐藏index.php文件 内容如下
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
location / {
if (!-e $request_filename){
rewrite ^/(.*) /index.php last;
}
}
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php/$1 [L,QSA]
GET /users
GET /users?page=2
GET /users?fields=id,username,created_at
GET /users?sort=id,-username
200: OK。一切正常。
201: 响应 POST 请求时成功创建一个资源。Location header 包含的URL指向新创建的资源。
204: 该请求被成功处理,响应不包含正文内容 (类似 DELETE 请求)。
304: 资源没有被修改。可以使用缓存的版本。
400: 错误的请求。可能通过用户方面的多种原因引起的,例如在请求体内有无效的JSON 数据,无效的操作参数,等等。
401: 验证失败。
403: 已经经过身份验证的用户不允许访问指定的 API 末端。
404: 所请求的资源不存在。
405: 不被允许的方法。 请检查 Allow header 允许的HTTP方法。
415: 不支持的媒体类型。 所请求的内容类型或版本号是无效的。
422: 数据验证失败 (例如,响应一个 POST 请求)。 请检查响应体内详细的错误消息。
429: 请求过多。 由于限速请求被拒绝。
500: 内部服务器错误。 这可能是由于内部程序错误引起的。