分类目录归档:PHP

PHP技术相关

PHP使用curl抓取https页面报cURL error 60: SSL certificate

最近项目里用laravel 安装了PHP的爬虫库 Goutte 抓取网页,修改内容
抓取https的时候遇到 cURL error 60: SSL certificate

下面直接说办法了
主要针对 开发环境遇到这个情况。
window + php7 + phpstudy

下载最新的根证书文件:https://curl.haxx.se/ca/cacert.pem
下载到phpstudy目录

修改php.ini文件
curl.cainfo = D:\phpStudy\cacert.pem
文件路径为刚才下载的文件绝对路径,然后重启 phpstudy 就行

PHP7捕获错误异常

公司最近一个项目使用的是PHP7,发现使用 php5里面的 Exception 类捕获不到致命错误。
查了一下手册,PHP7的错误报告机制已改变,大多数错误被作为 Error 异常抛出

php官网说明是
这种 Error 异常可以像 Exception 异常一样被第一个匹配的 try / catch 块所捕获。如果没有匹配的 catch 块,则调用异常处理函数(事先通过 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。

Error 类并非继承自 Exception 类,所以不能用 catch (Exception $e) { … } 来捕获 Error。你可以用 catch (Error $e) { … },或者通过注册异常处理函数( set_exception_handler())来捕获 Error。

来一段代码实例

try {
    echo asdfasdf('1');  //未定义的函数
} catch (Exception $e) {
    // Handle exception
    echo 'Exception';
} catch (Error $e) { // Clearly a different type of object
    // Log error and end gracefully
    echo 'Error';
}

最后输出的是 Error 。。。
所以用PHP7捕获异常防止错误的话,建议 catch :Exception 和 Error

php使用curl设置超时的重要性

这段时间用PHP写了个爬虫程序,但是经常执行了一段时间后程序就卡住了。
程序是用的curl方式进行抓取,后来设置了 CURLOPT_TIMEOUT 参数就没有出现这个问题了
平常如果测试curl都直接设置了url就直接执行了。
curl功能还是很强大的,如果线上使用最好还是把 所有参数都设置一遍,还可以设置毫秒级超时
最后分享一段 curl 方法

function http_request($URI, $isHearder = false, $post = false)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $URI);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);          //单位 秒,也可以使用
#curl_setopt($ch, CURLOPT_NOSIGNAL, 1);     //注意,毫秒超时一定要设置这个
#curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //超时毫秒,cURL 7.16.2中被加入。从PHP 5.2.3起可使用
    curl_setopt($ch, CURLOPT_HEADER, $isHearder);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36');
    curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__)."/tmp.cookie");
    curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__)."/tmp.cookie");
    if(strpos($URI, 'https') === 0){
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    }
    if($post){
        curl_setopt ($ch, CURLOPT_POST, 1);
        curl_setopt ($ch, CURLOPT_POSTFIELDS, $post);
    }
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

过滤utf8mb4字符转为mysql支持的utf8

最近做开发 发现,有些字符不能存进mysql,后来百度后,得出的结论是,mysql的utf8编码并不是真正完整的utf8,在mysql新版本里选择utf8mb4这才是完整的utf8编码。
手机上有些图标比如: Emoji表情图标 在mysql里面需要选择utf8mb4才能存储和显示,网上大部分用mysql存Emoji表情相关的解决办法是 把mysql的字符集改为 utf8mb4,但是 最近有个需求就是截取掉对于mysql的utf8mb4的字符集。想了几天,突然想在wordpress看代码,结果 果然找到,分享之。此方案为过滤掉 utf8mb4 的字符

