PHP curl 获取响应的状态吗

2012年12月23日 没有评论

PHP curl可以从服务器端模拟一个http请求,例如抓取网页、模拟登陆等。根据选项设置,可以在curl_exec的返回结果中获取到响应头和body,但这没有响应的状态吗。想要获取状态吗,需要在执行curl_exec后再通过curl_getinfo来获取。例如:

$ch = curl_init ();
curl_setopt($ch, CURLOPT_URL, 'http://www.google.com.hk');
curl_setopt($ch, CURLOPT_TIMEOUT, 200);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_NOBODY, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_exec($ch);
$httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE);

另外curl_getinfo还可以获取很多其他信息,具体请参考:http://php.net/manual/en/function.curl-getinfo.php 。

分类: PHP 标签:

使用PHPMailer发送邮件

2012年12月20日 2 条评论

PHPMailer是别人封装好的一个发送邮件的库,用起来很方便。其支持mail、sendmail和smtp的方式。官网地址:http://phpmailer.worxware.com/,可以到https://code.google.com/a/apache-extras.org/p/phpmailer/downloads/list去下载最新版本的。下面通过gmail smtp发送邮件为例来说明smtp使用方法。

function sendMail($subject, $body, $to, $ccs = array()) {
    require_once './class.phpmailer.php';

    $mail  = new PHPMailer();
    //设定邮件编码,默认ISO-8859-1,也可以直接去源代码中修改
    $mail->CharSet = 'UTF-8';
    // 使用smtp的方式发送
    $mail->IsSMTP();
    //smtp服务器需要认证
    $mail->SMTPAuth = TRUE;
    //安全协议 gmail 是采用ssl的
    $mail->SMTPSecure = "ssl";
    //smtp服务器
    $mail->Host = 'smtp.gmail.com';
    //smtp服务器端口,普通是25
    $mail->Port = 465;
    //smtp 认证用户名和密码
    $mail->Username = 'yourgmailaccount@gmail.com';
    $mail->Password = "yourpassword";
    //发件人地址和名字,名字可以省略
    $mail->SetFrom('yourgmailaccount@gmail.com', 'display name');
    // 邮件标题
    $mail->Subject = $subject;
    // 邮件内容,支持HTML格式
    $mail->MsgHTML($body);
    // 收件人地址
    $mail->AddAddress($to);
    // 抄送人
    foreach ($ccs as $cc) {
        $mail->AddCC($cc);
    }

    if(!$mail->Send()) {
        echo "error info:" . $mail->ErrorInfo;
    }
}
分类: PHP 标签:

PHP ob_clean 清空先前输出

2012年12月19日 没有评论

默认配置下,php输出是先到输出缓冲区(output_buffering),只要数据还没有真正发送到浏览器(严格来说是tcp buffer),那么还是有机会清空先前的缓冲区里面的数据,使用内置的ob_clean函数即可。注意:ob_clean 只是清空当前缓冲区的数据,如果先前输出的数据大于缓冲区,那么一部分数据已经发送,发送的这部分数据是无法清空的。另外如果禁用php输出缓冲区,那么ob_clean起不到任何效果的。

分类: PHP 标签:

php foreach 传值还是传引用

2012年12月17日 3 条评论

php 中遍历一个array时可以使用for或foreach,foreach的语法为:foreach ($arr as $k => $v)。遍历数组,把index赋给$k,数组的值赋给$v,那么此处的赋值是传值还是传引用呢。先看下面的例子:

$arr = array(
    array('id' => 1, 'name' => 'name1'),
    array('id' => 2, 'name' => 'name2'),
);

foreach ($arr as $obj) {
    $obj['id'] = $obj['id'];
    $obj['name'] = $obj['name'] . '-modify';
}

print_r($arr); //输出的结果
Array(
    [0] => Array (
        [id] => 1
        [name] => name1
    )
    [1] => Array(
        [id] => 2
        [name] => name2
    )
)

观察可以发现在foreach循环中对$arr操作并没有影响到$arr的元素,所以这里的赋值是传值而不是传引用。那如果需要修改$arr中元素的值该怎么办呢?可以在变量前面加一个”&”符号,例如:

foreach ($arr as &$obj) {
    $obj['id'] = $obj['id'];
    $obj['name'] = $obj['name'] . '-modify';
}

再看另外一个例子,array里面存放的是object,

$arr = array(
    (object)(array('id' => 1, 'name' => 'name1')),
    (object)(array('id' => 2, 'name' => 'name2')),
);

foreach ($arr as $obj) {
    $obj->name = $obj->name  . '-modify'; 
}

print_r($arr); //输出的结果

Array
(
    [0] => stdClass Object
        (
            [id] => 1
            [name] => name1-modify
        )

    [1] => stdClass Object
        (
            [id] => 2
            [name] => name2-modify
        )

)

此时可以看到原始数组中的object对象已经修改了,所以这里的赋值又是传引用而不是传值

综合上述,得出的结论:如果数组里面存放的是普通类型的元素就是采用传值的方式,存放对象类型元素采用的方式为传地址

分类: PHP 标签:

php 字符串和数字比较问题

2012年12月4日 没有评论

今天遇到一个问题,调用对方接口,按照接口说明,返回为数字0,1,2等等,其中0标示成功,其他表示不同的错误代码。程序通过 if ($ret == 0) 进行判断,开始程序是好的,今天出现问题了,由于对方接口修改,直接返回字母字符串作为错误信息提示,然后我这边就悲剧了,上述判断永远都为TRUE。

原因在于php是弱类型语言,所以可以对两个不同类型的变量进行比较操作,但最终进行比较前,php会把某一方转换称另一方一样的类型,这点很重要。如果是字符串和数字进行比较,那么php会把字符串强制转换称数字,对于纯字母的字符串,那么转换后就是0了,所以if ($ret == 0) 成了。

附PHP官方介绍:http://php.net/manual/zh/language.operators.comparison.php

分类: PHP 标签:

php is_dir函数

2012年12月2日 没有评论

php提供内置函数is_dir来检查传入的路径参数是否为目录,如果是目录则返回true。也就是说传入的参数是文件或者不存在都为false,因此当前参数不能说不是文件夹就是文件。另外需要注意的是参数支持相对路径和绝对路径。如果是绝对路径,那么就直接判断其是否为文件夹,但是相对路径就不一样了,参数指定的路径是相对当前工作目录的。例如传入的参数为“test”,那么他实际检查的是脚本所在的路径下是否有名为test的目录。由于当前工作目录不是很明晰的,为了避免犯错,最好是使用绝对路径。

分类: PHP 标签:

PHP中HTTP_HOST和SERVER_NAME的区别

2012年9月16日 1 条评论

HTTP_HOST是客户端请求时封装在HTTP request header中,而SERVER_NAME是web服务器中配置文件定义的。这两个值有时是相同的,但不能说他们就是一样的,因为这个起决于服务器的WEB server 配置。例如使用nginx作为为web 服务器,配置如下:

server {
	listen      80;
	server_name *.netingcn.com;
	....
}

假设访问 http://www.netingcn.com/test.php,这是使用$_SERVER['HTTP_HOST']得到的结果为:www.netingcn.com,而$_SERVER['SERVER_NAME']则是*.netingcn.com

从url中提取参数名和参数值

2012年8月12日 没有评论

在已知参数名的情况下,获取参数值,使用正则表达式能很容易做到。js的实现方法如下:

function getValue(url, name) {
	var reg = new RegExp('(\\?|&)' + name + '=([^&?]*)', 'i');
	var arr = url.match(reg);

	if (arr) {
		return arr[2];
	}

	return null;
}

如果想获取所有的参数名和其对应的值,同样也可以使用正则表达式的方法,js实现方法:

function getKeyValue(url) {
	var result = {};
	var reg = new RegExp('([\\?|&])(.+?)=([^&?]*)', 'ig');
	var arr = reg.exec(url);

	while (arr) {
		result[arr[2]] = arr[3];

		arr = reg.exec(url);
	}

	return result;
}

注意在js中用于匹配的还有一个叫match,match是字符串的方法,而exec是RegExp对象的方法。使用字符串的match方法,同时正则表达式指定为全局匹配,那么正则表达式中的分组将没有用,返回的结果是所有匹配正则表达式的子字符串。exec方法没有使用全局匹配标志时,返回的时间第一个匹配的子字符,如果使用了全局匹配标志,第一次执行从头开始匹配符号的字符串,再次调用,就从上一次匹配结果后开始匹配。

下面提供php的实现方法:

function getKeyValue($url) {
	$result = array();
	$mr = preg_match_all('/(\?|&)(.+?)=([^&?]*)/i', $url, $matchs);

	if ($mr !== FALSE) {
		for ($i = 0; $i < $mr; $i++) {
			$result[$matchs[2][$i]] = $matchs[3][$i];
		}
	}

	return $result;
}

php的preg_match_all方法把匹配的结果存放在第三个指定的参数中,是一个二维数组。第一维度是分组信息的数组,即第一个数组存放的是所有匹配的完整字符串,第二个数组存放的是第一个()对应的值得,第二维度是分组的值。

php header 之 Set-Cookie

2012年7月29日 没有评论

php设置cookie可以使用setcookie函数或header函数。使用header方式时候需要注意字符串的顺序,如果顺序不对,可能会出现意想不到的问题。正确的顺序为

name=value; [expires=date; [path=path]; [domain=domainname]; [secure]]

例如:在netingcn.com下设置一个名为cookiename,值为cookieValue,过期时间为一年的cookie

header("Set-Cookie: cookiename=cookieValue; expires=" . gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT", time() + (86400 * 365)) .  '; path=/; domain=netingcn.com');

如果把domain、path放到expires前面,在firefox通过httpfox查看时,发现过期时间是“End Of Session”,但退出浏览器后重新打开,发现该cookie还是存在的,chrome显示的也是类似。虽说浏览器最终还是设置了一个一年过期的cookie,不过domain信息为当前页面的完整域,不是设置的顶级域。所以一定要注意顺序。

另外,如果用header的方式设置多个cookie,需要设置header的第二个参数为FALSE,下面是header函数的声明:

void header ( string string [, bool replace [, int http_response_code]] )

第二个参数replace 指明是替换掉前一条类似的标头还是增加一条相同类型的标头。默认为替换,但如果将其设为 FALSE 则可以强制发送多个同类标头。

分类: PHP 标签:

unable to load dynamic library memcached.so

2012年7月28日 1 条评论

通过源代码编译安装php的memcached扩展,一路顺利,最终生成了memcached.so,同时在php.ini中添加了extension=memcached.so,使用命令php -v查看时提示PHP Warning: PHP Startup: Unable to load dynamic library。以前在多台机器上安装扩展都是这么设置就可以,但是这台机器上就不行,后来发现是此机器的php.ini默认配置中使用了extension_dir,解决办法就是注释掉php.ini中的extension_dir配置。

关于memcached扩展的安装可以参看这里:http://www.netingcn.com/php-memcached.html

分类: PHP 标签:

无觅相关文章插件,快速提升流量