php随笔,持续更新

1、mysql添加索引的操作

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`  )

 

2、excel数据的导入和导出

最近的工作中涉及到了数据库数据导入Excel,和Excel数据导出。磕磕绊绊总算搞定了,在这里总结一下:

(一)数据导入Excel,文件保存至本地

   废话不多说 直接上代码

    /**
     * @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...

修改代码如下:

/**
     * @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数据导出成数组

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');

 

3、包含上传文件的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);
            }
        });
    });

 

4、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;
    }
}

 5、一款好用的模板引擎-think-angular

  链接地址:https://www.kancloud.cn/shuai/php-angular/127397

6、常见的几种web攻击及防御----php篇

  一、sql注入攻击
              攻击者把SQL命令插入到Web表单的输入域或页面请求的字符串,欺骗服务器执行恶意的SQL命令。

      例:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1';

    防范方法:
    1.检查变量数据类型和格式
    2.过滤特殊符号
    3.绑定变量,使用预处理语句

  二、跨网站脚本攻击(Cross Site Scripting,XSS)
    攻击者将恶意代码注入到网页上,其他用户在加载网页时就会执行代码,攻击者可能得到包括但不限于更高的权限

    例:http://localhost/test.php?name=<script>alert(123456)</script>

    防范方法:使用htmlspecialchars函数将特殊字符转换成HTML编码,过滤输出的变量

  三、跨网站请求伪造攻击(Cross Site Request Forgeries,CSRF)

    攻击者伪造目标用户的HTTP请求,然后此请求发送到有CSRF漏洞的网站,网站执行此请求后,引发跨站请求伪造攻击。

    例:某个购物网站购买商品时,采用http://www.shop.com/buy.php?item=watch&num=100,item参数确定要购买什么物品,num参数确定要购买数量,如果攻击者以隐藏的方式发送给目标用户链接
,那么如果目标用户不小心访问以后,购买的数量就成了100个

    防范方法:
    1、检查网页的来源
    2、检查内置的隐藏变量
    3、使用POST,不要使用GET,处理变量也不要直接使用$_REQUEST

  四、Session固定攻击(Session Fixation)

    攻击者预先设定session id,让合法用户使用这个session id来访问被攻击的应用程序,一旦用户的会话ID被成功固定,攻击者就可以通过此session id来冒充用户访问应用程序。

     防范方法:
    1.定期更改session id    2.更改session的名称   3.关闭透明化session id  4.只从cookie检查session id   5.使用URL传递隐藏参数

  五、Session劫持攻击(Session Hijacking)

    攻击者利用各种手段来获取目标用户的session id。一旦获取到session id,那么攻击者可以利用目标用户的身份来登录网站,获取目标用户的操作权限。

    防范方法:
    1.定期更改session id
    2.更改session的名称
    3.关闭透明化session id
    4.设置HttpOnly。通过设置Cookie的HttpOnly为true,可以防止客户端脚本访问这个Cookie,从而有效的防止XSS攻击。

  六、文件上传漏洞攻击(File Upload Attack)

  攻击者利用程序缺陷绕过系统对文件的验证与处理策略将恶意代码上传到服务器并获得执行服务器端命令的能力

  防范方法:

  1.文件上传的目录设置为不可执行;
  2.判断文件类型,设置白名单。对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码;
  3.使用随机数改写文件名和文件路径:一个是上传后无法访问;再来就是像shell、.php 、.rar和crossdomain.xml这种文件,都将因为重命名而无法攻击;
  4.单独设置文件服务器的域名:由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传crossdomain.xml、上传包含Javascript的XSS利用等问题将得到解决。

 

 

 7、一个面试常问道的问题:session的工作原理

答:首先,由于浏览器和服务器采用的是http无状态协议的通讯,为了保持客户端的状态,所以就使用session来达到这个目的。

   其实,当客户端访问服务器时,服务器根据需求设置session,将会话信息保存在服务器上,同时将标示session的session_id通过COOKIE传递给客户端浏览器,要知道,这个session_id就是唯一的。

然后,客户端浏览器每次请求都会带上服务器为它生成的session_id,来获取服务器上与之对应的session数据的。

 

 8、ThinkPHP5.0应用强制路由、行为、统一返回值格式

 

答:最近喜欢上了laravel的路由模式,发现tp5也有类似的操作。因此就动手做了一些改造,

  1、强制路由模式

   'url_route_on' => true,

  'url_route_must' => true,

   设置这两个参数便可实现tp强制路由,路由定义方式如下例:
  

//闭包
Route::get('/',function(){ return 'Hello,world!'; });

Route::get('/test','index/Test/test');

  2、行为(Hook)

  这个是tp5的一个扩展,我感觉可以用来模拟中间件的作用,可以在路由里调用,实现权限验证等

  具体见tp5手册

$result = Hook::exec('app\\index\\behavior\\CheckAuth','run',$params);

  3、统一返回值格式

  在做接口开发时,统一返回值格式很有必要

  简单的做法是写一个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;
    }

  返回值样式:

  

 

 

    

posted @ 2017-05-18 11:21  风中凌乱的猫  阅读(258)  评论(0编辑  收藏  举报