标签 PHP 下的文章

做采集的都知道,一般采集过来的内容难免会带有html标签,如果有太多的标签会影响之后的数据分析或提取,所以需要过滤掉!PHP已经为我们提供了很多清除html格式的方法了,下面就让老高介绍一下。

strip_tags

strip_tags($str) 去掉 HTML 及 PHP 的标记 语法: string strip_tags(string str); 传回值: 字串 函式种类: 资料处理 内容说明 : 解析:本函式可去掉字串中包含的任何 HTML 及 PHP 的标记字串。若是字串的 HTML 及 PHP 标签原来就有错,例如少了大于的符号,则也会传回错误。这个函数和 fgetss() 有着相同的功能

例子

echo strip_tags("Hello world!");
# Hello world!

htmlspecialchars

这个函数把html中的标签转换为html实体,博客的代码展示就必须使用这个函数,要不贴出来的代码就会被执行了。 预定义的字符是: & (和号) 成为 & ” (双引号) 成为 ” ‘ (单引号) 成为 ‘ < (小于) 成为 < > (大于) 成为 >

例子

$new = htmlspecialchars("Test", ENT_QUOTES);
echo $new; 
# <a href='test'>Test</a>
# 如果需要展现
,那么浏览器解析HTML的时候会自动将他变为换行 # 但是通过htmlspecialchars就可以让< 变为 '

与htmlspecialchars功能相反的函数是htmlspecialchars_decode,他会把HTML实体转化为字符!

后补函数

PHP去除html、css样式、js格式的方法很多,但发现,它们基本都有一个弊端:空格往往清除不了 经过不断的研究,最终找到了一个理想的去除html包括空格css样式、js 的PHP函数。

$descclear = str_replace("\r","",$descclear);//过滤换行
$descclear = str_replace("\n","",$descclear);//过滤换行
$descclear = str_replace("\t","",$descclear);//过滤换行
$descclear = str_replace("\r\n","",$descclear);//过滤换行
$descclear = preg_replace("/\s+/", " ", $descclear);//过滤多余回车
$descclear = preg_replace("/<[ ]+/si","<",$descclear); //过滤<__("<"号后面带空格)
$descclear = preg_replace("/<\!--.*?-->/si","",$descclear); //过滤html注释
$descclear = preg_replace("/<(\!.*?)>/si","",$descclear); //过滤DOCTYPE
$descclear = preg_replace("/<(\/?html.*?)>/si","",$descclear); //过滤html标签
$descclear = preg_replace("/<(\/?head.*?)>/si","",$descclear); //过滤head标签
$descclear = preg_replace("/<(\/?meta.*?)>/si","",$descclear); //过滤meta标签
$descclear = preg_replace("/<(\/?body.*?)>/si","",$descclear); //过滤body标签
$descclear = preg_replace("/<(\/?link.*?)>/si","",$descclear); //过滤link标签
$descclear = preg_replace("/<(\/?form.*?)>/si","",$descclear); //过滤form标签
$descclear = preg_replace("/cookie/si","COOKIE",$descclear); //过滤COOKIE标签
$descclear = preg_replace("/<(applet.*?)>(.*?)<(\/applet.*?)>/si","",$descclear); //过滤applet标签
$descclear = preg_replace("/<(\/?applet.*?)>/si","",$descclear); //过滤applet标签
$descclear = preg_replace("/<(style.*?)>(.*?)<(\/style.*?)>/si","",$descclear); //过滤style标签
$descclear = preg_replace("/<(\/?style.*?)>/si","",$descclear); //过滤style标签
$descclear = preg_replace("/<(title.*?)>(.*?)<(\/title.*?)>/si","",$descclear); //过滤title标签
$descclear = preg_replace("/<(\/?title.*?)>/si","",$descclear); //过滤title标签
$descclear = preg_replace("/<(object.*?)>(.*?)<(\/object.*?)>/si","",$descclear); //过滤object标签
$descclear = preg_replace("/<(\/?objec.*?)>/si","",$descclear); //过滤object标签
$descclear = preg_replace("/<(noframes.*?)>(.*?)<(\/noframes.*?)>/si","",$descclear); //过滤noframes标签
$descclear = preg_replace("/<(\/?noframes.*?)>/si","",$descclear); //过滤noframes标签
$descclear = preg_replace("/<(i?frame.*?)>(.*?)<(\/i?frame.*?)>/si","",$descclear); //过滤frame标签
$descclear = preg_replace("/<(\/?i?frame.*?)>/si","",$descclear); //过滤frame标签
$descclear = preg_replace("/<(script.*?)>(.*?)<(\/script.*?)>/si","",$descclear); //过滤script标签
$descclear = preg_replace("/<(\/?script.*?)>/si","",$descclear); //过滤script标签
$descclear = preg_replace("/javascript/si","Javascript",$descclear); //过滤script标签
$descclear = preg_replace("/vbscript/si","Vbscript",$descclear); //过滤script标签
$descclear = preg_replace("/on([a-z]+)\s*=/si","On\\1=",$descclear); //过滤script标签
$descclear = preg_replace("/&#/si","&#",$descclear); //过滤script标签,如javAsCript:alert();
//使用正则替换
$pat = "/<(\/?)(script|i?frame|style|html|body|li|i|map|title|img|link|span|u|font|table|tr|b|marquee|td|strong|div|a|meta|\?|\%)([^>]*?)>/isU";
$descclear = preg_replace($pat,"",$descclear);

