1.更改 Apache httpd.conf 配置文件
1.1、加载 mod_rewrite.so,确认加载了 mod_rewrite.so 模块(将如下配置前的 # 号去掉):
1.2、更改 AllowOverride 配置,如果tp3目录在www下的/tp3,直接在httpd.conf底部添加下面代码:
AllowOverride All
1.3、添加 .htaccess 文件(TP3主目录下就有,确保代码没错和在入口文件同级目录就ok)
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
2.更改TP3项目配置文件
2.1、编辑项目配置文件 Conf/config.php ,将 URL 模式配置为 2(Rewrite模式):
'URL_MODEL' => 2,
2.1、更改模块配置或者项目配置的config.php
'配置值'
'DB_TYPE' => 'oracle', // 数据库类型
'DB_USER' => 'user', // 用户名
'DB_PWD' => 'pwd', // 密码
'DB_PREFIX' => '', // 数据库表前缀
'DB_DSN' => 'oci:host=127.0.0.1;dbname=TestOrcl;charset=utf8'
);
2.2、实际使用,详细查看TP3.2.3开发手册
// 实例化Member对象
$db = M('Member');
//数据更新
// 方法1:
// $db->realname = 'ThinkPHP2';
// $count = $db->where('id=1')->save();
// 方法2:
// $data['realname']='ThinkPhP';
// $count=$db->where('id=1')->save($data);
// if($count==1){
// echo '';
// }
// 写入
//下一个自增ID
// $id = $db->getNextInsID('member_seq');
// $data['id'] = $id;//字段必须要小写,不然会忽略掉
// $data['loginname'] = '13800138000';
// $data['realname'] = 'tp3';
// $data['password'] = '123456';
// $count = $db->add($data);
//
// $str="alert('add ".($count?"sussecc!":"fail!")."')";
// echo '';
// 删除
// $count=$db->where('id>=865 and id<=902')->delete();
// $str="alert('del ".($count?"sussecc!":"fail!")."')";
// echo '';
// 查询
$result = $db->field('id,LoginName,RealName,to_char(LASTACTTIME, \'YYYY-MM-DD HH24:MI:SS\') as LASTACTTIME')->where('id<10')->order('id')->limit(10)->select();
dump($result);
//SQL查询
//$Model = new \Think\Model();
//$result=$Model->query("select * from member t1 left join zy t2 on t2.memberid=t1.id where t2.id is not null");
//dump($result);
/**
* TODO
* 2016-05-09 新增方法 修复bug 修复及支持获取自增Id的上次记录 by czw
* 取得Oracle最近插入的ID
* @access public
*/
public function getNextInsID($sequence = '') {
try {
$lastInsID = $this->_linkID->lastInsertId();
} catch(\PDOException $e) {
//对于驱动不支持PDO::lastInsertId()的情况
try {
$lastInsID = 0;
$seqPrefix = C("DB_SEQUENCE_PREFIX") ? C("DB_SEQUENCE_PREFIX") : 'seq_';
$seqSuffix = C("DB_SEQUENCE_SUFFIX") ? C("DB_SEQUENCE_SUFFIX") : '';
$sequence = strtoupper($sequence ? $sequence : $seqPrefix.$this->table.$seqSuffix);
$q = $this->query("SELECT {$sequence}.nextval as t FROM DUAL");
if($q) {
$lastInsID = $q[0]['t'];
}
} catch(\Exception $e) {
print "Error!: " . $e->getMessage() . "";
exit;
}
}
return $lastInsID;
}
2.4、把上述文件中的execute()方法中,查询sequence的代码和执行$this->PDOStatement->execute();失败后,获取主键字段自动调用获取自增的代码删除掉!多次测试发现在调试模式下,发起插入数据的操作时,缺少主键数据不会返回false从而执行后边的获取自增部分代码。直接报错,干脆剔掉吧。自己直接单独提前获取好主键自增ID后,再提交执行。
/**
* 执行语句
* @access public
* @param string $str sql指令
* @param boolean $fetchSql 不执行只是获取SQL
* @return integer
*/
public function execute($str,$fetchSql=false) {
$bind = $this->bind; //TODO 新增 修复bug 修复及支持获取自增Id的上次记录 by czw
$this->initConnect(true);
if ( !$this->_linkID ) return false;
$this->queryStr = $str;
if(!empty($this->bind)){
$that = $this;
$this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '\''.$that->escapeString($val).'\''; },$this->bind));
}
if($fetchSql){
return $this->queryStr;
}
//释放前次的查询结果
if ( !empty($this->PDOStatement) ) $this->free();
$this->executeTimes++;
N('db_write',1); // 兼容代码
// 记录开始执行时间
$this->debug(true);
$this->PDOStatement = $this->_linkID->prepare($str);
if(false === $this->PDOStatement) {
$this->error();
return false;
}
$this->bind = $this->bind ? $this->bind : $bind;//TODO 新增 修复bug 修复及支持获取自增Id的上次记录 by czw
foreach ($this->bind as $key => $val) {
if(is_array($val)){
$this->PDOStatement->bindValue($key, $val[0], $val[1]);
}else{
$this->PDOStatement->bindValue($key, $val);
}
}
$this->bind = array();
$result = $this->PDOStatement->execute();
$this->debug(false);
if ( false === $result) {
$this->error();
}
return $result;
}
2.5、把ThinkPHP/Library/Think/Model.class.php文件中的getLastInsID()方法改成:
/**
* 返回最后插入的ID
* @access public
* @return string
*/
public function getNextInsID($sequence) {
return $this->db->getNextInsID($sequence);
}
以后直接可以通过下面方法获取下一自增ID
$id = $db->getNextInsID('member_seq');
public function checkRootPath($rootpath){
if(!(is_dir('./') && is_writable('./'))){
$this->error = '上传根目录不存在!请尝试手动创建:'.$rootpath;
return false;
}
$this->rootPath = $rootpath;
return true;
}
$upload = new \Think\Upload();// 实例化上传类
$upload->maxSize = 1 * 1024 * 1024;// 设置附件上传大小,1024*1024为1MB
$upload->exts = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
$upload->rootPath = 'Public/'; // 设置附件上传根目录
$upload->savePath = 'Uploads/'; // 设置附件上传(子)目录
//是否使用子目录保存上传文件
$upload->autoSub = true;
// 采用date函数生成命名规则 传入Y-m-d参数
$upload->saveName = array('udate',array('YmdHisu'));
// 上传文件
$info = $upload->upload();
$data = null;
if (!$info) {// 上传错误提示错误信息
$data = [
'Status' => 'Err',
'Content' => $upload->getError()
];
} else {// 上传成功
$data = [
'Status' => 'OK',
'Content' => '上传成功'
];
}
print_r(json_encode($data));
$upload->saveName = array('udate',array('YmdHisu'));
在\tp3\ThinkPHP\Common\functions.php文件下新建一个可以获取毫秒级时间的字符串方法,用作命名上传文件。
/**
* 获取毫秒级的时间字符串
* @param string $format 日期格式:默认u只返回毫秒,‘Y-m-d H:i:s.u’详细
* @return string
*/
function udate($format = 'u', $utimestamp = null) {
if (is_null($utimestamp))
$utimestamp = microtime(true);
$timestamp = floor($utimestamp);
$milliseconds = round(($utimestamp - $timestamp) * 1000000);
return date(preg_replace('`(?
php图片上传测试
public function checkRootPath($rootpath){
if(!(is_dir('./') && is_writable('./'))){
$this->error = '上传根目录不存在!请尝试手动创建:'.$rootpath;
return false;
}
$this->rootPath = $rootpath;
return true;
}
$config = array(
'maxSize' => 1 * 1024 * 1024, // 设置附件上传大小,1024*1024为1MB
'rootPath' => 'Public/', // 设置附件上传根目录
'savePath' => 'Uploads/', // 设置附件上传(子)目录
//'saveName' => array('uniqid',''), //默认采用uniqid函数生成一个唯一的字符串序列。
'saveName' => array('udate', array('YmdHisu')), // 采用自定义udate函数生成命名规则 传入YmdHisu参数
'exts' => array('jpg', 'gif', 'png', 'jpeg'),// 设置附件上传类型
'autoSub' => true, //是否使用子目录保存上传文件
'subName' => array('date','Ymd'), //子目录命名规则
//'subName' => 'get_user_id', //可以使用自定义函数来保存,和saveName参数一样
);
$upload = new \Think\Upload($config); // 实例化上传类
// 上传所有文件
//$info = $upload->upload();
// 上传单个文件,current($_FILES)获取$_FILES数组第一个值
$info = $upload->uploadOne(current($_FILES));
$data = null;
if (!$info) {// 上传错误提示错误信息
$data = [
'Status' => 'Err',
'Content' => $upload->getError()
];
} else {// 上传成功
$data = [
'Status' => 'OK',
'Content' => '上传成功'
];
}
print_r(json_encode($data));
在\tp3\ThinkPHP\Common\functions.php文件下新建一个可以获取毫秒级时间的字符串方法,用作命名上传文件。
/**
* 获取毫秒级的时间字符串
* @param string $format 日期格式:默认u只返回毫秒,‘Y-m-d H:i:s.u’详细
* @return string
*/
function udate($format = 'u', $utimestamp = null) {
if (is_null($utimestamp))
$utimestamp = microtime(true);
$timestamp = floor($utimestamp);
$milliseconds = round(($utimestamp - $timestamp) * 1000000);
return date(preg_replace('`(?
php图片上传测试
要使用命名范围功能,主要涉及到模型类的_scope
属性定义和scope
连贯操作方法的使用。
Home模块Model下新建模型类MemberModel.class.php(文件名,注意不能少了.class)
protected $_scope = array(
// 命名范围normal
'normal' => array(
'where' => array('State' => 1)
),
// 命名范围latest
'latest' => array(
'order' => 'LastActTime DESC',
'limit' => 10
)
);
调用:
$Model = D('Member');// 这里必须使用D方法 因为命名范围在模型里面定义
$result = $Model->scope('normal,latest')->select();
dump($result);
5.1、ThinkPHP的字段映射功能可以让你在表单中隐藏真正的数据表字段,而不用担心放弃自动创建表单对象的功能,假设我们的User表里面有username和email字段,我们需要映射成另外的字段,定义方式如下:
'loginname',// 把表单中mobile映射到数据表的loginname字段
'name' =>'realname'
);
'READ_DATA_MAP'=>true, //读取数据根据模型字段映射返回
1、下载地址:http://phpexcel.codeplex.com/ ps:当前使用thinkphp3.2.3,请下载1.7.9版本。亲测1.8.0版本在TP3.23下,调用报....PHPEXCEL not found...,本人初学愚钝据网上各种方法进行N次处理还是解决不了。后来降到1.79后,一切顺利
2、把下载文件中的PHPExcel目录和PHPExcel.php放到TP框架 \ThinkPHP\Library\Org\Util\下
3、因为PHPExcel没有用命名空间,只能inport导入
4、自己写的读取、导出excel通用方法,有详细注释。基本看懂了就够用了。也可以百度 ‘PHPExcel中文开发手册’,看下详细参数设置使用说明。
/**
* 导出正规数据excel表
* @param string $fileName 标题
* @param array $headArr 列头\字段\宽度和定义
* $headArr = array(
* 'id' => ['text' => '用户ID', 'width' => 10],
* 'name' => ['text' => '用户名字', 'width' => 20]
* );
* @param array $data 数据源
* @return boolean
*/
function getExcel($fileName, $headArr, $data)
{
//对数据进行检验
if (empty($data) || !is_array($data)) {
die("数据源错误");
}
//检查文件名
if (empty($fileName)) {
exit;
}
//导入PHPExcel类库,因为PHPExcel没有用命名空间,只能inport导入
import("Org.Util.PHPExcel");
import("Org.Util.PHPExcel.Writer.Excel5");
import("Org.Util.PHPExcel.IOFactory.php");
//创建PHPExcel对象,注意,不能少了\
$objPHPExcel = new \PHPExcel();
$objProps = $objPHPExcel->getProperties();
$objProps->setCreator('Nicky');//创建人
$objProps->setLastModifiedBy('Nicky');//最后修改人
$objPHPExcel->setActiveSheetIndex(0);//设置当前的sheet
$objActSheet = $objPHPExcel->getActiveSheet(); //获取当前sheet
$objActSheet->setTitle($fileName); //当值sheet标题
//边框样式
$styleArray = array(
'borders' => array(
'allborders' => array(
//'style' => PHPExcel_Style_Border::BORDER_THICK,//边框是粗的
'style' => \PHPExcel_Style_Border::BORDER_THIN,//细边框
//'color' => array('argb' => 'FFFF0000'),
),
),
);
//所有单元格水平居中、垂直居中
$objPHPExcel->getDefaultStyle()->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
$objPHPExcel->getDefaultStyle()->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
//所有单元格行高
$objActSheet->getDefaultRowDimension()->setRowHeight(20);
//字体
$objPHPExcel->getDefaultStyle()->getFont()->setName('宋体');
//************************** 设置列头标题 ***********************
$key = ord("A");
foreach ($headArr as $v) {
$colum = chr($key);
$objActSheet->setCellValue($colum . '2', $v['text']);
if (empty($v['width'])) {
$objActSheet->getColumnDimension($colum)->setAutoSize(true);
} else {
$objActSheet->getColumnDimension($colum)->setWidth($v['width']);
}
$key += 1;
}
//列数
$tmp = chr($key - 1);
//************************** end ***********************
//************************** 设置第一行大标题 ***********************
$objActSheet->setCellValue('A1', $fileName);
$objActSheet->getRowDimension('1')->setRowHeight(30);
$objActSheet->getStyle('A1')->getFont()->setSize(23);
$objActSheet->mergeCells('A1:' . $tmp . '1');//合并单元格
//************************** end ***********************
$column = 3;
//写入数据
foreach ($data as $key => $rows) {// 行写入
$span = ord("A");
foreach ($headArr as $k => $v) {
$j = chr($span);
$objActSheet->setCellValue($j . $column, $rows[$k]);
$span++;
}
$column++;
}
//设置列头填充颜色
$objActSheet->getStyle('A2:' . $tmp . '2')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID);
$objActSheet->getStyle('A2:' . $tmp . '2')->getFill()->getStartColor()->setARGB('FF1494DF');
//设置列头和标题字体加粗
$objActSheet->getStyle('A1:' . $tmp . '2')->getFont()->setBold(true);
//设置全局边框
$objActSheet->getStyle('A1:' . $tmp . ($column - 1))->applyFromArray($styleArray);//这里就是画出从单元格A5到N5的边框,看单元格最右边在哪哪个格就把这个N
$date = date("Y_m_d", time());
$fileName .= "_{$date}.xls";
$fileName = iconv("utf-8", "gb2312", $fileName);
ob_end_clean();//清除缓冲区,避免乱码
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition: attachment;filename=\"$fileName\"");
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
//header('Cache-Control: max-age=1');
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('php://output'); //文件通过浏览器下载
exit;
}
/**
* 读取Excel数据
* @param string $path 文件路径(ps:./Public/1.xls)
* @param int $beginRow 开始行数
* @return array $arr 读取出来的数据
*/
function readExcel($path, $beginRow = 1)
{
//导入PHPExcel类库,因为PHPExcel没有用命名空间,只能inport导入
import("Org.Util.PHPExcel");
//创建PHPExcel对象,注意,不能少了\
// $PHPExcel=new \PHPExcel();
//如果excel文件后缀名为.xls,导入这个类
import("Org.Util.PHPExcel.Reader.Excel5");
$PHPReader = new \PHPExcel_Reader_Excel5();
//如果excel文件后缀名为.xlsx,导入这下类
//import("Org.Util.PHPExcel.Reader.Excel2007");
//$PHPReader=new \PHPExcel_Reader_Excel2007();
//载入文件
$PHPExcel = $PHPReader->load($path);
//获取表中的第一个工作表,如果要获取第二个,把0改为1,依次类推
$currentSheet = $PHPExcel->getSheet(0);
//获取总列数
$allColumn = $currentSheet->getHighestColumn();
//获取总行数
$allRow = $currentSheet->getHighestRow();
//循环获取表中的数据,$currentRow表示当前行,从哪行开始读取数据,索引值从0开始
for ($currentRow = $beginRow; $currentRow <= $allRow; $currentRow++) {
//从哪列开始,A表示第一列
for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++) {
//数据坐标
$address = $currentColumn . $currentRow;
//读取到的数据,保存到数组$arr中
$arr[$currentRow - $beginRow][$currentColumn] = $currentSheet->getCell($address)->getValue();
}
}
return $arr;
}
return iconv('gbk','utf-8',$location['country'].$location['area']);;
//测试
public function test(){
$tmp=new \Org\Net\IpLocation();//导入IpLocation类
dump($tmp->getlocation('8.8.8.8'));
}
1.一个常用的通过cURL发送HTTP请求的函数,可以添加到Common/function.php里面
/**
* 发送HTTP请求方法
* @param string $url 请求URL
* @param array $params 请求参数
* @param string $method 请求方法GET/POST
* @param array $header
* @param bool $multi
* @return array $data 响应数据
* @throws Exception
*/
function http($url, $params, $method = 'GET', $header = array(), $multi = false){
$opts = array(
CURLOPT_TIMEOUT => 30,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
// CURLOPT_DNS_USE_GLOBAL_CACHE => false,
// CURLOPT_DNS_CACHE_TIMEOUT => 2,
CURLOPT_HTTPHEADER => $header
);
/* 根据请求类型设置特定参数 */
switch(strtoupper($method)){
case 'GET':
$opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
break;
case 'POST':
//判断是否传输文件
$params = $multi ? $params : http_build_query($params);
$opts[CURLOPT_URL] = $url;
$opts[CURLOPT_POST] = 1;
$opts[CURLOPT_POSTFIELDS] = $params;
break;
default:
throw new Exception('不支持的请求方式!');
}
/* 初始化并执行curl请求 */
$ch = curl_init();
curl_setopt_array($ch, $opts);
$data = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if($error) throw new Exception('请求发生错误:' . $error);
return $data;
}
3.检查php.ini的extension_dir值是哪个目录,检查有无php_curl.dll,没有的请下载php_curl.dll
4.重启下 apache
5.实例
//测试发送http请求
//定义一个要发送的目标URL;
$url = "http://www.xxx.com";
//定义传递的参数数组;
$data['aaa'] = 'aaaaa';
$data['bbb'] = 'bbbb';
//定义返回值接收变量;
$httpstr = http($url, $data, 'POST', array("Content-type: text/html; charset=utf-8"));
dump($httpstr);