分类目录归档:LAMP路上

工作中遇到的一些问题和得到的一些经验关于 Linux、Apache、Mysql、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模板引擎,网上看了一下,结果还是比较简单。
以此记录一下 继续阅读

shell中$0,$?,$!,$$,$*,$#等特殊变量说明及用法

闲来无事看了下关于<>,看到书上说shell可以获取程序的返回值,故百度一下(google最近太不稳定了),发现shell里还有很多特殊变量没有记住,还是写篇博客记录下,以后也方便查找

变量说明:

$$
Shell本身的PID(进程ID)
$!
Shell最后运行的后台Process的PID
$?
最后运行的命令的结束代码(返回值),可以得到之前运行程序的返回值,可以判断程序是否运行正确(一般程序运行正确返回0)
$-
使用Set命令设定的Flag一览
$*
所有参数列表。如”$*”用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数。
$@
所有参数列表。如”$@”用「”」括起来的情况、以”$1″ “$2” … “$n” 的形式输出所有参数。
$#
添加到Shell的参数个数
$0
Shell本身的文件名
$1~$n
添加到Shell的各参数值。$1是第1参数、$2是第2参数…。

我们先写一个简单的脚本,执行以后再解释各个变量的意义
# touch variable
# vi variable
脚本内容如下:
#!/bin/sh
echo “number:$#”
echo “scname:$0”
echo “first :$1”
echo “second:$2”
echo “argume:$@”
保存退出
赋予脚本执行权限
# chmod +x variable
执行脚本
# ./variable aa bb
number:2
scname:./variable
first: aa
second:bb
argume:aa bb
通过显示结果可以看到:
$# 是传给脚本的参数个数
$0 是脚本本身的名字
$1是传递给该shell脚本的第一个参数
$2是传递给该shell脚本的第二个参数
$@ 是传给脚本的所有参数的列表
$?

树莓派raspbian系统下USB无线网配置

最近准备用树莓派做个 wifi小车,为了驱动问题 专门还买了 tp-link的usb无线网卡,没想到买回来就是驱动不了。。。废话就不说了直接上解决办法了

没想到买的是TP-LINK WN725N V2无线网卡,网上查找了一下Raspberry Pi(树莓派)是支持这个网卡v1版本的,没想到他v2版本芯片升级了。

最开始网上搜,需要自己编译,结果慢慢发现直接下载一个 .ko的文件就直接可以用。但这个 8188eu.ko还要分系统的版本。我是装的目前为止最新的 raspbian系统,用的就是 8188eu.ko & firmware (Compiled in 2014-01) 继续阅读

MySQL数据库里面InnoDB与Myisam的对比区别

最近一段时间有点小忙,做了关于支付的东西。
因为支付方面的业务很严谨,所以看到代码里面用了 MYSQL的事务功能,抽空自己也弄了一下,才发现MyISAM根本就不支持 事务,InnoDB支持事务。
然后百度了一下 MyISAM和InnoDB 区别。找到以下表格,贴出来以免忘了 继续阅读

用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:*”); 继续阅读