我这里的mysql本来就不支持utf8mb4的,所以就这样基本上看不到效果….

    $str = '□测试,测试!123□';
    $charset = 'utf8';
    $regex = '/
        (
            (?: [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
            |   [\xC2-\xDF][\x80-\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
            |   \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
            |   [\xE1-\xEC][\x80-\xBF]{2}
            |   \xED[\x80-\x9F][\x80-\xBF]
            |   [\xEE-\xEF][\x80-\xBF]{2}';

    if ( 'utf8mb4' === $charset ) {
        $regex .= '
            |    \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
            |    [\xF1-\xF3][\x80-\xBF]{3}
            |    \xF4[\x80-\x8F][\x80-\xBF]{2}
        ';
    }

    $regex .= '){1,40}                          # ...one or more times
        )
        | .                                  # anything else
        /x';
    $str1 = preg_replace( $regex, '$1', $str );
    var_dump($str1);

    //另一种解决方法
    $str1 = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $str);
    var_dump($str1);

PHP实现linux下tail命令功能

发现很久没更新博客了,前几天写了个微信爬虫,但是想要实时查看爬虫的情况,所以爬虫会把记录写到一个文件里面。
如果是在linux shell直接用 tail -f 命令就可以实时查看更新了。但是每次都要ssh登录,觉得还是太麻烦。
干脆用PHP写个tail功能的脚本,然后再用 ajax请求 php文件 获取文件最后几行,这样就可以直接在浏览器上面实现 linux命令行里面tail功能了。 继续阅读

ThinkPHP框架使用Smarty模板引擎

最近公司使用ThinkPHP框架,所以比较关注,想到之前公司使用的框架用的模板引擎是 Smarty,而且用的还挺顺手的。
转到使用ThinkPHP自带的模板引擎还有点不习惯,所以在想换成Smarty模板引擎,网上看了一下,结果还是比较简单。
以此记录一下 继续阅读

用CORS(跨域源资源共享)解决跨域问题

前几天比较厉害的一位前端的同事说了一下跨域的问题,提供了一些比较好的解决办法。最后推荐的方法就是CORS(跨来源资源共享)。不过这方法好像 百度出来的东西挺少的,所以自己测试了一下。还是比较好用,不过这方法有些比较老的浏览器不支持,IE8据说是支持的,不过有点麻烦。具体支持情况可以查看 维基百科 http://zh.wikipedia.org/wiki/CORS

主要是在服务器端申明一下支持 CORS就行了。。。
header(“Access-Control-Allow-Origin:https://phpquan.com”);
这是比较安全的,意思是只接受 phpquan.com 跨域来的请求。这样就可以很简单的使用jQuery里面的ajax方法请求。
百度了很多,一般解决方法是最省事的一句 header(“Access-Control-Allow-Origin:*”); 继续阅读

NetBeans风格化

经常在QQ群看到别人的截图,代码背景是黑色的,有种不明觉厉的感觉。问了一下是用的什么IDE,回答用的是 VI。
这几天发现NetBeans也可以风格化,做成像VI的样子。可能很多人都早就知道这东西了,不过我的确这几天才发现,虽然可能晚了点但还是分享一下,如图:
Uploaded-Monokai

继续阅读

PHP防注入小论,目前觉得htmlspecialchars挺好

好久没写博客了,也证明好久都没写代码了。
最近不忙,写代码时可停下来试试每个函数的不同和特性。 之前写PHP对于防注入一直不太注意,这次专门对 htmlspecialchars 、htmlentities、addslashes 几个函数使用了一下。。。

htmlspecialchars 将特殊字符转成 HTML 格式,具体的说,函数会转化以下字符:
& (和号) 成为 &
” (双引号) 成为 "
‘ (单引号) 成为 '
< (小于) 成为 &lt;
> (大于) 成为 &gt;

对应的反编码函数为 htmlspecialchars_decode

htmlentities,将所有的字元都转成 HTML 字串
对应的反编码函数 html_entity_decode

注意 :htmlspecialchars最多只能处理4个html标记,htmlentities是转化全部字符,包括中文。

addslashes是使用反斜线引用字符串,该函数一般都是数据库查询之前就需要处理的必要步骤,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。这些字符是单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)
对应的反编码函数为stripslashes是还原addslashes引用的字符串。

所以这里一般文本输入输出的话使用 htmlspecialchars和htmlspecialchars_decode,有些文本里面有中文的话,又不支持html的话使用 htmlspecialchars 比较实用。
字段查询可能还是使用 addslashes

ThinkPHP3.1修改X-Powered-By信息

最近发现 ThinkPHP 框架里面把头文件信息里面的 X-Powered-By 改了,这样很明显让人知道是使用的ThinkPHP框架,有个危险的地方就是 万一 ThinkPHP曝出漏洞的话,这是个很明显的目标。所以找了一下修改 X-Powered-By的方法。其实也很简单。。

找到这个文件
ThinkPHP/Lib/Core/View.class.php

里面搜索 ‘header’,能看到有一个是 header(‘X-Powered-By:ThinkPHP’) 只要把这句注释掉,或者修改成其他的就行。