#大数据学习笔记# 汇总

Java


Linux


Hadoop


Zookeeper


Hive


#原创# CMSTOP系统快速入门

# CMSTOP #
熟悉CMSTOP系统,首先别急着阅读源码,毕竟作为一款商业的CMS,直接阅读源码反而不能快速的使用起来!从后台的功能使用上去熟悉是比较容易理解整个应用的构建思想的。
后台也是基于MVC的路径的,可以快速的找到对应的控制器,但CMS前台的则是生成的静态页面,路径根据路径的设置(在后台新建栏目、页面时指定)而生成的一系列静态文件,所以直接通过前台的路径去找源码是相对其他MVC系统而言的一大区别。

1、资源下载
源码:https://coding.net/u/webjust/p/cms_top/git
> 核心文件经过了Zend加密,可以通过解密网站进行解密:http://dezend.qiling.org/free/

2、环境搭建
下载PHPSTUDY2016 http://www.php.cn/xiazai/gongju

2.1、服务器端包含(ssi)
Apache下开启SSI配置使html支持include包含的方法

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
<VirtualHost *:80>
    DocumentRoot "D:\phpStudy\WWW\cmstop.info"
    ServerName cmstop.info
    ServerAlias cmstop.info
  <Directory "D:\phpStudy\WWW\cmstop.info">
    Options Indexes FollowSymLinks Includes
    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
    AllowOverride None
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

2.2、magic_quotes_gpc函数关闭:
在php.ini文件内找到
magic_quotes_gpc = On
将其改为
magic_quotes_gpc = Off

2.3、支持index.shtml索引页

Select Code
1
2
3
<IfModule dir_module>
    DirectoryIndex index.html index.shtml index.php index.htm l.php
</IfModule>

2.4 win7x64+PHPStudy2018安装redis扩展
https://blog.csdn.net/leejianjun/article/details/79555026
https://windows.php.net/downloads/pecl/releases/redis/3.0.0/php_redis-3.0.0-7.0-nts-vc14-x86.zip
https://windows.php.net/downloads/pecl/releases/igbinary/2.0.5/php_igbinary-2.0.5-7.0-nts-vc14-x86.zip

3、后台操作流程解读
3.1 新增栏目:

以栏目为例,最终会在数据库存储栏目对应的模板文件、URL路径(理解这部分是理解前台的生成页面的URL的关键所在),大部分CMS属于是静态的页面,所以前台会生成静态文件。

这里,我们还要理解CMSTOP一个比较关键的概念「区块」。下面是一个视图文件的源码;

Select Code
1
<!--{template 'system/header.html'}-->

这是引入公共的模板文件

Select Code
1
<!--#include virtual="{ROOT}section/30.html"-->

这是引入区块。可以认为CMSTOP的每一个前台的页面,都是可以由很多个自定义的区块组合而成一个页面,这样维护人员就可以很容易的在页面上添加一个元素,非常灵活,算是其很大的一个特色了。

3.2 区块
以首页为例:

区块中,你可以定义HTML,也可以根据模板引擎的语法自定义动态的输出等内容;

首页模板:

原先的模板如上,替换掉区块以后的代码就是这样的:

你可能会问:怎么不直接定义在模板文件中呢?区块你可以理解为公共部分的提取,我可能会很灵活的用在多个页面,而管理「区块」的任务也不需要由「程序员」来完成,内容管理员就可以维护区块了。是不是很方便处理像CMS页面上的广告位(类似的这种功能)?

最终存储在数据库 `cmstop_section` 的「区块」,都对应1个ID。

生成的区块的静态文件,都存放在 /section 根目录下,而不需要从数据库读取,至于如何生成这些静态文件,则可以进一步的去理解系统里面是如何生成的,要找到这个方法也是顺其自然的。

如果需要了解进一步生成区块静态文件的方法,就可以根据这个方法找到对应的后台控制器方法

以此类推,可以找到生成栏目页、新闻内容页、自定义的页面:

总之,到这里为止,我们应该充分的理解CMSTOP的前台页面的URL是根据后台设置的规则生成的纯静态文件。

4、其他功能

当然作为一个强大的内容管理系统,内容是核心,而其他的组件都是为内容的维护服务的,可以多在后台使用其他的功能,结合对应的表结构来理解,就可以很容易掌握,从而根据需求来进行一些二次开发的任务。官网也有详细的手册:http://www.cmstop.com/help/

结尾:
至于MVC里面的模板,控制器,模型,可以参考二次开发手册,也可以根据系统已经生产的一套页面的源码,去直接借用即可,这里不做过多的阐述:http://doc.cmstop.com/develop/

整理ThinkPHP5笔记

# 整理TP5笔记 #
## 安装
下载:
https://github.com/top-think/think

Windows安装Composer:
https://getcomposer.org/download/

Composer中国全量镜像安装方法,及检测方法

手册:
https://www.kancloud.cn/manual/thinkphp5_1/353946

## 目录结构

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
www  WEB部署目录(或者子目录)
├─application           应用目录
│  ├─common             公共模块目录(可以更改)
│  ├─module_name        模块目录
│  │  ├─common.php      模块函数文件
│  │  ├─controller      控制器目录
│  │  ├─model           模型目录
│  │  ├─view            视图目录
│  │  ├─config          配置目录
│  │  └─ ...            更多类库目录
│  │
│  ├─command.php        命令行定义文件
│  ├─common.php         公共函数文件
│  └─tags.php           应用行为扩展定义文件
│
├─config                应用配置目录
│  ├─module_name        模块配置目录
│  │  ├─database.php    数据库配置
│  │  ├─cache           缓存配置
│  │  └─ ...            
│  │
│  ├─app.php            应用配置
│  ├─cache.php          缓存配置
│  ├─cookie.php         Cookie配置
│  ├─database.php       数据库配置
│  ├─log.php            日志配置
│  ├─session.php        Session配置
│  ├─template.php       模板引擎配置
│  └─trace.php          Trace配置
│
├─route                 路由定义目录
│  ├─route.php          路由定义
│  └─...                更多
│
├─public                WEB目录(对外访问目录)
│  ├─index.php          入口文件
│  ├─router.php         快速测试文件
│  └─.htaccess          用于apache的重写
│
├─thinkphp              框架系统目录
│  ├─lang               语言文件目录
│  ├─library            框架类库目录
│  │  ├─think           Think类库包目录
│  │  └─traits          系统Trait目录
│  │
│  ├─tpl                系统模板目录
│  ├─base.php           基础定义文件
│  ├─convention.php     框架惯例配置文件
│  ├─helper.php         助手函数文件
│  └─logo.png           框架LOGO文件
│
├─extend                扩展类库目录
├─runtime               应用的运行时目录(可写,可定制)
├─vendor                第三方类库目录(Composer依赖库)
├─build.php             自动生成定义文件(参考)
├─composer.json         composer 定义文件
├─LICENSE.txt           授权说明文件
├─README.md             README 文件
├─think                 命令行入口文件

## 配置
.env
Env::get(”)

应用配置目录 config
模块配置目录 application/module/config

打开调试模式:
‘app_debug’ => true,

读取配置:
use think\facade\Config;
Config::get()

助手函数:config()

数据库配置
D:\wamp\www\tp5.info\config\database.php

## 入口文件
默认的应用入口文件位于public/index.php

Select Code
1
2
3
4
5
6
7
8
9
namespace think;

