前面写过一篇PHP读取EXCEL插入Mysql数据库中,应用phpExcelReader导入, 这次做毕业设计时用的ThinkPHP,有个上传学生信息(excel)插入数据库的功能,其实原理一样,先是上传,然后读取内容,然后根据phpExcelReader的read读取各sheet值然后插入数据库。其代码为:
import.html
1
2
3
4
5
6
7
| <form method="post" action="__URL__/import" name="form1" enctype="multipart/form-data">
<table cellspacing="0" cellpadding="0" border="1">
<tr>
<td ><input type="file" name="myfile" /> <input type="submit" class="mybutton" name="import" value="导入" ></td>
</tr>
</table>
</form> |
StudentsAction.class.php
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
| class StudentsAction extends Action
{
public function import()
{
header("Content-Type:text/html; charset=utf-8");
Vendor('Excel.reader'); // 加载reader类。
if(!$this->isPost())
{
$this->display();
}
else
{
if($_FILES['myfile']['name']!='')
{
$tmp_file=$_FILES['myfile']['tmp_name'];
$file_types=explode(".",$_FILES['myfile']['name']);
$file_type=$file_types[count($file_types)-1];
if(strtolower($file_type)!="xls"){
// echo "<span style=\"color:red;line-height: 25px;\">格式错误 <a href=\"#\" onclick=history.go(-1);>请返回</a> </span>";
$this->assign('jumpUrl',__URL__/import);
$msg="格式错误,请重新上传";
$this->success($msg);
}
$savePath="Excel/xls/";
$str = date('Ymdhis');
$file_name=$str.".".$file_type;
if(!copy($tmp_file,$savePath.$file_name)){
//echo "<span style=\"color:red;line-height: 25px;\">上传错误请重试!!<a href=# onclick=history.go(-1);>[返回]</a></span>";
$this->assign('jumpUrl',__URL__/import);
$msg="上传错误,请重新上传";
$this->success($msg);
}else{
$data = new Spreadsheet_Excel_Reader();
$data->setOutputEncoding('utf-8');
$data->read("Excel/xls/".$file_name);
for ($i = 2; $i <= $data->sheets[0]['numRows']; $i++) {
$number=$data->sheets[0]['cells'][$i][1]; $passwd=$data->sheets[0]['cells'][$i][1]; $name=$data->sheets[0]['cells'][$i][2];
$catid=$data->sheets[0]['cells'][$i][3];
$sex=$data->sheets[0]['cells'][$i][4];
$tel=$data->sheets[0]['cells'][$i][5];
$home=$data->sheets[0]['cells'][$i][6];
$minzu=$data->sheets[0]['cells'][$i][7];
$Students=D("Students");
$info=array(
'number'=>$number,
'passwd'=>$passwd,
'name'=>$name,
'catid'=>$catid,
'sex'=>$sex,
'tel'=>$tel,
'home'=>$home,
'minzu'=>$minzu,
);
$Students->create($info);
$Students->add();
}
$this->assign('jumpUrl',__URL__);
$msg="学生信息导入成功";
$this->success($msg);
}
}
}
}
} |
我们知道,ThinkPHP的模型有自动验证和自动完成功能,但是通常我们需要在模型类里面定义验证因子和完成因子。这样的话,我们使用M方法实例化模型的时候就不能使用内置的自动完成和自动验证功能了,其实仍然有办法的,因为TP提供了一个强大的属性动态更改的方法setProperty。利用该方法就完全可以用M方法实现自动验证功能了,例如:
$User = M(‘User’);
$auto = array (
array(‘status’,’1′), // 新增的时候把status 字段设置为 1
array(‘password’,'md5′,1,’function’) // 对 password 字段在新增的时候使md5 函数处理
array(‘name’,'getName’,1,’callback’) // 对 name 字段在新增的时候回调 getName 方法
array(‘create_time’,'time’,2,’function’), // 对 create_time 字段在更新的时候写入当前时间戳
);
$validate = array(
array(‘verify’,'require’,'验证码必须!’), //默认情况下用正则进行验证
array(‘repassword’,'password’,'确认密码不正确’,0,’confirm’), // 验证确认密码是否和密码一致
array(‘password’,'checkPwd’,'密码格式不正确’,0,’function’), // 自定义函数验证密码格式
);
$User->setProperty(‘_auto’,$auto);
$User->setProperty(‘_validate’,$validate);
if($User->create()){
$User->add();
}else{
$this->error($User->getError());
}
完成自动验证和自动完成只是setProperty方法的一个小技巧而已,更强大的功能还需要你去发挥了。
页面Trace 功能是ThinkPHP 的一个用于开发调试的辅助手段。可以实时显示当前页面的操作的请求信息、运行情况、SQL 执行、错误提示等,启用调试模式的话,页面 Trace 功能会默认开启(除非在项目的调试配置文件中关闭),并且系统默认的Trace 信息包括:当前页面、请求方法、通信协议、请求时间、用户代理、会话 ID、运行情况、SQL 记录、错误记录和文件加载情况。
如果需要扩展自己的Trace 信息,有下面几种方式:
第一种方式:在当前项目的配置目录下面定义 trace.php 文件,返回数组方式的定义,例如:
return array(
'当前页面'=>$_SERVER['PHP_SELF'],
'通信协议'=>$_SERVER['SERVER_PROTOCOL'],...
);
在显示页面Trace 信息的时候会把这个部分定义的信息追加到系统默认的信息之后,这种方式通常用于 Trace 项目的公共信息。
第二种方式:在 Action 方法里面使用 trace 方法来增加 Trace 信息,该部分可以用于系统的开发阶段调试。例如:
$this>trace('执行时间',$runTime);
$this>trace('Name 的值',$name);
$this>trace('GET 变量',dump($_GET,false));
我们知道,ThinkPHP的模型有自动验证和自动完成功能,但是通常我们需要在模型类里面定义验证因子和完成因子。这样的话,我们使用M方法实例化模型的时候就不能使用内置的自动完成和自动验证功能了,其实仍然有办法的,因为TP提供了一个强大的属性动态更改的方法setProperty。利用该方法就完全可以用M方法实现自动验证功能了,
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| $User = M('User');
$auto = array (
array('status','1'), // 新增的时候把status 字段设置为 1
array('password','md5',1,'function') // 对 password 字段在新增的时候使md5 函数处理
array('name','getName',1,'callback') // 对 name 字段在新增的时候回调 getName 方法
array('create_time','time',2,’function’), // 对 create_time 字段在更新的时候写入当前时间戳
);
$validate = array(
array('verify','require','验证码必须!'), //默认情况下用正则进行验证
array('repassword','password','确认密码不正确',0,’confirm’), // 验证确认密码是否和密码一致
array('password','checkPwd','密码格式不正确',0,’function’), // 自定义函数验证密码格式
);
$User->setProperty('_auto',$auto);
$User->setProperty('_validate',$validate);
if($User->create()){
$User->add();
}else{
$this->error($User->getError());
} |
转自流年老大:
TP2.0 添加目录安全文件:
在有些服务器环境下面,是开启了apache的目录浏览权限的,这样就会导致用户可以通过URL访问到你的应用目录,查看到你有哪些模块和模板文件,显然对系统的安全性方面造成了一定的影响。
对于这样的情况,TP提供了一个目录安全文件写入的功能,能够在项目的编译过程自动生成各个目录的安全文件,避免直接访问目录。要开启这个功能,我们只需要在项目的入口文件里面添加下面的定义:
define(‘BUILD_DIR_SECURE’,true);
然后访问项目(必须在自动生成项目目录之前访问),这样就会自动给项目目录生成目录安全文件(默认会在相关的目录下面生成空白的index.htm 文件),并且可以自定义安全文件的文件名DIR_SECURE_FILENAME ,默认是 index.html,如果你想给你们的安全文件定义为 default.html 可以使用
define(‘DIR_SECURE_FILENAME’, ‘default.html’);
还可以支持多个安全文件写入,例如你想同时写入 index.html 和 default.html 两个文件,以满足不同
的服务器部署环境,可以这样定义:
define(‘DIR_SECURE_FILENAME’, ‘index.html,default.html’);
默认的安全文件只是写入一个空白字符串,如果需要写入其他内容,可以通过
DIR_SECURE_CONTENT 参数来指定,例如:
define(‘DIR_SECURE_CONTENT’, ‘deney Access!’);
PS:
1、如果在后期设置,需要删除Runtime目录 才能重新生成目录安全文件
2、确保相关目录的可写权限
TP提供了非常灵活的URL方式, 前面写过 U方法生成伪静态
与 空操作实现伪静态
本文介绍下 利用伪静态实现网站语言伪装:
TP里面有一个URL伪静态的功能,本来是用于把URL伪装成一个静态页面地址用于SEO优化,例如设置:
'URL_HTML_SUFFIX'=>'.html'
就可以实现
http://serverName/News.html
这样的URL,实际上就是和
具有同样的作用。
稍微改进下,其实这个功能还可以起到表面上伪装网站技术的作用,呵呵~
例如,想忽悠客户你什么语言都能开发,遇到需要.Net的客户我们改成
'URL_HTML_SUFFIX'=>'.aspx'
就可以把
伪装成
http://serverName/News.aspx
遇到要求Java的客户,我们可以改成
或者
'URL_HTML_SUFFIX'=>'.jsp'
当然,我们不能靠这个忽悠客户, 但是 是不是很好玩儿。 ^_^
ThinkPHP 提供了非常灵活的URL模式,可以自己定制URL,支持URL路由,非常方便.
再次介绍下利用U函数生成URL伪静态的功能。
首先, 在配置文件(config.php)里设置 URL_HTML_SUFFIX 设置静态后缀
例
1
2
3
4
5
6
7
| <?php
return array(
'URL_HTML_SUFFIX'=>'.shtml', //随意, 可设置其它的。
...
//其它配置信息
);
?> |
来砍下手册U方法的定义规则:
U方法的定义规则如下(方括号内参数根据实际应用决定):
U('[项目://][路由@][分组名-模块/]操作? 参数1=值1[&参数N=值N]')
或者用数组的方式传入参数
U('[项目://][路由@][分组名-模块/]操作',array('参数1'=>'值1' [,'参数N'=>'值N']))
如果不定义项目和模块的话 就表示当前项目和模块名称,下面是一些简单的例子:
U('Myapp://User/add') // 生成Myapp项目的User模块的add操作的URL地址
U('Blog/read?id=1') // 生成Blog模块的read操作 并且id为1的URL地址
U('Admin-User/select') // 生成Admin分组的User模块的select操作的URL地址
参数请确保使用 ?id=1&name=tp或者数组的方式来定义,虽然有些情况下
U('Blog/read/id/1')和U('Blog/read?id=1')的效果一样
但是在不同的URL设置情况下,会导致解析的错误。
根据项目的不同URL设置,同样的U方法调用可以智能地对应产生不同的URL地址效果,例如针对
U('Blog/read?id=1')这个定义为例。
如果当前URL设置为普通模式的话,最后生成的URL地址是:
http://<serverName>/index.php?m=Blog&a=read&id=1
如果当前URL设置为PATHINFO模式的话,同样的方法最后生成的URL地址是:
http://<serverName>/index.php/Blog/read/id/1
如果当前URL设置为REWRITE模式的话,同样的方法最后生成的URL地址是:
http://<serverName>/Blog/read/id/1
如果当前URL设置为REWRITE模式,并且设置了伪静态后缀为.html的话,同样的方法最后生成的URL地址是:
http://<serverName>/Blog/read/id/1.html
U方法还可以支持路由,如果我们定义了一个名称为View的路由,指向Blog模块的read操作
参数是id,那么U('View@?id=1')生成的URL地址是:
http://<serverName>/index.php/View/id/1
好,我们只需在模板文件里 用U函数 生成的链接 就直接加上设置的后缀了。
例:
tpl/default/news/ 下的index.html文件
1
| <a href="{:U("News/edit/id/$vo[id]")}">阅读</a> |
是不是很强大! ^_^
TP扩展函数 msubstr 截取字符串不能显示省略号的bug. 之前用设置$suffix=true了,可是还不能显示bug, 去论坛问了问,没人回答, 看了下源码。 修改了下.能正常显示省略号。
官方的源码:
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
| /**
+----------------------------------------------------------
* 字符串截取,支持中文和其他编码
+----------------------------------------------------------
* @static
* @access public
+----------------------------------------------------------
* @param string $str 需要转换的字符串
* @param string $start 开始位置
* @param string $length 截取长度
* @param string $charset 编码格式
* @param string $suffix 截断显示字符
+----------------------------------------------------------
* @return string
+----------------------------------------------------------
*/
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true)
{
if(function_exists("mb_substr"))
return mb_substr($str, $start, $length, $charset);
elseif(function_exists('iconv_substr')) {
return iconv_substr($str,$start,$length,$charset);
}
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = join("",array_slice($match[0], $start, $length));
if($suffix) return $slice."…";
return $slice;
} |
自己修改过的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true)
{
if(function_exists("mb_substr"))
{ if($suffix)
return mb_substr($str, $start, $length, $charset)."...";
else
return mb_substr($str, $start, $length, $charset);
}
elseif(function_exists('iconv_substr')) {
if($suffix)
return iconv_substr($str,$start,$length,$charset)."...";
else
return iconv_substr($str,$start,$length,$charset);
}
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
} |
官方的两个if 都成立就执行截取了, 没有$suffix 的事了。 汗.. *-*!
修改下,自己加上判断省略号。 OK。 ^_^
ThinkPHP提供了灵活的静态文件生成功能,可以在输出模板的同时生成需要的静态文件.
使用:
$this->buildHtml('静态文件', '静态路径','模板文件');
静态路径如果留空的话 默认保存在HTML_PATH(默认的HTML_PATH路径位于项目目录下面的Html目录,如果没有的话手动创建)定义的路径下面,,静态文件可以随意设置,也可以包括路径,如果不存在的路径系统会自动创建。
看下TP的buildhtml的源文件Action.class.php:
1
2
3
| protected function buildHtml($htmlfile='',$htmlpath='',$templateFile='',$charset='',$contentType='text/html') {
return $this->view->buildHtml($htmlfile,$htmlpath,$templateFile,$charset,$contentType);
} |
View.class.php类部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| +----------------------------------------------------------
* @access public
+----------------------------------------------------------
* @htmlfile 生成的静态文件名称
* @htmlpath 生成的静态文件路径
* @param string $templateFile 指定要调用的模板文件
* 默认为空 由系统自动定位模板文件
* @param string $charset 输出编码
* @param string $contentType 输出类型
+----------------------------------------------------------
* @return string
+----------------------------------------------------------
*/
public function buildHtml($htmlfile,$htmlpath='',$templateFile='',$charset='',$contentType='text/html') {
$content = $this->fetch($templateFile,$charset,$contentType);
$htmlpath = !empty($htmlpath)?$htmlpath:HTML_PATH;
$htmlfile = $htmlpath.$htmlfile.C('HTML_FILE_SUFFIX');
if(!is_dir(dirname($htmlfile)))
// 如果静态目录不存在 则创建
mk_dir(dirname($htmlfile));
if(false === file_put_contents($htmlfile,$content))
throw_exception(L('_CACHE_WRITE_ERROR_'));
return $content;
} |
fetch类部分:
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
| /**
+----------------------------------------------------------
* 加载模板和页面输出
+----------------------------------------------------------
* @access public
+----------------------------------------------------------
* @param string $templateFile 模板文件名 留空为自动获取
* @param string $charset 模板输出字符集
* @param string $contentType 输出类型
* @param string $display 是否直接显示
+----------------------------------------------------------
* @return mixed
+----------------------------------------------------------
*/
public function fetch($templateFile='',$charset='',$contentType='text/html',$display=false)
{
$GLOBALS['_viewStartTime'] = microtime(TRUE);
if(null===$templateFile)
// 使用null参数作为模版名直接返回不做任何输出
return ;
if(empty($charset)) $charset = C('DEFAULT_CHARSET');
// 网页字符编码
header("Content-Type:".$contentType."; charset=".$charset);
header("Cache-control: private"); //支持页面回跳
//页面缓存
ob_start();
ob_implicit_flush(0);
if(!file_exists_case($templateFile))
// 自动定位模板文件
$templateFile = $this->parseTemplateFile($templateFile);
$engine = strtolower(C('TMPL_ENGINE_TYPE'));
if('php'==$engine) {
// 模板阵列变量分解成为独立变量
extract($this->tVar, EXTR_OVERWRITE);
// 直接载入PHP模板
include $templateFile;
}elseif('think'==$engine && $this->checkCache($templateFile)) {
// 如果是Think模板引擎并且缓存有效 分解变量并载入模板缓存
extract($this->tVar, EXTR_OVERWRITE);
//载入模版缓存文件
include C('CACHE_PATH').md5($templateFile).C('TMPL_CACHFILE_SUFFIX');
}else{
// 模板文件需要重新编译 支持第三方模板引擎
// 调用模板引擎解析和输出
$className = 'Template'.ucwords($engine);
require_cache(THINK_PATH.'/Lib/Think/Util/Template/'.$className.'.class.php');
$tpl = new $className;
$tpl->fetch($templateFile,$this->tVar,$charset);
}
$this->templateFile = $templateFile;
// 获取并清空缓存
$content = ob_get_clean();
// 模板内容替换
$content = $this->templateContentReplace($content);
// 布局模板解析
$content = $this->layout($content,$charset,$contentType);
// 输出模板文件
return $this->output($content,$display);
} |
考虑的很全面.
TP很适合我这种懒人用。 ^_^
首先看一下ThinkPHP的控制器
ThinkPHP采用模块和操作的方式来执行
http://servername/appName/moduleName/actionName/params
执行的项目(appName)、模块(moduleName)和操作(actionName),appName可以不需要,通常是网站的首页,因为项目名称可以在入口文件中指定,这种情况下,appName就会被index.php替代 ,而ThinkPHP提供的URL_MODEL 的2模式 URL重写,可以去掉index.php,让你的URL看上去更友好。
阅读全文…
Recent Comments