1.聚合函数及having使用细节
$info = $goods -> where() -> field(字段) -> select();
1、返回一个二维数组信息
2、返回全部数据表信息
3、给该方法传递参数
1) select(20) 查询主键值等于30的记录信息
2) select(“20,21,22,23”); 查询主键值等于20,21,22,23的记录信息
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function showlist(){
$goods = D("Goods");
//查询主键值等于30的记录信息
//$info = $goods -> select(30);
//查询主键值等于20,21,22,23的记录信息
$info = $goods -> select("20,21,22,23");
//把数据assign到模板
$this -> assign('info',$info);
$this->display();
}
4、find()如果我们查询的结果只有一个信息,使用select()会返回一个二维数组,为了使用方便我们可以返回一个一维数组,这时候可使用find()方法
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function showlist(){
$goods = D("Goods");
$info = $goods -> find(30); //返回一维数组结果
show_bug($info);
$this->display();
}
5、having()方法设置查询条件,where()方法设置查询条件
1)、使用有先后顺序
2)、where price>100 having price>100
3)、where设置条件,字段必须是数据表中存在的字段
4)、having设置条件,字段必须是selec语句查询出来的字段
//两者都能使用的情况
select goods_price,goods_number from sw_goods where goods_price>100 //正确
select goods_price,goods_number from sw_goods having goods_price>100 //正确
//只可以使用where,不可以使用having
select goods_name,goods_number from sw_goods where goods_price>100 //正确
select goods_name,goods_number from sw_goods having goods_price>100 //错误
//只可以使用having,不可以使用where
//查询每种goods_category_id商品的价格平均值,获得平均价格大于1000的种类信息
select goods_category_id,avg(goods_price) as ag from sw_goods where ag>1000 group by goods_category_id //错误
select goods_category_id,avg(goods_price) as ag from sw_goods group by goods_category_id having ag>1000 //正确
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function showlist(){
$goods = D("Goods");
$info = $goods -> having('goods_price > 1000') -> select();
//把数据assign到模板
$this -> assign('info',$info);
$this->display();
}
6、相关聚合函数 count() sum() avg() max() min()
以上聚合函数是最后被调用的方法,可以结合具体条件方法使用
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function showlist(){
$goods = D("Goods");
//查询记录总条数
echo $goods -> count();
echo "<br/>";
//获得价格最高的商品信息
echo $goods -> max('goods_price');
echo "<br/>";
//获得价格大于1000的商品总数
echo $goods -> where('goods_price > 1000') -> count();
echo "<br/>";
//此时limit()不起效果
//运行时默认为limit(1)
echo $goods -> limit(5) -> where('goods_price > 1000') -> count();
//把数据assign到模板
$this -> assign('info',$info);
$this->display();
}
2.添加数据记录add
数组方式实现数据添加
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
//添加商品
public function add(){
//利用数组方式实现数据添加
$goods = D("Goods");
$ar = array(
'goods_name' => '红米Pro',
'goods_price' => 1000,
'goods_number' => 53,
);
//goods_name、goods_price、goods_number是数据表中字段名称
$rst = $goods -> add($ar);
show_bug($rst);
if ($rst > 0) {
echo "success";
}else{
echo "failure";
}
$this->display();
}
AR方法实现数据添加
TP框架中的AR是假的,但是可以实现
1、ActiveRecord 活跃记录
2、AR规定了程序与数据库之间的关系
1)、一个数据表对应一个类Model
2)、一条数据记录对应类的一个对象
3)、每个字段对应该对象的具体属性
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
//添加商品
public function add(){
//利用AR方式实现数据添加
$goods = D("Goods");
$goods -> goods_name = '红米';
$goods -> goods_price = 1200;
$goods -> goods_number = 53;
$rst = $goods -> add($ar);
show_bug($rst);
if ($rst > 0) {
echo "success";
}else{
echo "failure";
}
$this->display();
}
3.收集表单数据并实现收集添加
制作一个表单
shop/Admin/View/Goods/add.html
程序代码如下:
/* 常量__SELF__对应的路径为:ThinkPHP/shop/index.php/Admin/Goods/add */
<form action="{$smarty.const.__SELF__}" method="post" enctype="multipart/form-data">
<table border="1" width="100%" class="table_a">
<tr>
<td>商品名称</td>
<td><input type="text" name="goods_name" /></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="goods_price" /></td>
</tr>
<tr>
<td>商品数量</td>
<td><input type="text" name="goods_number" /></td>
</tr>
<tr>
<td>商品重量</td>
<td><input type="text" name="goods_weight" /></td>
</tr>
<tr>
<td>商品详细描述</td>
<td>
<textarea name="goods_introduce"></textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="添加">
</td>
</tr>
</table>
</form>
通过$_POST收集信息
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function add(){
//两个逻辑:1、展现表单;2、接受表单数据
//echo __SELF__;
//该常量对应的路径为:ThinkPHP/shop/index.php/Admin/Goods/add
if (!empty($_POST)) {
//输出_POST信息
print_r($_POST);
} else {
$this->display();
}
}
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function add(){
//两个逻辑:1、展现表单;2、接受表单数据
$goods = D("Goods");
if (!empty($_POST)) {
$ar = $_POST;
$z = $goods -> add($ar);
if ($z) {
echo "success";
} else {
echo "failure";
}
} else {
$this->display();
}
}
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function add(){
//两个逻辑:1、展现表单;2、接受表单数据
$goods = D("Goods");
if (!empty($_POST)) {
$goods -> goods_name = $_POST['goods_name'];
$goods -> goods_price = $_POST['goods_price'];
$goods -> goods_number = $_POST['goods_number'];
$goods -> goods_weight = $_POST['goods_weight'];
$goods -> goods_introduce = $_POST['goods_introduce'];
$z = $goods -> add($ar);
if ($z) {
echo "success";
} else {
echo "failure";
}
} else {
$this->display();
}
}
通过create()方法实现数据收集
使用AR方式时,当有相对多的字段进行添加,可以使用create()方法实现数据收集,并且对于非法的字段会自动进行过滤
数据模型对象 -> create()
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function add(){
//两个逻辑:1、展现表单;2、接受表单数据
$goods = D("Goods");
if (!empty($_POST)) {
$goods -> create();
$z = $goods -> add($ar);
if ($z) {
echo "success";
} else {
echo "failure";
}
} else {
$this->display();
}
}
ThinkPHP/Library/Think/Model.class.php
程序代码如下:
/**
* 创建数据对象 但不保存到数据库
* @access public
* @param mixed $data 创建数据
* @param string $type 状态
* @return mixed
*/
public function create($data='',$type='') {
// 如果没有传值默认取POST数据
if(empty($data)) {
// 收集post表单数据并传递给$data
$data = I('post.');
...
// 验证完成生成数据对象
if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据
$fields = $this->getDbFields();
foreach ($data as $key=>$val){
if(!in_array($key,$fields)) {
// 提交的表单数据如果与数据表中字段不匹配将进行过滤
unset($data[$key]);
}elseif(MAGIC_QUOTES_GPC && is_string($val)){
$data[$key] = stripslashes($val);
}
}
}
...
// 返回创建的数据以供其他调用
return $data;
}
4.实现数据修改save
注意:
1、明确告诉系统哪条数据被更新
2、设置where进行数据更新
save()方法返回值:
0:执行没有问题,执行前后数据没有变化
自然数:受影响的记录条数
false:执行失败
程序代码如下:
//数组形式
$goods = D("Goods");
$ar = arrat('goods_name'=>'联想手机';'goods_price'=>1200);
$goods -> save($ar);
//AR形式
$goods = D("Goods");
$goods -> goods_name = 联想手机;
$goods -> goods_price =>1200;
$goods -> save();
上述程序将会修改全部数据,SQL语句从技术上可行,但从业务上不可行(事故),以上情况在TP框架中不可被执行。
需要做出如下修改
程序代码如下:
//数组形式
//情况1
$goods = D("Goods");
$ar = arrat('goods_id'=>12;'goods_name'=>'联想手机';'goods_price'=>1200);
$goods -> save($ar);
//情况1
$goods = D("Goods");
$ar = arrat('goods_name'=>'联想手机';'goods_price'=>1200);
$goods -> where('goods_price > 1000') -> save($ar);
//AR形式
//情况1
$goods = D("Goods");
$goods -> goods_id = 12;
$goods -> goods_name = 联想手机;
$goods -> goods_price =>1200;
$goods -> save();
//情况2
$goods = D("Goods");
$goods -> goods_name = 联想手机;
$goods -> goods_price =>1200;
$goods -> where('goods_price > 1000') -> save();
5.删除数据及原生SQL语句执行
删除数据
$goods = D("Goods");
//以下三种方式都可以删除数据
$goods -> delete(63); //删除主键值等于30的记录信息
$goods -> delete('10,20,30'); //删除主键值等于10,20,30的三条记录
$goods -> where('goods_id > 50 ') -> delete(); //删除goods_id大于50的全部记录
执行原生SQL语句
1、查询语句query() 返回一个二维数组信息
2、添加、修改、删除、execute() 返回受影响的记录条数
程序代码如下:
$goods = D("Goods");
$sql = "select * from sw_goods";
$goods -> query($sql);
$sql = "select goods_category_id from sw_goods group by goods_category_id having avg(goods_price)>1000";
$rst = $goods -> query($sql);
$sql = "update sw_goods set goods_name='红米' where goods_id=100";
$goods -> execute($sql);
6.后台商品修改实现
通过路由给一个操作方法传递参数
http://网址/index.php/模块/控制器/方法upd/变量名1/值/变量名2/值/变量名3/值
以上路由是通过get形式给指定的操作传递了三个参数信息
单参数$_GET接收
原则上参数信息接收的时候通过$_GET接收即可
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
//修改商品
public function upd(){
echo $_GET['goods_id'];
$this->display();
}
访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2
多参数$_GET接收
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
//修改商品
public function upd(){
echo $_GET['goods_id'];
echo $_GET['name'];
$this->display();
}
访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2/name/tom
但是以上参数信息接收太直接,不安全,需要按照框架规则使用如下方式接收get参数信息
使用操作方法接收参数
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function upd($name,$goods_id){
echo $goods_id;
echo $name;
$this->display();
}
访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2/name/tom
以上参数表述,如果在请求的时候没有按照规则传递参数,那么当前方法禁止访问,除非参数已经设置了默认值。
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function upd($name=tom,$goods_id){
echo $goods_id;
echo $name;
$this->display();
}
访问http://localhost/ThinkPHP/shop/index.php/Admin/Goods/upd/goods_id/2
修改商品信息步骤
1、在“修改”按钮处把修改商品id信息通过get形式传递给upd操作
shop/Admin/View/Goods/showlist.html
程序代码如下:
<a href="{$smarty.const.__CONTROLLER__}/upd/goods_id/{$v.goods_id}">修改</a>
2、在upd方法中制作形式参数$good_id,接受浏览器传递的get变量goods_id
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
//修改商品
public function upd($goods_id){
$this->display();
}
3、表单添加隐藏域或在方法内设置where语句,确保SQL语句在TP框架能执行
4、在upd操作方法内部有两个逻辑:展现表单、收集表单。
shop/Admin/View/Goods/upd.html
程序代码如下:
<form action="" method="post" enctype="multipart/form-data">
{*隐藏域传递被修改的商品id信息*}
<input type="hidden" name="goods_id" value="{$info.goods_id}" />
<table border="1" width="100%" class="table_a">
<tr>
<td>商品名称</td>
<td><input type="text" name="goods_name" value="{$info.goods_name}" /></td>
</tr>
...
<tr>
<td>商品详细描述</td>
<td>
<textarea name="f_goods_introduce">{$info.goods_introduce}</textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="修改">
</td>
</tr>
</table>
</form>
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function upd($goods_id){
$goods = D("Goods");
//两个逻辑:1、展示表单;2、收集表单
if (!empty($_POST)) {
//print_r($_POST);
$goods -> create();
$rst = $goods -> save();
if ($rst) {
echo "success";
} else {
echo "failure";
}
} else {
$info = $goods -> find($goods_id); //一维数组
$this -> assign('info',$info);
$this->display();
}
}
shop/Admin/View/Goods/upd.html
程序代码如下:
<form action="{$smarty.const.__SELF__}" method="post" enctype="multipart/form-data">
<table border="1" width="100%" class="table_a">
<tr>
<td>商品名称</td>
<td><input type="text" name="goods_name" value="{$info.goods_name}" /></td>
</tr>
</tr>
...
<tr>
<td colspan="2" align="center">
<input type="submit" value="修改">
</td>
</tr>
</table>
</form>
shop/Admin/Controller/GoodsController.class.php
程序代码如下:
public function upd($goods_id){
$goods = D("Goods");
//两个逻辑:1、展示表单;2、收集表单
if (!empty($_POST)) {
//print_r($_POST);
$goods -> create();
$rst = $goods -> where("goods_id = $goods_id" )-> save();
if ($rst) {
echo "success";
} else {
echo "failure";
}
} else {
$info = $goods -> find($goods_id); //一维数组
$this -> assign('info',$info);
$this->display();
}
}
7.注册表单验证
制作表单
表单form数据通过create()方法收集
shop/Home/View/User/register.html
程序代码如下:
<form id="yw0" action="{$smarty.const.__SELF__}" method="post">
<table cellpadding="5" cellspacing="3" style="text-align:left; width:100%; border:0;">
<tbody>
<tr>
<td style="width:13%; text-align: right;">
<label for="User_username" class="">用户名
<span class="">*</span>
</label>
</td>
<td style="width:87%;">
<input class="" size="25" name="username" id="User_username" type="text" value="" />
<span style="color:red;">用户名已经存在</span>
</td>
</tr>
<tr>
<td align="right">
<label for="User_password" class="">密码
<span class="">*</span>
</label>
</td>
<td>
<input class="" size="25" name="password" id="User_password" type="password" value="" />
</td>
</tr>
<tr>
<td align="right">
<label for="User_password2">密码确认</label>
</td>
<td>
<input class="" size="25" name="password2" id="User_password2" type="password" />
</td>
</tr>
<tr>
<td align="right">
<label for="User_user_email">邮箱</label>
</td>
<td>
<input class="" size="25" name="user_email" id="User_user_email" type="text" value="" />
</td>
</tr>
<tr>
<td align="right">
<label for="User_user_qq">qq号码</label>
</td>
<td>
<input class="" size="25" name="user_qq" id="User_user_qq" type="text" value="" />
</td>
</tr>
<tr>
<td align="right">
<label for="User_user_tel">手机</label>
</td>
<td>
<input class="" size="25" name="user_tel" id="User_user_tel" type="text" value="" />
</td>
</tr>
<tr>
<td align="right">
<label for="User_user_sex">性别</label>
</td>
<td>
<input id="ytUser_user_sex" type="hidden" value="" name="user_sex" />
<span id="User_user_sex">
<input id="User_user_sex_0" value="1" checked="checked" type="radio" name="user_sex" />
<label for="User_user_sex_0">男</label>
<input id="User_user_sex_1" value="2" type="radio" name="user_sex" /
<label for="User_user_sex_1">女</label>
<input id="User_user_sex_2" value="3" type="radio" name="user_sex" />
<label for="User_user_sex_2">保密</label></span>
</td>
</tr>
<tr>
<td align="right"><label for="User_user_xueli">学历</label></td>
<td>
<select name="user_xueli" id="User_user_xueli">
<option value="1" selected="selected">-请选择-</option>
<option value="2">小学</option>
<option value="3">初中</option>
<option value="4">高中</option>
<option value="5">大学</option>
</select>
<div class="" id="User_user_xueli_em_" style="display:none"></div>
</td>
</tr>
<tr>
<td align="right"><label for="User_user_hobby">爱好</label></td>
<td>
<input id="ytUser_user_hobby" type="hidden" value="" name="user_hobby" />
<span id="User_user_hobby">
<input id="User_user_hobby_0" value="1" type="checkbox" name="user_hobby[]" />
<label for="User_user_hobby_0">篮球</label>
<input id="User_user_hobby_1" value="2" type="checkbox" name="user_hobby[]" />
<label for="User_user_hobby_1">足球</label>
<input id="User_user_hobby_2" value="3" type="checkbox" name="user_hobby[]" />
<label for="User_user_hobby_2">排球</label>
<input id="User_user_hobby_3" value="4" type="checkbox" name="user_hobby[]" />
<label for="User_user_hobby_3">棒球</label>
</span>
</td>
</tr>
<tr>
<td align="right"><label for="User_user_introduce">简介</label></td>
<td>
<textarea cols="50" rows="5" name="user_introduce" id="User_user_introduce"></textarea>
</td>
</tr>
<tr>
<td> </td>
<td align="left">
<input name="Submit" value="用户注册" class="" type="submit" />
</td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
</tbody>
</table>
</form>
自定义数据Model模型类实现具体验证规则
shop/Home/Controller/UserController.class.php
程序代码如下:
function register(){
$user = new \Model\UserModel();
//判断表单是否提交
if (!empty($_POST)) {
//print_r($_POST);
$z = $user -> create(); //集成表单验证
//只有全部验证通过$z才会为真
if (!$z) {
//验证失败,输出错误信息
//getError()方法返回验证失败的信息
show_bug($user->getError());
} else {
$rst = $user -> add();
if ($rst) {
echo "success";
} else {
echo "error";
}
}
} else {
//$this -> display();
}
//为了开发方便,将$this -> display()放到这里
$this -> display();
}
shop/Model/UserModel.class.php
程序代码如下:
<?php
namespace Model;
use Think\Model;
class UserModel extends Model{
//一次性获得全部验证错误
//是否批处理验证
protected $patchValidate=true;
//实现表单项目验证
//通过重写父类属性_validate实现表单验证
protected $_validate=array(
//用户名验证
array('username','require','用户名必须填写'),
array('username','','用户名已存在',0,'unique'),
//密码验证
array('password','require','密码必须填写'),
array('password','5,10','密码位数必须5-10之间',0,'length'),
//确认密码验证
array('password2','require','确认密码必须填写'),
//与密码的值必须一致
array('password2','password','两次密码必须一致',0,'confirm'),
//邮箱验证
array('user_email','email','邮箱格式不正确'),
//qq验证
// array('user_qq','number','qq号码必须是数字'),
// array('user_qq','5,12','qq号码位数5到12之间',0,'length'),
array('user_qq',"/^[1-9]\d{4,11}$/",'qq格式不正确'),
//手机号码验证
array('user_tel','/^1\d{10}$/','手机号码格式不正确'),
//验证学历
// array('user_xueli','1','学历必须选择一个',0,'notin'),
array('user_xueli',"2,3,4,5",'学历必须选择一个',0,'in'),
//验证爱好
//爱好项目至少选择两项以上
//爱好的值是一个数组,判断其元素个数即可知道结果
//callback利用当前Model中的一个指定方法进行验证
array('user_hobby',"check_hobby",'爱好必须选择两项以上',0,'callback'),
);
//自定义方法验证爱好信息
//$name参数是当前被验证项目的信息
//$name = $_POST['user_hobby']
function check_hobby($name){
if (count($name)<2) {
return false;
} else {
return true;
}
}
}

验证条件
注意:
1、通过new进行模型实例化
2、调用create()方法才可以触发TP自动验证