// 加载基础文件
require __DIR__ . '/../thinkphp/base.php';
// 执行应用并响应
Container::get('app')->run()->send();

// 绑定指定的模块
Container::get('app')->bind('index')->run()->send();    // 绑定当前访问模块

## URL
没有定义路由的情况下典型的URL访问规则是:

Select Code
1
http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数名/参数值...]

默认采用PATH_INFO访问地址

根据路由信息生成URL:

Select Code
1
2
3
4
5
6
7
8
9
// 使用\think\facade\Url::build()
echo Url::build('index/blog/read', ['id' => 5]);    //http://tp5.info/blog/5.html
echo '<br>';
echo Url::build('index/blog/read', ['name' => 'admin']);    ///blog/read/name/admin.html
echo '<br>';
echo Url::build('index/blog/read', ['name' => 'admin'], 'shtml', true); //http://tp5.info/blog/read/name/admin.shtml
echo '<br>';
// 助手函数url()
echo url('index/blog/read');    ///blog/read.html

## 路由
D:\wamp\www\tp5.info\route\route.php

1、回调函数
2、字符串:控制器/方法

最基础的路由定义方法是:

Select Code
1
2
3
4
Route::rule('路由表达式','路由地址','请求类型');
Route::rule('new/:id','index/News/read');
Route::rule('new/:id','News/update','POST');
Route::rule('new/:id','News/read','GET|POST');

快捷注册方法的用法为:
Route::快捷方法名(‘路由表达式’,’路由地址’);

Select Code
1
2
3
4
5
Route::get('new/:id','News/read'); // 定义GET请求路由规则
Route::post('new/:id','News/update'); // 定义POST请求路由规则
Route::put('new/:id','News/update'); // 定义PUT请求路由规则
Route::delete('new/:id','News/delete'); // 定义DELETE请求路由规则
Route::any('new/:id','News/read'); // 所有请求都支持的路由规则

规则表达式:
每个参数中以:开头的参数都表示动态变量,并且会自动绑定到操作方法的对应参数
变量用[ ]包含起来后就表示该变量是路由匹配的可选变量
如果希望URL进行完全匹配,可以在路由表达式最后使用$符号

路由标识:
如果你需要快速的根据路由生成URL地址,可以在定义路由的时候指定生成标识。

Select Code
1
2
3
4
// 注册路由到index模块的News控制器的read操作
Route::rule('new/:id','index/News/read')->name('new_read');
// 生成路由地址的时候就可以使用
url('new_read',['id'=>10]);

定义路由:
1、路由到模块/控制器/操作
Route::get(‘blog/:id’,’index/group.blog/read’);
2、路由到操作方法:@[模块/控制器/]操作
Route::get(‘blog/:id’,’@index/blog/read’);
3、路由到重定向地址
Route::get(‘blog/:id’,’/blog/read/id/:id’);
4、闭包定义

Select Code
1
2
3
Route::get('hello', function () {
    return 'hello,world!';
});

5、路由分组
6、RESFUL资源路由
Route::resource(‘blog’,’index/blog’);

## MVC模式
https://www.kancloud.cn/manual/thinkphp5_1/353953
ThinkPHP支持传统的MVC(Model-View-Controller)模式以及流行的MVVM(Model-View-ViewModel)模式的应用开发,但无论采用何种模式,URL的规范仍然是统一的。

– 路由:路由是用于规划(一般同时也会进行简化)请求的访问地址,在访问地址和实际操作方法之间建立一个路由规则 => 路由地址的映射关系。
– 模块:一个典型的应用是由多个模块组成的,这些模块通常都是应用目录下面的一个子目录,每个模块都有自己独立的配置文件、公共文件和类库文件。
– 控制器:一个模块下面有多个控制器负责响应请求,而每个控制器其实就是一个独立的控制器类。控制器主要负责请求的接收,并调用相关的模型处理,并最终通过视图输出。严格来说,控制器不应该过多的介入业务逻辑处理。事实上,控制器是可以被跳过的,通过路由我们可以直接把请求调度到某个模型或者其他的类进行处理。
– 模型:模型类通常完成实际的业务逻辑和数据封装,并返回和格式无关的数据。ThinkPHP的模型层支持多层设计,你可以对模型层进行更细化的设计和分工,例如把模型层分为逻辑层/服务层/事件层等等。
– 视图:控制器调用模型类后,返回的数据通过视图组装成不同格式的输出。视图根据不同的需求,来决定调用模板引擎进行内容解析后输出还是直接输出。视图通常会有一系列的模板文件对应不同的控制器和操作方法,并且支持动态设置模板目录。
– 中间件:中间件主要用于HTTP请求的拦截处理

## 自定义函数
D:\wamp\www\tp5.info\application\common.php

## 控制器
控制器文件通常放在application/module/controller下面,类名和文件名保持大小写一致,并采用驼峰命名(首字母大写)。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace app\index\controller;

use think\Controller;

class Index extends Controller
{
    public function index()
    {
        return 'index';
    }
}

渲染输出:

Select Code
1
2
3
4
5
6
7
8
// 默认输出类型设置为JSON 'default_return_type'    => 'json',
return ['name' => 'thinkphp', 'time' => date('Y-m-d H:i:s')]; //输出JSON
// 输出字符串
return 'hello world';
// 输出json
return json(['name' => 'thinkphp', 'time' => date('Y-m-d H:i:s')]);
// 渲染模板输出
return view();  // 指向模板\index\view\index\hello.html

内置了两个跳转方法success和error,用于页面跳转提示。

控制器中间件

## 请求
当前的请求对象由think\Request类负责,在很多场合下并不需要实例化调用,通常使用依赖注入即可。在其它场合(例如模板输出等)则可以使用think\facade\Request静态类操作。

– 构造器注入
– 操作方法依赖注入
– 通过Facade机制来静态调用请求对象的方法
– request助手函数,可以在任何需要的时候直接调用当前请求对象

请求信息:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
dump($request->host());
dump($request->port());
dump($request->url());
dump($request->pathinfo());
dump($request->param());
dump($request->type());
dump($request->method());
echo '<hr>';
dump(\think\facade\Request::url());
dump(\think\facade\Request::pathinfo());
dump(\think\facade\Request::method());
dump(\think\facade\Request::param());
echo '<hr>';
halt($request);

变量信息:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dump(\think\facade\Request::has('id'));
dump(\think\facade\Request::param('id'));
// 依赖注入
dump($request->id);
dump($request->param('id'));
dump($request->param('name', 'admin'));
dump($request->param('name', ''));
dump($request->param('name', '', 'strip_tags'));
dump($request->param());
// 助手函数
dump(input());
dump(input('?get.id'));
dump(input('param.id'));
dump(input('param.'));
dump(input('id'));

## 响应
返回字符串:
最简单的响应输出是直接在路由闭包或者控制器操作方法中返回一个字符串

返回JSON:
修改默认输出文件类型;
快捷方法:json()

返回XML:
xml()

渲染模板:
view()

页面重定向
redirect()

附件下载
download()

重定向传参,传入session:
return redirect(‘hello’)->with(‘name’,’thinkphp’);

