TP框架课堂练习:上传照片
学习TP框架后 ,发觉TP框架比PHP的思路还要复杂,所以整理了如何去看懂流程和自己去理解的思路
初学TP框架一般都是把一整个网站分成一个个简单的功能去学习,那样代码不是很多,所以可以从HTML5代码和相关的TP代码去分析。在我们课堂中,上传照片只有简单的三个页面,所以分成三个部分去理解
TP安装特别容易,只要把下载的压缩包解压并放在相关项目中就可以
TP框架的下载路径:http://www.thinkphp.cn/
第一个页面:上传页面
先看相关页面代码
HTML页面,路径:Application\Home\View\Index\index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<!--注意,enctype一定要设置为multipart/form-data-->
<form action="" method="post" enctype="multipart/form-data">
<table style="width:400px;height: 130px;border-collapse: collapse;margin: 20px auto;">
<tr>
<td> 商品名:</td>
<td><input type="text" name="gname" /></td>
</tr>
<tr>
<td> 上传图片:</td>
<td><input type="file" name="img" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="提交" /> <a href="__CONTROLLER__/lst">查看列表</a></td>
</tr>
</table>
</form>
</body>
</html>
控制器:IndexController.class.php,所有PHP代码都在里面写,项目中的路径:Application\Home\IndexController.class.php
public function index() {
if (IS_POST) {//判断是否有POST请求数据,有就处理数据,没有就显示添加表单页面
if ($_FILES['img']['size']) {//判断是否有图片上传,有则上传图片,没有则使用默认图片
//获得图片的路径并保存到$data['imgpath']中
$data['imgpath'] = $this->upload($_FILES['img']);
}else{
$data['imgpath'] = 'default.jpg';
}
//获取商品名并保存到$data['gname']中
$data['gname'] = $_POST['gname'];
//实例化ginfo表模型类并调用add方法向数据库添加商品信息
$res = D('ginfo')->add($data);
if ($res) {
//上传成功跳转到商品列表页面
$this->success('添加成功,请稍等...', U('lst'));
return;
}
$this->error();
}
$this->display();
}
public function upload($img) {
$upload = new \Think\Upload();//实例化TP框架的文件上传类
$upload->maxSize = 3145728;//配置上传文件的大小
$upload->rootPath = './Public/Uploads/';//配置文件上传的根目录
$upload->exts = array('jpg', 'gif', 'png', 'jpeg');//配置上传文件的格式
$info = $upload->uploadOne($img);//调用TP单个文件上传方法
if (!$info) {//判断文件是否上传成功
$this->error($upload->getError());
return;
}
//将成功上传的文件的路径保存到$path中并返回
$path = $info['savepath'] . $info['savename'];
return $path;
}
上面两份就是上传页面和相关的PHP代码,主要从PHP代码中分析,HTML没什么难度和重点。
第一步:看index()函数命名,函数的命名直接关系到页面的调用,所以函数命名和HTML页面命必须相同,调用页面的代码:$this->display();还有另外一种情况(我没有试过 只是感觉),如果函数命名和HTML页面命不相同,可以在$this->display()中输入正确页面的路径
第二步:上面代码都有注释,就不多解释了,D是使用数据表,add是往数据表中添加数据。$this->upload($_FILES['img']),这行代码可以在upload()获取
第二个页面:照片的列表
HTML页面,路径:Application\Home\View\Index\lst.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h3 style="text-align: center;">商品列表</h3>
<table border='2' style="width:400px;height: 130px;border-collapse: collapse;margin:0px auto;text-align: center;">
<tr>
<td>商品ID</td>
<td>商品名</td>
<td>商品展示图</td>
<td>相关操作</td>
</tr>
<foreach name="infos" item="row">
<tr>
<td>{$row['gid']}</td>
<td>{$row['gname']}</td>
<td><img width="100" src="__PUBLIC__/Uploads/{$row['imgpath']}" /></td>
<!--注意 修改链接要将商品id一并写入-->
<td><a href="__CONTROLLER__/revise/gid/{$row['gid']}">修改</a> <a href="__CONTROLLER__/index">返回继续添加</a></td>
</tr>
</foreach>
</table>
</body>
</html>
PHP代码
public function lst() {
//实例化ginfo表模型类并调用select方法获取所有商品数据
$infos = D('ginfo')->select();
//为视图文件分配变量数据
$this->assign('infos', $infos);
//调用视图页面
$this->display();
}
在这两份文件中主要点是foreach中的infos名称,在lst()中 D('ginfo')->select()是从数据库中获取所有照片数并按数组赋给$infos ,然后通过$this->assign('infos', $infos)再传递给HTML页面循环排列出来,排列的特点是每一行的键就是数据表名。
第三个页面:修改页面
HTML页面,路径:Application\Home\View\Index\revise.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="__CONTROLLER__/update" method="post" enctype="multipart/form-data">
<table style="width:480px;height: 130px;border-collapse: collapse;margin: 20px auto;">
<tr>
<td><input hidden="text" name="gid" value="{$info['gid']}" /></td>
</tr>
<tr>
<td>商品名:</td>
<td><input type="text" name="gname" value="{$info['gname']}"/></td>
</tr>
<tr>
<td>修改图片:</td>
<td><img width="100" src="__PUBLIC__/Uploads/{$info['imgpath']}" /><input type="file" name="img" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="提交" /> <a href="__CONTROLLER__/lst">返回列表</a></td>
</tr>
</table>
</form>
</body>
</html>
PHP代码
public function revise() {
$gid = $_GET['gid'];//获取商品id
$info = D('ginfo')->where("gid=$gid")->find();//根据商品id获取商品详细信息
$this->assign('info', $info);//自:使用 assign 方法对模板变量进行赋值;所以assign('wish',$wish)中第一个参数‘wish’表示在模版取值用的变量名,第二个参数是wish变量的值
$this->display();
}
public function update() {
if ($_FILES['img']['size']) {//判断是否上传了图片,是则执行上传操作,不是则跳过
$data['imgpath'] = $this->upload($_FILES['img']);
}
//将更新数据以数组的形式保存到$data中
$data['gname'] = $_POST['gname'];
//将更新条件以数组形式保存到$where中
$where['gid'] = $_POST['gid'];
//实例化ginfo模型类并执行save操作
$res = D('ginfo')->where($where)->save($data);//调用TP的save方法更新数据时,如果新数据与数据库中得数据一致,那么执行M('table')->save(data)方法时,该方法会返回false。
if ($res) {//判断更新操作是否成功,是则跳转到商品列表页面
$this->success('修改成功,请稍等...', U('lst'));
return;
}
$this->error();
}
再修改页面其实并没有什么特殊的,主要是把要修改照片的ID传递过来(http://localhost:8080/ThinkPHP_3.2.2_full/index.php/Home/Index/revise/gid/7)id名为gid,值为7。然后在recvse()接收id值就没问题了。还有一个注意点就是在HTML中from的action值,会PHP应该都能懂。
最后附上一份我也不太懂的代码
public function _before_update() {
if ($_FILES['img']['size']) {//判断是否选择了新的图片,是则根据商品id获取原图地址,执行unlink函数销毁原图,不是则直接跳过
$where['gid'] = $_GET['gid'];
$imgpath = D('ginfo')->where($where)->getField('imgpath');
if ($imgpath) {
$imgurl = './Public/Uploads/' . $imgpath;
$res = unlink($imgurl);
if (!$res) {
$this->error('删除原图失败');
}
}
}
}
应该是在修改照片之前进行判断(_before_可能代表默认调用)
运行测试。http://localhost/项目名称/index.php/Home/Index/Index
如果了解更深刻的欢迎留言讨论