总结

采集这个东西说简单很简单,但说难真的很难。一旦遇到错误,就会让人很抓狂!

想要成为采集高手,你不仅需要了解从一个计算机发出的基于TCP的HTTP请求到最终得到请求的文件的整个过程,而且能够使用一系列的工具来协助你跟踪数据的去处,同时需要考虑你写出的采集任务的效率!

如果你需要采集twitter或者Facebook的数据,可以参考使用shadowsocks轻松搭建FQ环境

编程时间长了,大家见过很多函数功能吧,比如获取用户IP等等,现在我将常用的PHP函数做个总结,方便大家COPY和使用。

's','o'=>'t','l'=>'xx');
//echo strsReplace('hello',$arrayName);
function strsReplace($str, $replaces)
{
	$subject=$str;
    foreach ($replaces as $k => $v)
        $subject = str_replace($k, $v, $subject);
    return $subject;
}

//规范文件名
//$filename='"<>/\\\asda/.,psd|"';
//echo tripFilename($filename);
function tripFilename($filename)
{
	//$s=array("/","\\","?","*","<",">",'"',"|",",","'");//使用时请删除屏蔽
    return str_replace($s,"",$filename);
}

//PHP判断数组维度  
//$arr=array('yiyi'=>1212,'haha'=>array('heihei'=>array(array("a")),"b"));
//echo getMaxDim($arr);
function getMaxDim($vDim)
{
    if (!is_array($vDim))
        return 0;
    else {
        $max1 = 0;
        foreach ($vDim as $item1) {
            $t1 = getMaxDim($item1);
            if ($t1 > $max1)
                $max1 = $t1;
        }
        return $max1 + 1;
    }
}

//给数字加小数点,默认格式为452.00
//echo fee(452);
function fee($fee, $size = 2)
{
    $fee = trim($fee);
    if (empty($fee))
        return '0.00';
    if (!is_numeric($fee))
        return 'err';
    return number_format($fee, $size, '.', '');
}

//获取随机序列(注:实测数字最好9位一下)
//echo random(9,1);
//echo random(25);
function random($length, $numeric = 0)
{
    PHP_VERSION < '4.2.0' && mt_srand((double) microtime() * 100000000000);
    if ($numeric) {
        $hash = sprintf('%0' . $length . 'd', mt_rand(0, pow(10, $length) - 1));
    } else {
        $hash  = '';
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
        $max   = strlen($chars) - 1;
        for ($i = 0; $i < $length; $i++) {
            $hash .= $chars[mt_rand(0, $max)];
        }
    }
    return $hash;
}

