一、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; }
返回值樣式: