在php中file_get_contents与curl()函数都可以用来抓取对方网站的数据并保存到本地服务器中,但是总得来讲file_get_contents()效率稍低些,常用失败的情况、curl()效率挺高的,支持多线程,不过需要开启下curl扩展,也就是说要使用curl函数就必须要打开curl扩展了,而file_get_contents函数系统是默认的哦。
下面是curl扩展开启的步骤:
1、将PHP文件夹下的三个文件php_curl.dll,libeay32.dll,ssleay32.dll复制到system32下;
2、将php.ini(c:WINDOWS目录下)中的;extension=php_curl.dll中的分号去掉;
3、重启apache或者IIS。
我们先来看看两个函数的简单实例
curl()函数
代码如下 |
复制代码 |
$ch = curl_init("http://www.111cn.net/");
curl_exec($ch);
curl_close($ch);
//$ch = curl_init("要采集的网址"); curl_init()函数的作用初始化一个curl会话
//curl_exec($ch);执行$ch
//curl_close($ch); 关闭$ch
|
file_get_contents函数
例子
代码如下 |
复制代码 |
<?php
echo file_get_contents("http://www.111cn.net");
?> |
输出:
代码如下 |
复制代码 |
This is a test file with test text.
|
总结
fopen / file_get_contents 每次请求都会重新做DNS查询,并不对DNS信息进行缓存。
但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。
所以CURL的性能比fopen / file_get_contents 好很多。
file_get_contents与curl效率及稳定性问题
代码如下 |
复制代码 |
$config['context'] = stream_context_create(array('http' => array('method' => "GET",'timeout' => 5)));
|
'timeout' => 5//这个超时时间不稳定,经常不好使。这时候,看一下服务器的连接池,会发现一堆类似下面的错误,让你头疼万分:
代码如下 |
复制代码 |
file_get_contents(http://***): failed to open stream… |
不得已,安装了curl库,写了一个函数替换:
代码如下 |
复制代码 |
function curl_get_contents($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //设置访问的url地址
//curl_setopt($ch,CURLOPT_HEADER,1); //是否显示头部信息
curl_setopt($ch, CURLOPT_TIMEOUT, 5); //设置超时
curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_); //用户访问代理 User-Agent
curl_setopt($ch, CURLOPT_REFERER,_REFERER_); //设置 referer
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); //跟踪301
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回结果
$r = curl_exec($ch);
curl_close($ch);
return $r;
}
|
如此,除了真正的网络问题外,没再出现任何问题。
这是别人做过的关于curl和file_get_contents的测试:
file_get_contents抓取google.com需用秒数:
代码如下 |
复制代码 |
1.2.31319094
2.2.30374217
3.2.21512604
4.3.30553889
5.2.30124092
curl使用的时间:
1.0.68719101
2.0.64675593
3.0.64326
4.0.81983113
5.0.63956594
|
那么如何根据服务器情况来使用file_get_contents还是curl()呢,下面我们可以利用function_exists函数来判断php是否支持一个函数可以轻松写出下面函数
代码如下 |
复制代码 |
< ?php
function vita_get_url_content($url) {
if(function_exists('file_get_contents')) {
$file_contents = file_get_contents($url);
} else {
$ch = curl_init();
$timeout = 5;
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$file_contents = curl_exec($ch);
curl_close($ch);
}
return $file_contents;
}
?>
|
在php中将html标签转换成纯文本的方法有不少,像php自带了函数strip_tags它就可以把html直接转换在纯文本文格式了,下面我来具体来看看各种转换代码。
先来看strip_tags()函数用法
下面的例子删除<a>标记之外的所有标记:
代码如下 |
复制代码 |
<!--?php <br ?--> $input = "This <a href="http://www.111cn.net/">example</a>
is <strong>yanshare</strong>!";
echo strip_tags($input, "<a>");
?>
</a>
输入结果
This <a href="http://www.111cn.net/">example</a>
is yanshare!
|
这里就连接连接与连接中的内容都过滤掉了,我们如果想保留A中的内容可以参考下面代码
strip_tags有一个可选的参数allowable_tags指定在此过程中可以跳过的标记。下面的例子使用了strip_tags()删除字符串中的所以HTML标记:
代码如下 |
复制代码 |
<!--?php <br ?--> $input = "Email <a href="example@example.com">example@example.com</a>";
echo strip_tags($input);
?>
这回返回以下结果:
Email example@example.com
|
一个自定义的将html转换为无html标签的字符集,返回转换好的字符串
代码如下 |
复制代码 |
function html2text($str){
$str = preg_replace("/<style .*?</style>/is", "", $str); $str = preg_replace("/<script .*?</script>/is", "", $str);
$str = preg_replace("/<br s*/?/>/i", "n", $str);
$str = preg_replace("/</?p>/i", "nn", $str);
$str = preg_replace("/</?td>/i", "n", $str);
$str = preg_replace("/</?div>/i", "n", $str);
$str = preg_replace("/</?blockquote>/i", "n", $str);
$str = preg_replace("/</?li>/i", "n", $str);
$str = preg_replace("/ /i", " ", $str);
$str = preg_replace("/ /i", " ", $str);
$str = preg_replace("/&/i", "&", $str);
$str = preg_replace("/&/i", "&", $str);
$str = preg_replace("/</i", "<", $str);
$str = preg_replace("/</i", "<", $str);
$str = preg_replace("/“/i", '"', $str);
$str = preg_replace("/&ldquo/i", '"', $str);
$str = preg_replace("/‘/i", "'", $str);
$str = preg_replace("/&lsquo/i", "'", $str);
$str = preg_replace("/’/i", "'", $str);
$str = preg_replace("/&rsquo/i", "'", $str);
$str = preg_replace("/>/i", ">", $str);
$str = preg_replace("/>/i", ">", $str);
$str = preg_replace("/”/i", '"', $str);
$str = preg_replace("/&rdquo/i", '"', $str);
$str = strip_tags($str);
$str = html_entity_decode($str, ENT_QUOTES, "utf-8");
$str = preg_replace("/&#.*?;/i", "", $str);
return $str;
}
|
在php中要实现数组搜索方法有很多种,我知道最简单的就是in_array与遍历数组后再一个个对比,其它还有更多更好方法,下面我来介绍介绍。
一维数组搜索很简单in_array()
如果 value 参数是字符串,且 type 参数设置为 true,则搜索区分大小写
代码如下 |
复制代码 |
<?php
$people = array("Peter", "Joe", "Glenn", "Cleveland");
if (in_array("Glenn",$people))
{
echo "Match found";
}
else
{
echo "Match not found";
}
?>
输出:
Match found
|
array_key_exists()函数
如果在一个数组中找到一个指定的键,函数array_key_exists()返回true,否则返回false。其形式如下:
boolean array_key_exists(mixed key,array array);
下面的例子将在数组键中搜索apple,如果找到,将输出这个水果的颜色:
代码如下 |
复制代码 |
$fruit["apple"] = "red";
$fruit["banana"] = "yellow";
$fruit["pear"] = "green";
if(array_key_exists("apple", $fruit)){
printf("apple's color is %s",$fruit["apple"]);
}
//apple's color is red
|
array_search()函数
array_search()函数在一个数组中搜索一个指定的值,如果找到则返回相应的键,否则返回false。其形式如下:
mixed array_search(mixed needle,array haystack[,boolean strict])
下面的例子在$fruits中搜索一个特定的日期(December 7),如果找到,则返回相应州的有关信息:
代码如下 |
复制代码 |
$fruits["apple"] = "red";
$fruits["banana"] = "yellow";
$fruits["watermelon"]="green";
$founded = array_search("green", $fruits);
if($founded)
printf("%s was founded on %s.",$founded, $fruits[$founded]);
//watermelon was founded on green.
|
array_keys()函数
array_keys()函数返回一个数组,其中包含所搜索数组中找到的所有键。其形式如下:
array array_keys(array array[,mixed search_value])
如果包含可选参数search_value,则只会返回与该值匹配的键。下面的例子将输出$fruit数组中找到的所有数组:
代码如下 |
复制代码 |
$fruits["apple"] = "red";
$fruits["banana"] = "yellow";
$fruits["watermelon"]="green";
$keys = array_keys($fruits);
print_r($keys);
//Array ( [0] => apple [1] => banana [2] => watermelon )
|
array_values()函数
array_values()函数返回一个数组中的所有值,并自动为返回的数组提供数值索引。其形式如下:
array array_values(array array)
下面的例子将获取$fruits中找到的各元素的值:
代码如下 |
复制代码 |
$fruits["apple"] = "red";
$fruits["banana"] = "yellow";
$fruits["watermelon"]="green";
$values = array_values($fruits);
print_r($values);
//Array ( [0] => red [1] => yellow [2] => green )
|
上面讲到的都只是一维数组搜索了,如果要实现二维数据或多维数据我们可参考下面实例
1 php搜索多维数组的键值
如下面例子:
代码如下 |
复制代码 |
$foo[1]['a']['xx'] = 'bar 1';
$foo[1]['b']['xx'] = 'bar 2';
$foo[2]['a']['bb'] = 'bar 3';
$foo[2]['a']['yy'] = 'bar 4';
$foo[3]['c']['dd'] = 'bar 3';
$foo[3]['f']['gg'] = 'bar 3';
$foo['info'][1] = 'bar 5';
如果要查找 bar 3 怎么进行查找呢。有三个结果,而这三个结果都要,看下面的函数:
-------------------------------------------------------------------------------------------------------------------------------
function array_search_re($needle, $haystack, $a=0, $nodes_temp=array()){
global $nodes_found;
$a++;
foreach ($haystack as $key1=>$value1) {
$nodes_temp[$a] = $key1;
if (is_array($value1)){
array_search_re($needle, $value1, $a, $nodes_temp);
}
else if ($value1 === $needle){
$nodes_found[] = $nodes_temp;
}
}
return $nodes_found;
}
---------------------------------------------------------------------------------------------------------------------------------
这个函数就可以把上面要查找到的内容全部返回出键名来
$result = array_search_re('bar 3', $foo);
print_r($result);
输出结果为如下:
Array ( [0] => Array ( [1] => 2 [2] => a [3] => bb )
[1] => Array ( [1] => 3 [2] => c [3] => dd )
[2] => Array ( [1] => 3 [2] => f [3] => gg )
)
|
php搜索多维数组的键名
代码如下 |
复制代码 |
function array_search_key($needle, $haystack){
global $nodes_found;
foreach ($haystack as $key1=>$value1) {
if ($key1=== $needle){
$nodes_found[] = $value1;
}
if (is_array($value1)){
array_search_key($needle, $value1);
}
}
return $nodes_found;
}
$result = array_search_key('a', $foo);
print_r($result);
输出结果为如下:
Array
(
[0] => Array
(
[xx] => bar 1
)
[1] => Array
(
[bb] => bar 3
)
[2] => Array
(
[yy] => bar 4
)
)
|
一篇php中匹配邮箱地址正则表达式实例,邮箱地址替换正则我常用的正则匹配表达式:/^[a-z]([a-z0-9]*[-_]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\\.][a-z]{2,3}([\\.][a-z]{2})?$/i,下面来详细分析有需要的朋友可参考。
php例
下面以PHP为例进行说明:
代码如下 |
复制代码 |
< ?php
if (ereg(“/^[a-z]([a-z0-9]*[-_.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[.][a-z]{2,3}([.][a-z]{2})?$/i; ”,$email))
{
echo “Your email address is correct!”;
}
else
{
echo “Please try again!”;
}
?> |
说明:
①/内容/i 构成一个不区分大小写的正则表达式;^ 匹配开始;$ 匹配结束。
②[a-z] E-Mail前缀必需是一个英文字母开头
③([a-z0-9]*[-_]?[a-z0-9]+)* 和_a_2、aaa11、_1_a_2匹配,和a1_、aaff_33a_、a__aa不匹配,如果是空字符,也是匹配的,*表示0个或者多个。
④*表示0个或多个前面的字符.
⑤[a-z0-9]* 匹配0个或多个英文字母或者数字;[-_]? 匹配0个或1“-”,因为“-”不能连续出现。
⑥[a-z0-9]+ 匹配1个或多个英文字母或者数字,因为“-”不能做为结尾
⑦@ 必需有个有@
⑧([a-z0-9]*[-_]?[a-z0-9]+)+ 见上面([a-z0-9]*[-_]?[a-z0-9]+)*解释,但是不能为空,+表示一个或者为多个。
⑨[.] 将特殊字符(.)当成普通字符;[a-z]{2,3} 匹配2个至3个英文字母,一般为com或者net等。
⑩([.][a-z]{2})? 匹配0个或者1个[.][a-z]{2}(比如.cn等) 我不知道一般.com.cn最后部份是不是都是两位的,如果不是请修改{2}为{起始字数,结束字数}
js例
代码如下 |
复制代码 |
<script>
function Email(ee){
var emailreg = "^\w+@\w+\.\w+(\.\w+)*$";
var rege = new RegExp(emailreg, 'g');
alert(rege.test(ee));
}
var ee1 = "12xwz@123e^rsrf6.csdfdfom.df";
var ee2 = "12xwz@123ersrf6.csdfdfom.df";
Email(ee1);
Email(ee2);
</script>
|
为了让你更好的掌握正则,请学习字符串转义形式
这里,你用字符串表示正则,转义符要用\表示,如果要匹配则要用\
^\w+@\w+\.\w+(\.\w+)*$
开始是w word有一个或多个
@后
是一个word
.后是一个word有一个或多个
(\.\w+)*可以没有或多个
要遍历一个文件夹里面的所有目录,列出里面所有的文件,PHP本身自带的有一个readdir的函数,不过只能读取当前的目录,根据这个函数,我写了另外一个函数,用来实现我的需求。
代码如下 |
复制代码 |
<?php
class listdir{
var $depth;
var $dirname;
var $list;
var $tostring;
function listdir($dir){
$this->dirname=$dir;
$this->depth=0;
$this->tostring=”";
}
//把结果保存进多维数组
function getlist($dir=”"){
if($dir==”")$dir=$this->dirname;
$d=@dir($dir);
while(false!==($item=$d->read()))
{
if($item!=”.”&&$item!=”..”)
{
$path=$dir.”/”.$item;
if(is_dir($path)){
$this->depth+=1;
$this->getlist($path);
}else{
$this->list[$this->depth][]=$item;
}
}
}
$this->list[$this->depth]['directory']=$dir;
$this->depth-=1;
$d->close();
return $this->list;
}
//字符窜化结果
function tostring($dir=”"){
if($dir==”")$dir=$this->dirname;
$d=@dir($dir);
$this->tostring.=”<UL>n”;
$this->tostring.=”Directory:”.$dir.”n”;
while(false!==($item=$d->read()))
{
if($item!=”.”&&$item!=”..”)
{
$path=$dir.”/”.$item;
if(is_dir($path)){
$this->depth+=1;
$this->tostring($path);
}else{
$this->tostring.=”<LI>”.$item.”</LI>n”;
}
}
}
$this->depth-=1;
$d->close();
$this->tostring.=”</UL>n”;
return $this->tostring;
}
}
$wapdir=”jquery”;
$d=new listdir($wapdir);
echo $d->tostring();
?>
|
要删除一个空的目录很简单~一个
rmdir() 函数就可以搞定,但是要删除一个非空目录,将不能进行快速的删除,必须先将目录中文件删除,但是目录里可能还会有子目录所以要进行递归删除~下面是我的例子~
代码如下 |
复制代码 |
<?php
function deletedir($dir){
if(!handle=@opendir($dir)){ //检测要打开目录是否存在
die("没有该目录");
}
while(false !==($file=readdir($handle))){
if($file!=="."&&$file!==".."){ //排除当前目录与父级目录
$file=$dir .DIRECTORY_SEPARATOR. $file;
if(is_dir($file)){
deletedir($file);
}else{
if(@unlink($file)){
echo "文件<b>$file</b>删除成功。<br>";
}else{
echo "文件<b>$file</b>删除失败!<br>";
}
}
}
if(@rmdir($dir)){
echo "目录<b>$dir</b>删除成功了。<br>n";
}else{
echo "目录<b>$dir</b>删除失败!<br>n";
}
}
//测试程序
$dir="/var/www/test";
deletedir($dir);
?> |
标签:[!--infotagslink--]