//错误提醒
function alertBack($msg = "")
{
    $html = "
		           ";
    echo $html;
    exit();
}

//提醒跳转
function alertGoto($url, $msg)
{
    $html = "
		           ";
    echo $html;
    exit();
}

//建立文件夹
function createDir($path)
{
    if (!file_exists($path)) {
        createDir(dirname($path));
        mkdir($path);
    }
}

//删除文件夹
function deleteDir($dir)
{
    $dh = opendir($dir);
    while ($file = readdir($dh))
        if ($file != "." && $file != "..") {
            $fullpath = $dir . "/" . $file;
            if (!is_dir($fullpath))
                unlink($fullpath);
            else
                deleteDir($fullpath);
        }
    closedir($dh);
    if (rmdir($dir))
        return true;
    else
        return false;
}

//获取扩展名
function getFileType($filename)
{
    if (substr_count($filename, ".") == 0) { // 检查文件名中是否有.号。 
        return; // 返回空
    } else if (substr($filename, -1) == ".") { // 检查是否以.结尾,即无扩展名 
        return; // 返回空 
    } else {
        $fileType = strrchr($filename, "."); // 从.号处切割 
        $fileType = substr($fileType, 1); // 去除.号  
        return $fileType; // 返回  
    }
}

//匹配手机号
function checkTel($tel)
{
    if (strlen($tel) != 11)
        return false;
    return preg_match('/^1(3|5|8)[0-9]{9}$/', $tel);

}

//检查EMAIL格式
function checkEmail($email)
{
    if ($email == '')
        return false;
    if (eregi("^[_\.0-9a-z]+@([0-9a-z][0-9a-z]+\.)+[a-z]{2,3}$", $email))
        return true;
    return false;

}

//SMTP发送邮件
function sendMail($mail)
{
    global $m;
    if ($m->cfg['mailMethod'] == 'mail()') {
    }
    if ($m->cfg['mailMethod'] == 'smtp') {
        include_once "lib/smtp.class.php";
        $smtpserver  = $m->cfg['smtpServer']; //您的smtp服务器的地址
        $port        = empty($m->cfg['smtpPort']) ? '25' : $m->cfg['smtpPort']; //smtp服务器的端口,一般是 25 
        $smtpuser    = $m->cfg['smtpCount']; //您登录smtp服务器的用户名
        $smtppwd     = $m->cfg['smtpPas']; //您登录smtp服务器的密码
        $mailtype    = "HTML"; //邮件的类型,可选值是 TXT 或 HTML ,TXT 表示是纯文本的邮件,HTML 表示是 html格式的邮件
        $sender      = $m->cfg['smtpCount']; //发件人,一般要与您登录smtp服务器的用户名($smtpuser)相同,否则可能会因为smtp服务器的设置导致发送失败
        $smtp        = new smtp($smtpserver, $port, true, $smtpuser, $smtppwd, $sender);
        $smtp->debug = true; //是否开启调试,只在测试程序时使用,正式使用时请将此行注释
        $send        = $smtp->sendmail($mail['to'], $sender, $mail['subject'], $mail['body'], $mailtype);
        if ($send == 1)
            return true;
        return $this->smtp->logs;
    }
}

//检查身份证有效性
function checkId($id_card)
{
    if (strlen($id_card) == 18) {
        return idcard_checksum18($id_card);
    } elseif ((strlen($id_card) == 15)) {
        $id_card = idcard_15to18($id_card);
        return idcard_checksum18($id_card);
    } else {
        return false;
    }
}
// 计算身份证校验码,根据国家标准GB 11643-1999 
function idcard_verify_number($idcard_base)
{
    if (strlen($idcard_base) != 17) {
        return false;
    }
    //加权因子 
    $factor             = array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);
    //校验码对应值 
    $verify_number_list = array('1','0','X','9','8','7','6','5','4','3','2');
    $checksum           = 0;
    for ($i = 0; $i < strlen($idcard_base); $i++) {
        $checksum += substr($idcard_base, $i, 1) * $factor[$i];
    }
    $mod           = $checksum % 11;
    $verify_number = $verify_number_list[$mod];
    return $verify_number;
}
// 将15位身份证升级到18位 
function idcard_15to18($idcard)
{
    if (strlen($idcard) != 15) {
        return false;
    } else {
        // 如果身份证顺序码是996 997 998 999,这些是为百岁以上老人的特殊编码 
        if (array_search(substr($idcard, 12, 3), array(
            '996',
            '997',
            '998',
            '999'
        )) !== false) {
            $idcard = substr($idcard, 0, 6) . '18' . substr($idcard, 6, 9);
        } else {
            $idcard = substr($idcard, 0, 6) . '19' . substr($idcard, 6, 9);
        }
    }
    $idcard = $idcard . idcard_verify_number($idcard);
    return $idcard;
}
// 18位身份证校验码有效性检查 
function idcard_checksum18($idcard)
{
    if (strlen($idcard) != 18) {
        return false;
    }
    $idcard_base = substr($idcard, 0, 17);
    if (idcard_verify_number($idcard_base) != strtoupper(substr($idcard, 17, 1))) {
        return false;
    } else {
        return true;
    }
}

//获取星期
//echo getWeek('2013-09-02');
function getWeek($day)
{
    $days = array('周日','周一','周二','周三','周四','周五','周六');
    $day  = explode('-', $day);
    return $days[date('w', mktime(0, 0, 0, $day[1], $day[2], $day[0]))];
}

?>

问题? 今天迁站的时候PHP突然报错:

is_readable() [function.is-readable]: open_basedir restriction in effect. File(D:\phpnow\vhosts\wordpress.com/wp-content/plugins/D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/crayon-syntax-highlighter-zh_CN.mo) is not within the allowed path(s): (D:\phpnow\vhosts\wordpress.com;C:\Windows\Temp;) in D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php on line 339 好吧,看来是crayon-syntax-highlighter插件出错了,下面我们就一起找找出错的地方吧。

如何解决

确定出错地点 根据出错提示我们找到了

D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php的第339行,代码如下:

if ( !is_readable( $mofile ) ) return false;

这个$mofile哪里来的呢?把整个函数贴出来找找看!

function load_textdomain( $domain, $mofile ) {
	global $l10n;

	$plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );

	if ( true == $plugin_override ) {
		return true;
	}

	do_action( 'load_textdomain', $domain, $mofile );

	$mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain );

	if ( !is_readable( $mofile ) ) return false;

	$mo = new MO();
	if ( !$mo->import_from_file( $mofile ) ) return false;

	if ( isset( $l10n[$domain] ) )
		$mo->merge_with( $l10n[$domain] );

	$l10n[$domain] = &$mo;

	return true;
}

看来是函数传进来的一个字符串,看来我们要继续寻找调用这个函数的地方了。不过wordpress的php文件少说也有1000多个,这样找下去是个什么效率?

等等!我好像想起来在学习数据结构的时候有一个概念叫栈,stack,什么是栈呢?其实站只是一个特殊的数据结构,它只允许在一串数据的一段进行操作,比如增加数据元素(入栈),删除数据元素(出栈)。举个栗子,堆栈就好比向水杯中放乒乓球,水杯的横截面只能通过一个乒乓球,如果想要把最先放进去的球取出来,必须把他上面的乒乓球按顺序一个一个取出来才行。 为什么突然想到栈这个概念呢?因为我们的函数调用就是使用的栈这个概念。简单地说,一个函数调用另一个函数,那么在调用期间需要保存现场,将自己的数据(比如调用指针、参数等)压入一个栈中,当调用完毕后再出栈恢复数据,然后继续调用。这个过程说起来简单,其实很复杂。以下摘自wikipedia:

在计算机科学领域中,'调用栈'Call Stack)是用于存储子程序信息的一类栈,别称执行栈(execution stack)、控制栈(control stack)、运行时栈(run-time stack)与机器栈(machine stack),在英语中亦经常简称为“栈”(“the stack”)。调用栈的维护对多数软件的正常运转有着重要意义,但一般高级语言都会隐藏其细节并自动进行维护。

既然细节被隐藏了,那么就不用深究了。下面就引出今天的主角函数。

主角

debug_backtrace()和debug_print_backtrace()两兄弟。

主要功能:他们保存了函数的调用栈信息,一个不输出以数组形式保存,另一个直接输出调用栈,调试的时候一般使用debug_print_backtrace()。 知道了这两个函数,将函数加入要追溯的函数内的第一行,不要忘了加;。 debug_backtrace()使用print_r显示如下:

Array
(
    [0] => Array
        (
            [file] => D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php
            [line] => 428
            [function] => load_textdomain
            [args] => Array
                (
                    [0] => crayon-syntax-highlighter
                    [1] => D:\phpnow\vhosts\wordpress.com/wp-content/plugins/D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/crayon-syntax-highlighter-zh_CN.mo
                )

        )

定睛一看,原来是个多维数组。file是调用文件,line是函数出现的行数,function是函数名,args是参数。 直接使用debug_print_backtrace()看看:

#0  load_textdomain(crayon-syntax-highlighter, D:\phpnow\vhosts\wordpress.com/wp-content/plugins/D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/crayon-syntax-highlighter-zh_CN.mo) called at [D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php:428]
#1  load_plugin_textdomain(crayon-syntax-highlighter, , D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/) called at [D:\phpnow\vhosts\wordpress.com\wp-admin\includes\plugin.php:121]
#2  _get_plugin_data_markup_translate(D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php, Array ([Name] => Crayon Syntax Highlighter,[PluginURI] => https://github.com/aramkocharyan/crayon-syntax-highlighter,[Version] => 2.4.1,[Description] => Supports multiple languages, themes, highlighting from a URL, local file or post text.,[Author] => Aram Kocharyan,[AuthorURI] => http://aramk.com/,[TextDomain] => crayon-syntax-highlighter,[DomainPath] => /trans/,[Network] => ), 1, 1) called at [D:\phpnow\vhosts\wordpress.com\wp-admin\includes\plugin.php:99]
#3  get_plugin_data(D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php) called at [D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php:39]
#4  include_once(D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php) called at [D:\phpnow\vhosts\wordpress.com\wp-settings.php:197]
#5  require_once(D:\phpnow\vhosts\wordpress.com\wp-settings.php) called at [D:\phpnow\vhosts\wordpress.com\wp-config.php:90]
#6  require_once(D:\phpnow\vhosts\wordpress.com\wp-config.php) called at [D:\phpnow\vhosts\wordpress.com\wp-load.php:29]
#7  require_once(D:\phpnow\vhosts\wordpress.com\wp-load.php) called at [D:\phpnow\vhosts\wordpress.com\wp-blog-header.php:12]
#8  require(D:\phpnow\vhosts\wordpress.com\wp-blog-header.php) called at [D:\phpnow\vhosts\wordpress.com\index.php:30]

所有的函数调用清晰的呈现!

BUG在哪里?

通过仔细查找,发现原来load_plugin_textdomain()的第三个参数出了问题,该参数没有返回相对路径导致最后的路径错误,导致了MO文件无法找到。修改即可!

高级应用

请参考此篇

PHP debug_backtrace的胡思乱想

PHP经典函数

sys_getloadavg()

这个函数返回当前系统的负载均值信息(当然 Windows 下不适用),详细文档可以翻阅 PHP的相关文档。文档中有段示例代码,基本上也就能看出它的用途了。

$load = sys_getloadavg();
if ($load[0] > 80) {
    header('HTTP/1.1 503 Too busy, try again later');
    die('Server too busy. Please try again later.');
}
//PS,如果“很不幸”你的 PHP 环境中没有这个函数,可以考虑使用下面这段代码
if (!function_exists('sys_getloadavg')) {
    function sys_getloadavg()
    {
        $loadavg_file = '/proc/loadavg';
        if (file_exists($loadavg_file)) {
            return explode(chr(32),file_get_contents($loadavg_file));
        }
        return array(0,0,0);
    }
}

debug_backtrace兄弟

使用请参考使用debug_backtrace()做PHP调试

get_browser()

该方法参考一个名叫browscap.ini的文件,该文件收录了各种浏览器信息,通过比对实现查找客户浏览器的功能。 两个使用方法:

1.下载最新的browscap.ini,放入PHP的安装目录或者C:\Windows文件夹下

下载地址

2.在PHP.INI文件中加入以下配置

[browscap]
;https://blog.phpgao.com/classic_code/
browscap = php_browscap.ini

3.使用代码如下

http://www.phpgao.com
print_r($browser);

返回结果如下

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3

Array
(
    [browser_name_regex] => ^mozilla/5\.0 (windows; .; windows nt 5\.1; .*rv:.*) gecko/.* firefox/0\.9.*$
    [browser_name_pattern] => Mozilla/5.0 (Windows; ?; Windows NT 5.1; *rv:*) Gecko/* Firefox/0.9*
    [parent] => Firefox 0.9
    [platform] => WinXP
    [browser] => Firefox
    [version] => 0.9
    [majorver] => 0
    [minorver] => 9
    [cssversion] => 2
    [frames] => 1
    [iframes] => 1
    [tables] => 1
    [cookies] => 1
    [backgroundsounds] =>
    [vbscript] =>
    [javascript] => 1
    [javaapplets] => 1
    [activexcontrols] =>
    [cdf] =>
    [aol] =>
    [beta] => 1
    [win16] =>
    [crawler] =>
    [stripper] =>
    [wap] =>
    [netclr] =>
)

另一种方法:

http://alexandre.alapetite.fr/doc-alex/php-local-browscap/index.en.html

glob()

eg1:

方便地替代 opendir() 和相关函数


eg2:获取所有文件名,并输出为一个带链接的列表

".$filename."
"; } ?>

eg3:非递归实现文件遍历


更多使用请参考:

http://php.net/manual/zh/function.glob.php

PHP Filter 函数

让人很省心的函数,自动验证电子邮件或者url格式,使用方法请参考:

http://www.w3school.com.cn/php/php_ref_filter.asp

错误处理

set_error_handler — 设置一个用户定义的错误处理函数

占个坑,以后讲

这个是采集基础,最好熟悉一下

$ch = curl_init();
# 设定url和把结果返回,是否返回头部
curl_setopt($ch, CURLOPT_URL, 'http://www.baidu.com/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->ch, CURLOPT_HEADER, 1);

# cookie文件设定
curl_setopt($this->ch, CURLOPT_COOKIEJAR,  $cookie_file);
curl_setopt($this->ch, CURLOPT_COOKIEFILE, $cookie_file);

# 额外头部
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('User-Agent: Mozilla/5.0'));

# 设定post
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $poststring);

# 连接、执行过期时间
curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($this->ch, CURLOPT_TIMEOUT, 30);

# 是否跟随301 302
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($this->ch, CURLOPT_MAXREDIRS, 10);

# refer
curl_setopt($this->ch, CURLOPT_REFERER, $refer);

# http版本和端口重用设置
curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($this->ch, CURLOPT_FORBID_REUSE, 1);

# 支持https
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);

# 如果需要进行毫秒超时,需要增加:
curl_setopt($this->ch, CURLOPT_NOSIGNAL, 1);

# 执行
$response = curl_exec($ch);
if(curl_errno($ch)){
    curl_error($ch);
    exit();
}
curl_close($ch);