## 视图
模板渲染:
//fetch方法
fetch(‘[模板文件]'[,’模板变量(数组)’])

//助手函数view
view(‘[模板文件]'[,’模板变量(数组)’])

//直接解析内容而不通过模板文件display
return $this->display($content, [‘name’ => ‘thinkphp’, ’email’ => ‘thinkphp@qq.com’]);

模板赋值:
//assign方法
//模板渲染时,传入数组
//公共模板变量赋值share

## 模板引擎
变量输出:
//字符串
{$name}
//数组
{$data.name} {$data[‘name’]}
//默认值
{$user.nickname|default=’这个家伙很懒’}
//系统变量输出
{$Think.server.script_name}
//请求变量
{$Request.param.id}

使用函数:
{$Request.param.id|md5}
{:Date(‘Y-m-d H:i:s’)}

运算符:
+ – * /
{$status? ‘正常’ : ‘错误’} //三元运算

原样输出:
{literal}{/literal}

模板注释:
{/* 注释内容 */ } 或 {// 注释内容 }

模板布局:
开启layout_on
//布局文件模板

Select Code
1
2
3
{include file="public/header" /}
{__CONTENT__}
{include file="public/footer" /}

//不开启设置文件模板
{layout name=”layout” /}

模板继承:
模板可以定义一个基础模板(或者是布局),并且其中定义相关的区块(block),然后继承(extend)该基础模板的子模板中就可以对基础模板中定义的区块进行重载。

//定义一个基础模板

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{block name="title"}标题{/block}</title>
</head>
<body>
{block name="menu"}菜单{/block}
{block name="left"}左边分栏{/block}
{block name="main"}主内容{/block}
{block name="right"}右边分栏{/block}
{block name="footer"}底部{/block}
</body>
</html>

//继承模板
{extend name=”Public:base” /}

//包含文件
{include file=’模版文件1,模版文件2,…’ /}

//传入参数
{include file=”Public/header” title=”$title” keywords=”开源WEB开发框架” /}

内置标签:
– 循环 foreach, for, volist
– 比较
– 条件判断 switch, if, in/notin/between/notbetween, empty…
– 資源文件加載 load
– 原生PHP {php}…{/php}

如:

Select Code
1
2
3
{for start="0" end="10" step="2"}
    {$i},
{/for}

## 调试
– 开启调试模式 ‘app_debug’ => true,
– APP_DEBUG = true
– 开启Trace调试 ‘app_trace’ => true,
– SQL:getLastSql()
– 查看变量 halt(), dump()

## 数据库连接
数据库配置文件 config\database.php

一、查找数据
//think\Db类查找

Select Code
1
2
3
4
5
6
7
8
9
10
// table不能省略表前缀
/*$user = Db::table('tp_user')->find();   //SELECT * FROM `tp_user` LIMIT 1
$user = Db::table('tp_user')->select(); //SELECT * FROM `tp_user`
$user = Db::table('tp_user')->where('id', 1)->find();   //查找不到则返回null
try {
$user = Db::table('tp_user')->where('id', 1)->findOrFail(); //查找不到则抛出异常
//SELECT * FROM `tp_user` WHERE `id` = 1 LIMIT 1
} catch (DataNotFoundException $exception) {
echo $exception->getMessage();
}

// name可以省略表前缀

Select Code
1
2
3
4
5
6
7
8
9
10
11
$user = Db::name('user')->where(['status' => 1])->find();   //SELECT * FROM `tp_user` WHERE `status` = 1 LIMIT 1
//查找某个字段的值
$user = Db::name('user')->where(['id' => 2])->value('name');    //SELECT `name` FROM `tp_user` WHERE `id` = 2
$user = Db::name('user')->where('status', 1)->column('name');   //SELECT `name` FROM `tp_user` WHERE `status` = 1*/
$user = Db::name('user')->where('status', 1)->column('*', 'name');   //指定name字段的值作为索引 返回所有数据
// 分批量处理,chunk方法一般用于命令行操作批处理数据库的数据
Db::name('user')->where('status', 1)->chunk(5, function ($users) {
	foreach ($users as $user) {
		...
	}
});

//db()辅助方法查找

Select Code
1
//$user = db('user')->find(); //SELECT * FROM `tp_user` LIMIT 1

二、新增数据、批量添加数据:

Select Code
1
2
3
4
5
6
7
8
9
$data = ['name' => 'La', 'age' => mt_rand(10, 50)];
$res = Db::name('user')->insert($data); //INSERT INTO `tp_user` (`name` , `age`) VALUES ('La' , 19)
$res = Db::name('user')->insertGetId($data);    //添加数据后如果需要返回新增数据的自增主键
$data = [
    ['name' => 'La', 'age' => mt_rand(10, 50)],
    ['name' => 'Kobe', 'age' => mt_rand(10, 50)],
    ['name' => 'ONil', 'age' => mt_rand(10, 50)],
];
$res = Db::name('user')->insertAll($data);  //INSERT INTO `tp_user` (`name` , `age`) VALUES ( 'La',14 ) , ( 'Kobe',35 ) , ( 'ONil',16 )

三、更新数据

Select Code
1
2
3
4
5
6
7
8
9
10
dump(Db::name('user')->where('id', 17)->update(['name' => 'think_2018']));
//UPDATE `tp_user` SET `name` = 'think_2018' WHERE `id` = 17
dump(Db::name('user')->update(['name' => 'think_2017', 'id' => 16]));   //和上面等同
//UPDATE `tp_user` SET `name` = 'think_2017' WHERE `id` = 16
dump(Db::name('user')->where('id', 17)->setField('name', 'think_php')); //修改某个字段
//UPDATE `tp_user` SET `name` = 'think_php' WHERE `id` = 17
dump(Db::name('user')->where('id', 17)->setInc('age'));
//UPDATE `tp_user` SET `age` = `age` + 1 WHERE `id` = 17
dump(Db::name('user')->where('id', 16)->setDec('age'));
//UPDATE `tp_user` SET `age` = `age` - 1 WHERE `id` = 16

四、删除数据

Select Code
1
2
3
4
5
6
7
8
9
10
//根据主键删除
dump(Db::name('user')->delete(17));
//DELETE FROM `tp_user` WHERE `id` = 17
dump(Db::name('user')->delete([15, 16]));
//DELETE FROM `tp_user` WHERE `id` IN (15,16)
//条件删除
dump(Db::name('user')->where('id', 14)->delete());
//DELETE FROM `tp_user` WHERE `id` = 14
dump(Db::name('user')->where('id', '>', 13)->delete());
//DELETE FROM `tp_user` WHERE `id` > 13

五、链式操作

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$res = Db::name('user')
    ->where('status', 1)
    ->order('create_time')
    ->limit(5)
    ->select();
//SELECT * FROM `tp_user` WHERE `status` = 1 ORDER BY `create_time` LIMIT 5

$res = Db::name('user')
    ->page(2, 5)
    ->select();
//SELECT * FROM `tp_user` LIMIT 5,5

$res = Db::table('tp_user')
    ->field('id, name, age')
    ->group('age')
    ->having('id>10')
    ->fetchSql(true)
    ->select();
//SELECT `id`,`name`,`age` FROM `tp_user` GROUP BY `age` HAVING id>10

// alias, field, join, union, distinct, lock, cache, comment, fetchSql, partition

六、链式查询

Select Code
1
2
3
4
5
6
7
8
9
10
$res = Db::name('user')->fetchSql(true)->count();
//SELECT COUNT(*) AS tp_count FROM `tp_user` LIMIT 1
$res = Db::name('user')->fetchSql(true)->count('id');
//SELECT COUNT(`id`) AS tp_count FROM `tp_user` LIMIT 1
$res = Db::name('user')->fetchSql(true)->max('age');
//SELECT MAX(`age`) AS tp_max FROM `tp_user` LIMIT 1
$res = Db::name('user')->fetchSql(true)->avg('age');
//SELECT AVG(`age`) AS tp_avg FROM `tp_user` LIMIT 1
$res = Db::name('user')->fetchSql(true)->sum('age');
//SELECT SUM(`age`) AS tp_sum FROM `tp_user` LIMIT 1

## 模型
定义一个模型

Select Code
1
2
3
4
5
6
7
8
9
10
<?php

namespace app\common\model;

use think\Model;

class User extends Model
{

}

模型设置:
默认主键为id;//protected $pk = ‘id’;

一、新增数据
新增数据的最佳实践原则:使用create方法新增数据,使用saveAll批量新增数据。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$User = new User();
// 1. 实例化对象,赋值并保存
$User->name = 'LuLu';
$User->age = mt_rand(1, 99);
//INSERT INTO `tp_user` (`name` , `age`) VALUES ('LuLu' , 68)

// 2. 直接传入数据到save方法批量赋值
dump($User->save(['name' => 'Mai', 'age' => mt_rand(10, 30)])); 
//INSERT INTO `tp_user` (`name` , `age`) VALUES ('Mai' , 17)

// 3. 直接在实例化的时候传入数据
dump((new User(['name' => 'Yao', 'age' => mt_rand(20, 30)]))->save());  
// INSERT INTO `tp_user` (`name` , `age`) VALUES ('Yao' , 23)

// 新增多条数据,saveAll方法新增数据返回的是包含新增模型(带自增ID)的数据集对象。
dump($User->saveAll([
    ['name' => 'Tom', 'age' => mt_rand(1, 5)],
    ['name' => 'Jack', 'age' => mt_rand(1, 8)],
]));
//[ SQL ] INSERT INTO `tp_user` (`name` , `age`) VALUES ('Tom' , 3)
//[ SQL ] INSERT INTO `tp_user` (`name` , `age`) VALUES ('Jack' , 3)

// create方法:创建并写入,返回当前模型的对象实例
$res = User::create(['name' => 'Bob', 'age' => mt_rand(1, 5)]);
// INSERT INTO `tp_user` (`name` , `age`) VALUES ('Bob' , 5)

二、更新数据
更新的最佳实践原则是:如果需要使用模型事件,那么就先查询后更新,如果不需要使用事件,直接使用静态的Update方法进行条件更新,如非必要,尽量不要使用批量更新。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//查找并更新
$user = User::get(2);
$user->name = '3bangz';
dump($user->save());
//UPDATE `tp_user` SET `name` = '3bangz' WHERE `id` = 2

//直接更新数据
$user = new User;
dump($user->save(['name' => 'update'], ['id' => 2]));
//UPDATE `tp_user` SET `name` = 'update' WHERE `id` = 2

//静态方法更新数据
User::where('id', 2)->update(['name' => 'after update']);
//UPDATE `tp_user` SET `name` = 'after update' WHERE `id` = 2

三、查找
模型查询的最佳实践原则是:在模型外部使用静态方法进行查询,内部使用动态方法查询,包括使用数据库的查询构造器。模型的查询始终返回对象实例,但可以和数组一样使用。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//查询构造器查找并更新
$user = User::where('age', '>', 50)->find();    //SELECT * FROM `tp_user` WHERE `age` > 50 LIMIT 1
if ($user) {
    $user->age = $user->age - 1;
    dump($user->save());
    // UPDATE `tp_user` SET `age` = 57 WHERE `id` = 8
}
dump(User::where('id', 1)->find()); //返回值为null
try{
    dump(User::where('id', 1)->findOrFail());
} catch (ModelNotFoundException $exception) {
    echo $exception->getMessage();
}
//查找不到时抛出异常信息 model data Not Found:app\common\model\User
// SELECT * FROM `tp_user` WHERE `id` = 1 LIMIT 1

//根据主键获取多条信息
$users = User::all('1,2,3');    //SELECT * FROM `tp_user` WHERE `id` IN (1,2,3)
$users = User::all([1,2,3]);    //SELECT * FROM `tp_user` WHERE `id` IN (1,2,3)
dump($users);
//查询构造器,查询
$users = User::where('age', '>', 60)->select(); //SELECT * FROM `tp_user` WHERE `age` > 60
dump($users);

四、删除
删除的最佳实践原则是:如果删除当前模型数据,用delete方法,如果需要直接删除数据,使用destroy静态方法。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//删除当前模型
/*$user = User::get(3);
dump($user->delete());*/
//SELECT * FROM `tp_user` WHERE `id` = 3 LIMIT 1
//DELETE FROM `tp_user` WHERE `id` = 3

//静态方法,根据主键删除
dump(User::destroy('5,6,7'));
//SELECT * FROM `tp_user` WHERE `id` IN (2,3,4)
//DELETE FROM `tp_user` WHERE `id` = 4

//闭包函数删除
User::destroy(function ($query) {
	$query->where('id', '<', 10);
});
//SELECT * FROM `tp_user` WHERE `id` < 10

dump(User::where('id', '<', 10)->delete()); //DELETE FROM `tp_user` WHERE `id` < 10

#原创# 3分钟手动PS DIY电脑桌面详细步骤

1、打开PhotoShop,新建desk.psd文件,[Print键]截图,填充黑色背景色

2、计算截图信息,4个方块的宽度和高度,间隔10个像素
宽度 (1920-10)/2=955
高度 (1080-10)/2=535

3、新建一个图,955*535px

4、拖放入desk.psd,文字图层,键入“正在做”,文字使用居中对齐,创建成一个图层组。设置图层样式,修改背景色(配色根据自己喜好)。

5、复制3份图层组,依次放在1 2 3 4位置,拖放会自动对齐

源文件下载:desk.zip下载
1920*1080px JPG下载

复习ThinkPHP 3.2框架

该篇以ThinkPHP3.2入手,整理常用的ThinkPHP部分,如数据库操作!(推荐看官方手册)

## 第1章 课程简介 ##
本章简要介绍了本门课程的课程内容以及学习目标。
### 1-1 快速入门ThinkPHP框架课程简介
图01

推荐10款PHP框架
https://www.helloweba.net/news/557.html

课程主要内容:
– 理解MVC思想与框架思维
– ThinkPHP基础知识
– ThinkPHP数据库的操作
– 基于ThinkPHP的博客文章系统

图2

## 第2章 关于MVC ##
简要介绍MVC的工作原理。
### 2-1 MVC简析
MVC是一种设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器,它们各自处理自己的任务。

模型:处理数据和业务逻辑
视图:通过布局向用户展示数据
控制器:接收用户请求,并调用相应的模型处理

图3

图4

## 第3章 使用ThinkPHP框架建立项目 ##
本章通过介绍ThinkPHP框架的安装和引用,以及对项目目录结构的说明,让大家对ThinkPHP有一个充分的了解,并学会Hello World页面的实现。
### 3-1 框架简介
框架是程序结构代码的集合,而不是业务逻辑代码。集合中包含了许多类、函数和功能包。这个集合是按照一定标准组成的功能体系。体系有很多设计模式,比如MVC等。

### 3-2 ThinkPHP框架学习流程
1、建立一个简单项目,了解项目的运行流程

2、了解TP的URL模式,建立自定义函数库

3、模板技术,调试模式和运行状态

4、数据的常用操作

### 3-3 ThinkPHP框架简介
– 国产、开源、面向对象、MVC框架
– 简单易用,查询语言丰富,详尽的中文文档
– 官网:www.thinkphp.cn

### 3-4 关于单一入口
在一个网站中,所有的请求都是指向同一个脚本文件的。

好处:项目结构规范,控制灵活,更加安全

### 3-5 使用ThinkPHP创建一个项目

Select Code
1
2
3
4
5
// 定义应用目录
define('APP_PATH','./App/');

// 引入ThinkPHP入口文件
require './ThinkPHP/ThinkPHP.php';

### 3-6 ThinkPHP框架目录结构解析
http://document.thinkphp.cn/manual_3_2.html#directory_structure

其中框架目录ThinkPHP的结构如下:
├─ThinkPHP 框架系统目录(可以部署在非web目录下面)
│ ├─Common 核心公共函数目录
│ ├─Conf 核心配置目录
│ ├─Lang 核心语言包目录
│ ├─Library 框架类库目录
│ │ ├─Think 核心Think类库包目录
│ │ ├─Behavior 行为类库目录
│ │ ├─Org Org类库包目录
│ │ ├─Vendor 第三方类库目录
│ │ ├─ … 更多类库目录
│ ├─Mode 框架应用模式目录
│ ├─Tpl 系统模板目录
│ ├─LICENSE.txt 框架授权协议文件
│ ├─logo.png 框架LOGO文件
│ ├─README.txt 框架README文件
│ └─ThinkPHP.php 框架入口文件

## 第4章 ThinkPHP框架的简单操作 ##
本章主要讲解框架的运行原理、ThinkPHP的URL模式以及ThinkPHP的配置文件等内容,旨在让小伙伴们对ThinkPHP框架的基本操作有一个深入的了解和掌握。
### 4-1 ThinkPHP运行流程
http://document.thinkphp.cn/manual_3_2.html#system_process

ThinkPHP框架开发的应用的标准执行流程:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
用户URL请求
调用应用入口文件(通常是网站的index.php)
载入框架入口文件(ThinkPHP.php)
记录初始运行时间和内存开销
系统常量判断及定义
载入框架引导类(Think\Think)并执行Think::start方法进行应用初始化
设置错误处理机制和自动加载机制
调用Think\Storage类进行存储初始化(由STORAGE_TYPE常量定义存储类型)
部署模式下如果存在应用编译缓存文件则直接加载(直接跳转到步骤22)
读取应用模式(由APP_MODE常量定义)的定义文件(以下以普通模式为例说明)
加载当前应用模式定义的核心文件(普通模式是 ThinkPHP/Mode/common.php)
加载惯例配置文件(普通模式是 ThinkPHP/Conf/convention.php)
加载应用配置文件(普通模式是 Application/Common/Conf/config.php)
加载系统别名定义
判断并读取应用别名定义文件(普通模式是 Application/Common/Conf/alias.php)
加载系统行为定义
判断并读取应用行为定义文件(普通模式是 Application/Common/Conf/tags.php)
加载框架底层语言包(普通模式是 ThinkPHP/Lang/zh-cn.php)
如果是部署模式则生成应用编译缓存文件
加载调试模式系统配置文件(ThinkPHP/Conf/debug.php)
判断并读取应用的调试配置文件(默认是 Application/Common/Conf/debug.php)
判断应用状态并读取状态配置文件(如果APP_STATUS常量定义不为空的话)
检测应用目录结构并自动生成(如果CHECK_APP_DIR配置开启并且RUNTIME_PATH目录不存在的情况下)
调用Think\App类的run方法启动应用
应用初始化(app_init)标签位侦听并执行绑定行为
判断并加载动态配置和函数文件
调用Think\Dispatcher::dispatch方法进行URL请求调度
自动识别兼容URL模式和命令行模式下面的$_SERVER['PATH_INFO']参数
检测域名部署以及完成模块和控制器的绑定操作(APP_SUB_DOMAIN_DEPLOY参数开启)
分析URL地址中的PATH_INFO信息
获取请求的模块信息
检测模块是否存在和允许访问
判断并加载模块配置文件、别名定义、行为定义及函数文件
判断并加载模块的动态配置和函数文件
模块的URL模式判断
模块的路由检测(URL_ROUTER_ON开启)
PATH_INFO处理(path_info)标签位侦听并执行绑定行为
URL后缀检测(URL_DENY_SUFFIX以及URL_HTML_SUFFIX处理)
获取当前控制器和操作,以及URL其他参数
URL请求调度完成(url_dispatch)标签位侦听并执行绑定行为
应用开始(app_begin)标签位侦听并执行绑定行为
调用SESSION_OPTIONS配置参数进行Session初始化(如果不是命令行模式)
根据请求执行控制器方法
如果控制器不存在则检测空控制器是否存在
控制器开始(action_begin)标签位侦听并执行绑定行为
默认调用系统的ReadHtmlCache行为读取静态缓存(HTML_CACHE_ON参数开启)
判断并调用控制器的_initialize初始化方法
判断操作方法是否存在,如果不存在则检测是否定义空操作方法
判断前置操作方法是否定义,有的话执行
Action参数绑定检测,自动匹配操作方法的参数
如果有模版渲染(调用控制器display方法)
视图开始(view_begin)标签位侦听并执行绑定行为
调用Think\View的fetch方法解析并获取模版内容
自动识别当前主题以及定位模版文件
视图解析(view_parse)标签位侦听并执行绑定行为
默认调用内置ParseTemplate行为解析模版(普通模式下面)
模版引擎解析模版内容后生成模版缓存
模版过滤替换(template_filter)标签位侦听并执行绑定行为
默认调用系统的ContentReplace行为进行模版替换
输出内容过滤(view_filter)标签位侦听并执行绑定行为
默认调用系统的WriteHtmlCache行为写入静态缓存(HTML_CACHE_ON参数开启)
调用Think\View类的render方法输出渲染内容
视图结束(view_end)标签位侦听并执行绑定行为
判断后置操作方法是否定义,有的话执行
控制器结束(action_end)标签位侦听并执行绑定行为
应用结束(app_end)标签位侦听并执行绑定行为
执行系统的ShowPageTrace行为(SHOW_PAGE_TRACE参数开启并且不是AJAX请求)
日志信息存储写入

### 4-2 ThinkPHP的配置文件
配置文件是自动加载的,加载的顺序是:
惯例配置->应用配置->模式配置->调试配置->状态配置->模块配置->扩展配置->动态配置

Select Code
1
2
3
4
5
6
7
8
惯例配置文件(位于ThinkPHP/Conf/convention.php)。
应用配置文件也就是调用所有模块之前都会首先加载的公共配置文件(默认位于Application/Common/Conf/config.php)。
为应用模式(后面会有描述)单独定义配置文件,文件命名规范是: Application/Common/Conf/config_应用模式名称.php(仅在运行该模式下面才会加载)
开启调试模式后,调试配置文件(位于ThinkPHP/Conf/debug.php)和应用调试配置文件(位于Application/Common/Conf/debug.php)
状态配置:你需要在公司和家里分别设置不同的数据库测试环境。那么可以这样处理,在公司环境中,我们在入口文件中定义:define('APP_STATUS','office');那么就会自动加载该状态对应的配置文件(位于Application/Common/Conf/office.php)。
模块配置:每个模块会自动加载自己的配置文件(位于Application/当前模块名/Conf/config.php)
扩展配置:'LOAD_EXT_CONFIG' => 'user,db' 
动态配置:C('参数名称','新的参数值'),动态配置赋值仅对当前请求有效,不会对以后的请求造成影响。

获取已经设置的参数值:C(‘参数名称’)
C方法也可以用于读取二维配置:C(‘USER_CONFIG.USER_TYPE’)

### 4-3 ThinkPHP的URL模式
URL参数中解析当前请求的模块、控制器和操作,这是3.2版本的标准URL格式。

http://serverName/index.php/模块/控制器/操作

ThinkPHP框架的URL是区分大小写(主要是针对模块、控制器和操作名,不包括应用参数)的。当URL_CASE_INSENSITIVE设置为true的时候表示URL地址不区分大小写,这个也是框架在部署模式下面的默认设置。

URL模式 URL_MODEL设置
– 普通模式 0
– PATHINFO模式 1
– REWRITE模式 2
– 兼容模式 3

  • 普通模式:http://localhost/?module=home&controller=user&action=login&var=value
  • PATHINFO模式下面的URL访问地址是: http://localhost/index.php/home/user/login/var/value/
  • REWRITE模式:http://localhost/home/user/login/var/value
  • 兼容模式:http://localhost/?s=/home/user/login/var/value

URL生成:U(‘地址表达式’,[‘参数’],[‘伪静态后缀’],[‘显示域名’])
echo U(‘Index/index’, ”, ‘html’, ‘localhost’); //http://localhost/index.php/Home/Index/index.html

### 4-4 隐藏index.php文件
http://document.thinkphp.cn/manual_3_2.html#url_rewrite

### 4-5 URL伪静态
‘URL_HTML_SUFFIX’ => ‘html’, // URL伪静态后缀设置

### 4-6 自定义函数库
\App\Common\Common\function.php

## 第5章 ThinkPHP框架的模板技术 ##
本章主要讲解了ThinkPHP框架的模板的使用以及模板引擎的选择。
### 5-1 建立项目模板
// 不带任何参数 自动定位当前操作的模板文件 $this->display();

创建首页文件路径:’./App/Home/View/Index/index.html’

### 5-2 模板的赋值和输出
$this->assign(‘name’,$value);
// 下面的写法是等效的
$this->name = $value;

采用内置的模板引擎,可以使用: {$name} [ {$email} {$phone} ] 输出同样的内容。

### 5-3 ThinkPHP模板引擎介绍
ThinkPHP内置了一个基于XML的性能卓越的模板引擎 ThinkTemplate,这是一个专门为ThinkPHP服务的内置模板引擎。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'TMPL_ENGINE_TYPE'      =>  'Think',     // 默认模板引擎 以下设置仅对使用Think模板引擎有效
'TMPL_CACHFILE_SUFFIX'  =>  '.php',      // 默认模板缓存后缀
'TMPL_DENY_FUNC_LIST'   =>  'echo,exit',    // 模板引擎禁用函数
'TMPL_DENY_PHP'         =>  false, // 默认模板引擎是否禁用PHP原生代码
'TMPL_L_DELIM'          =>  '{',            // 模板引擎普通标签开始标记
'TMPL_R_DELIM'          =>  '}',            // 模板引擎普通标签结束标记
'TMPL_VAR_IDENTIFY'     =>  'array',     // 模板变量识别。留空自动判断,参数为'obj'则表示对象
'TMPL_STRIP_SPACE'      =>  true,       // 是否去除模板文件里面的html空格与换行
'TMPL_CACHE_ON'         =>  true,        // 是否开启模板编译缓存,设为false则每次都会重新编译
'TMPL_CACHE_PREFIX'     =>  '',         // 模板缓存前缀标识,可以动态改变
'TMPL_CACHE_TIME'       =>  0,         // 模板缓存有效期 0 为永久,(以数字为值,单位:秒)
'TMPL_LAYOUT_ITEM'      =>  '{__CONTENT__}', // 布局模板的内容替换标识
'LAYOUT_ON'             =>  false, // 是否启用布局
'LAYOUT_NAME'           =>  'layout', // 当前布局名称 默认为layout

// Think模板引擎标签库相关设定
'TAGLIB_BEGIN'          =>  '<',  // 标签库标签开始标记
'TAGLIB_END'            =>  '>',  // 标签库标签结束标记
'TAGLIB_LOAD'           =>  true, // 是否使用内置标签库之外的其它标签库,默认自动检测
'TAGLIB_BUILD_IN'       =>  'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序
'TAGLIB_PRE_LOAD'       =>  '',   // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔

### 5-4 ThinkPHP模板引擎之变量输出和运算
模板中使用:Hello,{$name}
默认值输出:{$user.nickname|default=”这家伙很懒,什么也没留下”}
运算符:{$user[‘score’]+10} //在使用运算符的时候,不再支持点语法和常规的函数用法

### 5-5 ThinkPHP模板引擎之调用函数和系统参数
对模板变量使用函数:{$data.name|md5}
函数有多个参数:{$create_time|date=”y-m
支持多个函数过滤,多个函数之间用“|”分割即可:{$name|md5|strtoupper|substr=0,3} 或 {:substr(strtoupper(md5($name)),0,3)}

系统变量:{$Think.server.script_name}

### 5-6 ThinkPHP模板引擎之volist和foreach循环
循环输出系统变量:

Select Code
1
2
3
<volist name="list" id="vo">
{$vo.id}:{$vo.name}<br/>
</volist>
Select Code
1
2
3
<volist name="list" id="vo" key="k" >
{$k}.{$vo.name}
</volist>

没有指定key属性的话,默认使用循环变量i

### 5-7 ThinkPHP模板引擎之FOR循环

Select Code
1
2
<for start="开始值" end="结束值" comparison="" step="步进值" name="循环变量名" >
</for>

开始值和结束值是必须,其他是可选;
comparison 的默认值是lt;

### 5-8 ThinkPHP模板引擎之IF判断

Select Code
1
2
3
4
<if condition="($name eq 1) OR ($name gt 100) "> value1
<elseif condition="$name eq 2"/>value2
<else /> value3
</if>

### 5-9 ThinkPHP模板引擎之Switch判断

Select Code
1
2
3
4
5
<switch name="变量" >
<case value="值1" break="0或1">输出内容1</case>
<case value="值2">输出内容2</case>
<default />默认情况
</switch>

### 5-10 ThinkPHP模板引擎之比较标签
标签 含义
eq或者 equal 等于
neq 或者notequal 不等于
gt 大于
egt 大于等于
lt 小于
elt 小于等于
heq 恒等于
nheq 不恒等于

### 5-11 ThinkPHP模板引擎之区间标签
范围判断标签包括in notin between notbetween四个标签,都用于判断变量是否中某个范围。

### 5-12 ThinkPHP模板引擎之三元运算符

Select Code
1
2
{$status?'正常':'错误'}
{$info['status']?$info['msg']:$info['error']}

注意:三元运算符中暂时不支持点语法。

### 5-13 ThinkPHP模板引擎之案例实战

## 第6章 ThinkPHP框架的调试模式 ##
本章主要讲解了调试模式的用途以及如何使用调试模式进行相关的开发。
### 6-1 ThinkPHP的调试方法
开启调试模式:define(‘APP_DEBUG’,True);
在开启调试模式的状态下,系统会首先导入框架默认的调试模式配置文件,该文件位于系统目录的Conf\debug.php。

显示页面Trace信息
‘SHOW_PAGE_TRACE’ =>true,

系统提供了G方法可以很方便的获取某个区间的运行时间和内存占用情况

除了使用php内置的var_dump和print_r之外,内置了一个对浏览器友好的dump方法,用于输出变量的信息到浏览器查看。

默认情况下只是在调试模式记录日志,要在部署模式开启日志记录,必须在配置中开启LOG_RECORD参数,以及可以在应用配置文件中配置需要记录的日志级别
‘LOG_RECORD’ => true, // 开启日志记录

## 第7章 数据库操作(一) ##
本章主要讲解了ThinkPHP框架独特的CURD的操作方式,以及在查询数据库时所用的连贯操作、视图模型等内容。
### 7-1 连接数据库

Select Code
1
2
3
4
5
6
7
8
9
10
//数据库配置信息
'DB_TYPE'   => 'mysql', // 数据库类型
'DB_HOST'   => 'localhost', // 服务器地址
'DB_NAME'   => 'thinkphp', // 数据库名
'DB_USER'   => 'root', // 用户名
'DB_PWD'    => '123456', // 密码
'DB_PORT'   => 3306, // 端口
'DB_PREFIX' => 'think_', // 数据库表前缀 
'DB_CHARSET'=> 'utf8', // 字符集
'DB_DEBUG'  =>  TRUE, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增

如果在某个模型类里面定义了connection属性的话,则实例化该自定义模型的时候会采用定义的数据库连接信息。通常用于某些数据表位于当前数据库连接之外的其它数据库。

除了在模型定义的时候指定数据库连接信息外,我们还可以在实例化的时候指定数据库连接信息。

分布式数据库:
内置了分布式数据库的支持,包括主从式数据库的读写分离,但是分布式数据库必须是相同的数据库类型。
配置DB_DEPLOY_TYPE 为1 可以采用分布式数据库支持。
‘DB_HOST’ => ‘192.168.0.1,192.168.0.2’,

对于主从式数据库而言,需要设置读写分离,通过下面的设置就可以:
‘DB_RW_SEPARATE’=>true,
注意:主从数据库的数据同步工作不在框架实现,需要数据库考虑自身的同步或者复制机制。在读写分离的情况下,默认第一个数据库配置是主服务器的配置信息,负责写入数据,设置了DB_MASTER_NUM参数,则可以支持多个主服务器写入。

### 7-2 实例化模型
准备表:

Select Code
1
2
3
4
5
6
7
8
CREATE TABLE IF NOT EXISTS tp_user(
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL DEFAULT '',
age TINYINT(1) NOT NULL DEFAULT 2,
create_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP()
)DEFAULT CHARSET=utf8;

INSERT tp_user(id,name,age) VALUES(NULL,'Ada',10),(NULL,'Lucy',10),(NULL,'May',18),(NULL,'Kitty',22),(NULL,'David',30);

创建模型类文件
参数 实例化的模型文件(假设当前模块为Home)
User 对应的模型类文件的 \Home\Model\UserModel.class.php
UserType 对应的模型类文件的 \Home\Model\UserTypeModel.class.php

D方法实例化
当 \Home\Model\UserModel 类不存在的时候,D函数会尝试实例化公共模块下面的 \Common\Model\UserModel 类。
D方法可以自动检测模型类,如果存在自定义的模型类,则实例化自定义模型类,如果不存在,则会实例化系统的\Think\Model基类,同时对于已实例化过的模型,不会重复去实例化。

Select Code
1
2
$User = D('User');
//相当于 $User = new \Home\Model\UserModel();

M方法实例化模型
D方法实例化模型类的时候通常是实例化某个具体的模型类,如果你仅仅是对数据表进行基本的CURD操作的话,使用M方法实例化的话,由于不需要加载具体的模型类,所以性能会更高。

Select Code
1
2
$User = M('User');
//和用法 $User = new \Think\Model('User'); 等效
Select Code
1
2
3
4
5
$model = new Model('User'); //等同于M('User')
$model = M('User');
$User = D('User');  //实例化Common\Model\UserModel模型
dump($User->getUserInfo(1));
$all_user = $model->select();

实例化空模型类

Select Code
1
2
3
4
5
6
//实例化空模型
$Model = new Model();
//或者使用M快捷方法是等效的
$Model = M();
//进行原生的SQL查询
$Model->query('SELECT * FROM think_user WHERE status = 1');

### 7-3 CURD操作之添加数据

Select Code
1
2
3
4
5
6
7
$User = D('User');
//新增用户
$data = [
	'name' => 'zhangsan',
	'age' => 28
];
$res = $User->add($data);   //返回值为主键id值
Select Code
1
2
3
4
5
6
7
8
$User = D('User');
//批量新增用户
$data = [
	['name' => 'lisi', 'age' => 20],
	['name' => 'wangwu', 'age' => 58],
	['name' => 'liujiu', 'age' => 1]
];
$res = $User->addAll($data);   //返回值为主键id值
Select Code
1
$User->fetchSql(true)->addAll($data) //只生成SQL,不执行

### 7-4 CURD操作之查询数据

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$user = $User->order('id desc')->find();
echo $User->getLastSql();
echo '<br>';
$user = $User->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` LIMIT 1
echo '<br>';
$user = $User->order('id desc')->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` ORDER BY id desc LIMIT 1
echo '<br>';
$user = $User->order('id desc')->select();
echo $User->getLastSql();   //SELECT * FROM `tp_user` ORDER BY id desc
echo '<br>';
$where = [
	'id' => 1,
];
$user = $User->where($where)->order('id desc')->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` WHERE `id` = 1 ORDER BY id desc LIMIT 1
echo '<br>';
$where = [
	'id' => 1,
	'name' => 'Ada'
];
$user = $User->where($where)->order('id desc')->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` WHERE `id` = 1 AND `name` = 'Ada' ORDER BY id desc LIMIT 1
echo '<br>';
//连贯操作之字段值
$user = $User->getField('id,name');
echo $User->getLastSql();   //SELECT `id`,`name` FROM `tp_user`
echo '<br>';
$where = [
	'name' => ['like', 'A%'],
];
$user = $User->where($where)->order('id desc')->select();
echo $User->getLastSql();   //SELECT * FROM `tp_user` WHERE `name` LIKE 'A%' ORDER BY id desc 
echo '<br>';
//区间查询
$where = [
	'id' => [
		['gt', 1],
		['lt', 3]
	]
];
$user = $User->where($where)->getField('id,name');
echo $User->getLastSql();   //SELECT `id`,`name` FROM `tp_user` WHERE ( `id` > 1 AND `id` < 3 )
echo '<br>';

### 7-5 CURD操作之更新数据

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
// 更新数据
$data['name'] = 'Think';
$data['update_time'] = date('Y-m-d H:i:s', time());
$res = $User->where(['id' => 1])->save($data);  //1
// 更新字段值
$res = $User->where(['id' => 2])->setField('name', 'after...');
// 自增1
$res = $User->where(['id' => 3])->setInc('age');
// 自增3
$res = $User->where(['id' => 4])->setInc('age', 3);
// 自减
$res = $User->where(['id' => 5])->setDec('age');
dump($res);

### 7-6 CURD操作之删除数据

Select Code
1
2
3
4
5
6
7
8
$where = ['id' => 2];
$res = $User->where($where)->fetchSql(true)->delete();  //DELETE FROM `tp_user` WHERE `id` = 2

$where = ['id' => ['in', [2,3,4]]];
$res = $User->where($where)->fetchSql(true)->delete();  //DELETE FROM `tp_user` WHERE `id` IN (2,3,4)

$where = ['id' => ['lt', 5]];
$res = $User->where($where)->fetchSql(true)->delete();  //DELETE FROM `tp_user` WHERE `id` < 5

## 第8章 数据库操作(二) ##
本章主要讲解了ThinkPHP框架独特的CURD的操作方式,以及在查询数据库时所用的连贯操作、视图模型等内容。
### 8-1 连贯操作之order排序
$Model->where(‘status=1’)->order(‘id desc,status’)->limit(5)->select();

### 8-2 连贯操作之field方法
$Model->field(‘id,nickname as name’)->select();

### 8-3 连贯操作之limit和page方法

Select Code
1
2
3
4
$User->where('status=1')->field('id,name')->limit(10)->select();
$Article->limit('10,25')->select();
$Article->page('1,10')->select(); // 查询第一页数据
$Article->page('2,10')->select(); // 查询第二页数据

### 8-4 连贯操作之group和having方法

Select Code
1
2
3
4
5
$this->field('username,max(score)')->group('user_id')->select();
//SELECT username,max(score) FROM think_score GROUP BY user_id

$this->field('username,max(score)')->group('user_id')->having('count(test_time)>3')->select(); 
//SELECT username,max(score) FROM think_score GROUP BY user_id HAVING count(test_time)>3

### 8-5 多表查询之table方法

Select Code
1
2
3
4
5
$Model->table('think_user')->where('status>1')->select();

$Model->field('user.name,role.title')
->table(array('think_user'=>'user','think_role'=>'role'))
->limit(10)->select();

### 8-6 多表查询之join方法

Select Code
1
2
3
4
5
$Model = M('Artist');
$Model
->join('think_work ON think_artist.id = think_work.artist_id')
->join('think_card ON think_artist.card_id = think_card.id')
->select();

INNER JOIN: 如果表中有至少一个匹配,则返回行,等同于 JOIN
LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
FULL JOIN: 只要其中一个表中存在匹配,就返回行

### 8-7 多表查询之union方法

Select Code
1
2
3
4
5
$Model->field('name')
->table('think_user_0')
->union('SELECT name FROM think_user_1')
->union('SELECT name FROM think_user_2')
->select();

//每个union方法相当于一个独立的SELECT语句。

### 8-8 过滤查询之distinct方法
$Model->distinct(true)->field(‘name’)->select();
//SELECT DISTINCT name FROM think_user

## 第9章 关于命名范围的使用 ##
本章介绍了命名范围在实际项目中的使用方法和适用场景。
### 9-1 命名范围的使用
要使用命名范围功能,主要涉及到模型类的_scope属性定义和scope连贯操作方法的使用。

*Common\Model\UserModel.class.php*

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected $_scope = array(
	'normal' => [
		'order' => 'id asc',
	],
	'latest' => [
		'order' => 'id desc',
		'limit' => 5,
	]
);

$res = $User->scope('normal')->fetchSql(true)->select();
dump($res); //SELECT * FROM `tp_user` ORDER BY id asc
$res = $User->scope('latest')->fetchSql(true)->select();
dump($res); //SELECT * FROM `tp_user` ORDER BY id desc LIMIT 5

新安装MySQL常用命令整理

## CMD
* mysql -uroot -p –default-character-set=utf8 exam <C:/exam.sql
* mysql -uroot -p exam < C:/exam.sql * mysqldump -uroot -p dbname >db.sql

从mysql中导出数据库mysite:
在终端运行:mysqldump -h localhost -u root -p mysite > /home/wade/文档/test.sql
其中localhost是服务器名字 mysite是数据库名字,test.sql为输出的sql文件

将test.sql 导入到mysql数据库:
在终端运行:mysql -h localhost -u root -p mysite < /test.sql –default-character-set=utf8
其中:–default-character-set=utf8 解决中文乱码

新版本导入数据库步骤:
create database qiaomoxuan default charset ‘utf8’;
use qiaomoxuan
source d:/qiaomoxuan0731.sql

为WAMP3.0.6中的mysql设置密码
use mysql
update MySQL.user set authentication_string=password(‘root’) where user=’root’;
flush privileges;

修改配置文件,设置默认引擎为InnoDB:
default-storage-engine=InnoDB

创建表示例:
CREATE TABLE IF NOT EXISTS tp_user(
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL DEFAULT ”,
age TINYINT(1) NOT NULL DEFAULT 2,
create_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP()
)DEFAULT CHARSET=UTF8;

临时设置客户端默认字符集:
SET NAMES utf8;

查看创建表的语句:
SHOW CREATE TABLE tp_user;

Redis的基础应用

一、概念
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

Redis 与其他 key – value 缓存产品有以下三个特点:
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
– Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
– Redis支持数据的备份,即master-slave模式的数据备份。

Redis 优势
– 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
– 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
– 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
– 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

二、安装
http://www.runoob.com/redis/redis-install.html

三、五种数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

Strings
append – Append a value to a key
get – Get the value of a key
incr, incrBy – Increment the value of a key
set – Set the string value of a key
setRange – Overwrite part of a string at key starting at the specified offset
strLen – Get the length of the value stored in a key

Hashes
hDel – Delete one or more hash fields
hExists – Determine if a hash field exists
hGet – Get the value of a hash field
hGetAll – Get all the fields and values in a hash
hKeys – Get all the fields in a hash
hLen – Get the number of fields in a hash
hMGet – Get the values of all the given hash fields
hMSet – Set multiple hash fields to multiple values
hSet – Set the string value of a hash field
hVals – Get all the values in a hash
hScan – Scan a hash key for members
hStrLen – Get the string length of the value associated with field in the hash

Lists
lPop – Remove and get the first element in a list
lPush – Prepend one or multiple values to a list
lSet – Set the value of an element in a list by its index
rPop – Remove and get the last element in a list
rPush – Append one or multiple values to a list

Sets
sAdd – Add one or more members to a set
sCard, sSize – Get the number of members in a set
sPop – Remove and return one or more members of a set at random
sRandMember – Get one or multiple random members from a set
sScan – Scan a set for members

Sorted sets
zAdd – Add one or more members to a sorted set or update its score if it already exists
zCard, zSize – Get the number of members in a sorted set
zCount – Count the members in a sorted set with scores within the given values
zIncrBy – Increment the score of a member in a sorted set
zInter – Intersect multiple sorted sets and store the resulting sorted set in a new key
zRange – Return a range of members in a sorted set, by index
zRank, zRevRank – Determine the index of a member in a sorted set
zScore – Get the score associated with the given member in a sorted set

四、redis的PHP扩展
扩展 https://github.com/phpredis/phpredis

五、PHP操作redis

Select Code
1
2
3
4
5
<?php
   //连接本地的 Redis 服务
   $redis = new Redis();
   $redis->connect('127.0.0.1', 6379);
?>