一、mysql添加索引的操做php
1.PRIMARY KEY(主键索引)
mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
2.UNIQUE(惟一索引)
mysql>ALTER TABLE `table_name` ADD UNIQUE (
`column` )
3.INDEX(普通索引)
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
4.FULLTEXT(全文索引)
mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
5.多列索引
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )html
二、excel数据的导入和导出mysql
最近的工做中涉及到了数据库数据导入Excel,和Excel数据导出。磕磕绊绊总算搞定了,在这里总结一下:jquery
(一)数据导入Excel,文件保存至本地laravel
废话很少说 直接上代码web
/** * @param $rst 参数为数据数组 * @return bool|string * 将sql执行结果写入excel并保存 */ public function SaveExcel($rst) {$head_field = array_keys($rst[0]); //第一行的标题 require_once __DIR__.'/../Common/PHPExcel/PHPExcel.php'; require_once __DIR__.'/../Common/PHPExcel/PHPExcel/Writer/Excel2007.php'; require_once __DIR__.'/../Common/PHPExcel/PHPExcel/Writer/Excel5.php'; include_once __DIR__.'/../Common/PHPExcel/PHPExcel/IOFactory.php'; //建立新的PHPExcel对象 $objPHPExcel = new \PHPExcel(); $fileName = date('Y-m-d H:i:s',time()).".xls"; //设置表头 $key = ord("A"); foreach($head_field as $v){ $colum = chr($key); $objPHPExcel->setActiveSheetIndex(0) ->setCellValue($colum.'1', $v); $key += 1; } $column = 2; $objActSheet = $objPHPExcel->getActiveSheet(); foreach($rst as $key => $rows){ //行写入 $span = ord("A"); foreach($rows as $keyName=>$value){// 列写入 $j = chr($span); $objActSheet->setCellValue($j.$column, $value); $span++; } $column++; } $fileName = iconv("utf-8", "gb2312", $fileName); //重命名表 $objPHPExcel->getActiveSheet()->setTitle('Simple'); $objPHPExcel->setActiveSheetIndex(0); $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); if (!is_dir(Config::get('excel_path'))) { mkdir(Config::get('excel_path'), 0755, true); } $path = Config::get('excel_path') .'/'. $fileName; $objWriter->save($path); if(file_exists($path)){ return $path; }else{ return false; } }
遇到问题:当数据字段超过26列的时候报错 Invalid cell coordinate [1面试
缘由是Excel文件的列在Z以后是AA、AB......AZ、BA...ajax
修改代码以下:sql
/** * @param $rst * @param $name * @return bool|string * 将sql执行结果写入excel并保存 */ public function SaveExcel($rst) { Logger::write('进入下载方法'); $head_field = array_keys($rst[0]); require_once __DIR__.'/../Common/PHPExcel/PHPExcel.php'; require_once __DIR__.'/../Common/PHPExcel/PHPExcel/Writer/Excel2007.php'; require_once __DIR__.'/../Common/PHPExcel/PHPExcel/Writer/Excel5.php'; include_once __DIR__.'/../Common/PHPExcel/PHPExcel/IOFactory.php'; //建立新的PHPExcel对象 $objPHPExcel = new \PHPExcel(); $fileName = date('Y-m-d H:i:s',time()).".xls"; //设置表头 $key = ord("A"); $key2 = ord("@"); foreach($head_field as $v){ if($key>ord("Z")){ $key2 += 1; $key = ord("A"); $colum = chr($key2).chr($key); }else{ if($key2>=ord("A")){ $colum = chr($key2).chr($key); }else{ $colum = chr($key); } } $objPHPExcel->setActiveSheetIndex(0) ->setCellValue($colum.'1', $v); $key += 1; } $column = 2; $objActSheet = $objPHPExcel->getActiveSheet(); foreach($rst as $key => $rows){ //行写入 $span = ord("A"); $span2 = ord("@"); foreach($rows as $keyName=>$value){// 列写入 if($span>ord("Z")){ $span2 += 1; $span = ord("A"); $j = chr($span2).chr($span); }else{ if($span2>=ord("A")){ $j = chr($span2).chr($span); }else{ $j = chr($span); } } $objActSheet->setCellValue($j.$column, $value); $span++; } $column++; } $fileName = iconv("utf-8", "gb2312", $fileName); //重命名表 $objPHPExcel->getActiveSheet()->setTitle('Simple'); $objPHPExcel->setActiveSheetIndex(0); $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); if (!is_dir(Config::get('excel_path'))) { mkdir(Config::get('excel_path'), 0755, true); } $path = Config::get('excel_path') .'/'. $fileName; $objWriter->save($path); if(file_exists($path)){ return $path; }else{ return false; } }
(二)Excel数据导出成数组shell
public function test() { //传入文档路径path require_once __DIR__.'/../../../vendor/PHPExcel/Classes/PHPExcel/IOFactory.php'; $reader = \PHPExcel_IOFactory::createReader('Excel2007'); // 读取 excel 文档 $PHPExcel = $reader->load( __DIR__.'/question.xlsx'); // 文档名称 $sheet = $PHPExcel->getSheet(0); // 读取第一个工做表(编号从 0 开始) $highestRow = $sheet->getHighestRow(); // 取得总行数 $highestColumn = $sheet->getHighestColumn(); // 取得总列数 $arr = array(0=>'A',1=>'A',2=>'B',3=>'C',4=>'D',5=>'E',6=>'F',7=>'G',8=>'H',9=>'I',10=>'J',11=>'K',12=>'L',13=>'M', 14=>'N',15=>'O',16=>'P',17=>'Q',18=>'R',19=>'S',20=>'T',21=>'U',22=>'V',23=>'W',24=>'X',25=>'Y',26=>'Z'); //echo $highestRow.$highestColumn; // 一次读取一列 $data = []; for ($row = 2; $row <= $highestRow; $row++) { for ($column = 0; $arr[$column] != $highestColumn; $column++) { $val = $sheet->getCellByColumnAndRow($column, $row)->getValue(); $data[$row-2][]= $val; } } return $data; }
过程当中遇到一个问题
$PHPExcel = $reader->load( __DIR__.'/question.xlsx');
代码走到这里的时候报错 超出内存,缘由大概是用到 PHPExcel_IOFactory::load() 时会 不停的向本页跳转
解决办法是:
在Load前面加一行代码以下
$objReader = PHPExcel_IOFactory::createReader('EXCEL2007' ); $objReader->setReadDataOnly (true ); $objPHPExcel = $objReader->load('./upfile/test.xlsx');
三、包含上传文件的form的ajax提交
当表单中包含上传文件的时候,使用jquery常规的$.post(‘url’,data,function(){})不能提交上传文件;
此时须要使用FormData对象
$('#addfrome').on('click',function () { var formData = new FormData($('form')[1]); $.ajax({ url:"{:url('addFromE')}", type:'post', data:formData, processData: false, contentType: false, success:function(data){ dcument.write(data); } }); });
四、php中Curl方法传递多维数组的问题(附:curl封装方法)
最近在使用curl方法的时候遇到一个问题,curl的post方法传递的参数默认是觉得数组
当传递二维(多维)数组的时候会报一个notce,以下图
解决办法是php函数 http_build_query()函数
并且貌似这个函数最多只支持三维数组
附:curl请求封装方法
/** * curl发送htpp请求 * 能够发送https,http,get方式,post方式,post数据发送 */ function dataRequest($url,$https=true,$method='get',$data=null) { //初始化curl $ch = curl_init($url); //字符串不直接输出,进行一个变量的存储 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //https请求 if ($https === true) { //确保https请求可以请求成功 curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); } //post请求 if ($method == 'post') { curl_setopt($ch,CURLOPT_POST,true); curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query($data)); } //发送请求 $str = curl_exec($ch); $aStatus = curl_getinfo($ch); //关闭链接 curl_close($ch); if(intval($aStatus["http_code"])==200){ return json_decode($str,true); }else{ return false; } }
五、一款好用的模板引擎-think-angular
连接地址:https://www.kancloud.cn/shuai/php-angular/127397
六、常见的几种web攻击及防护----php篇
1、sql注入攻击
攻击者把SQL命令插入到Web表单的输入域或页面请求的字符串,欺骗服务器执行恶意的SQL命令。
例:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1';
防范方法:
1.检查变量数据类型和格式
2.过滤特殊符号
3.绑定变量,使用预处理语句
2、跨网站脚本攻击(Cross Site Scripting,XSS)
攻击者将恶意代码注入到网页上,其余用户在加载网页时就会执行代码,攻击者可能获得包括但不限于更高的权限
例:http://localhost/test.php?name=<script>alert(123456)</script>
防范方法:使用htmlspecialchars函数将特殊字符转换成HTML编码,过滤输出的变量
3、跨网站请求伪造攻击(Cross Site Request Forgeries,CSRF)
攻击者伪造目标用户的HTTP请求,而后此请求发送到有CSRF漏洞的网站,网站执行此请求后,引起跨站请求伪造攻击。
例:某个购物网站购买商品时,采用http://www.shop.com/buy.php?item=watch&num=100,item参数肯定要购买什么物品,num参数肯定要购买数量,若是攻击者以隐藏的方式发送给目标用户连接
,那么若是目标用户不当心访问之后,购买的数量就成了100个
防范方法:
一、检查网页的来源
二、检查内置的隐藏变量
三、使用POST,不要使用GET,处理变量也不要直接使用$_REQUEST
4、Session固定攻击(Session Fixation)
攻击者预先设定session id,让合法用户使用这个session id来访问被攻击的应用程序,一旦用户的会话ID被成功固定,攻击者就能够经过此session id来冒充用户访问应用程序。
防范方法:
1.按期更改session id 2.更改session的名称 3.关闭透明化session id 4.只从cookie检查session id 5.使用URL传递隐藏参数
5、Session劫持攻击(Session Hijacking)
攻击者利用各类手段来获取目标用户的session id。一旦获取到session id,那么攻击者能够利用目标用户的身份来登陆网站,获取目标用户的操做权限。
防范方法:
1.按期更改session id
2.更改session的名称
3.关闭透明化session id
4.设置HttpOnly。经过设置Cookie的HttpOnly为true,能够防止客户端脚本访问这个Cookie,从而有效的防止XSS攻击。
6、文件上传漏洞攻击(File Upload Attack)
攻击者利用程序缺陷绕过系统对文件的验证与处理策略将恶意代码上传到服务器并得到执行服务器端命令的能力
防范方法:
1.文件上传的目录设置为不可执行;
2.判断文件类型,设置白名单。对于图片的处理,可使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码;
3.使用随机数改写文件名和文件路径:一个是上传后没法访问;再来就是像shell、.php 、.rar和crossdomain.xml这种文件,都将由于重命名而没法攻击;
4.单独设置文件服务器的域名:因为浏览器同源策略的关系,一系列客户端攻击将失效,好比上传crossdomain.xml、上传包含Javascript的XSS利用等问题将获得解决。
七、一个面试常问道的问题:session的工做原理
答:首先,因为浏览器和服务器采用的是http无状态协议的通信,为了保持客户端的状态,因此就使用session来达到这个目的。
其实,当客户端访问服务器时,服务器根据需求设置session,将会话信息保存在服务器上,同时将标示session的session_id经过COOKIE传递给客户端浏览器,要知道,这个session_id就是惟一的。
而后,客户端浏览器每次请求都会带上服务器为它生成的session_id,来获取服务器上与之对应的session数据的。
八、ThinkPHP5.0应用强制路由、行为、统一返回值格式
答:最近喜欢上了laravel的路由模式,发现tp5也有相似的操做。所以就动手作了一些改造,
一、强制路由模式
'url_route_on' => true,
'url_route_must' => true,
设置这两个参数即可实现tp强制路由,路由定义方式以下例:
//闭包
Route::get('/',function(){ return 'Hello,world!'; });
Route::get('/test','index/Test/test');
二、行为(Hook)
这个是tp5的一个扩展,我感受能够用来模拟中间件的做用,能够在路由里调用,实现权限验证等
具体见tp5手册
$result = Hook::exec('app\\index\\behavior\\CheckAuth','run',$params);
三、统一返回值格式
在作接口开发时,统一返回值格式颇有必要
简单的作法是写一个Result类,定义一个静态方法实现统一格式
/** * 统一格式返回 * @param $data * @param int $errorCode * @param string $message * @return array */ public static function format($data, int $errorCode=0, $message=''){ return [ 'data' => $data, 'errorCode' => $errorCode, 'message' => $message ]; }
默认是不能直接返回数组的,所以还须要对源代码中的Response.php作一下修改
/** * 处理数据 * @access protected * @param mixed $data 要处理的数据 * @return mixed */ protected function output($data) { //为统一数据返回格式,修改返回值格式 if(is_array($data)||is_object($data)){ return json_encode($data); }else{ return $data; } // return $data; }
返回值样式: