php+jquery Ajax异步上传图片(ajaxSubmit)实例

 更新时间:2016年11月25日 16:20  点击:2376
下面我们一起来看一个php+jquery Ajax异步上传图片(ajaxSubmit)实例,这个我们真正的利用了ajax而不是使用iframe之类的哦。

效果如下

 代码如下 复制代码

index.php文件

php结合jquery异步上传图片(ajaxSubmit),以下为提交页面代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax异步上传图片</title>
<script src="js/jquery-1.4.2.js" language="JavaScript" type="text/javascript"></script>
<script src="js/jquery.form.js" language="JavaScript" type="text/javascript"></script>
<script type="text/javascript">

function sky_upfiles(){
    var messtxt;
 $("#sky_upform").ajaxSubmit({
                                //dataType:'script',
                                type:'post',
                                url: "doupfiles.php",   
                                beforeSubmit: function(){
                                    $("#sky_txt").html("图片上传中...");
                                },
                                success: function(data){       
                                    if(data=="1"){
                                    messtxt = "上传成功!";
                                    }else if(data=="-1"){
                                    messtxt = "文件超过规定大小!";
                                    }else if(data=="-2"){
                                    messtxt = "文件类型不符!";
                                    }else if(data=="-3"){
                                    messtxt = "移动文件出错!";
                                    }else{
                                    messtxt = "未知错误!";
                                    }
                                    $("#sky_txt").html(messtxt);               
                                    //$("#sky_txt").append(data);
                                },
                                resetForm: false,
                                clearForm: false
                        });
                        //$("#upimgform").submit();
}

        </script>
</head>
<body>
<br />
<fieldset style="width:97%">
  <legend>上传文件</legend>
    <form enctype="multipart/form-data" id="sky_upform" name="sky_upform" action="" method="post">
    <table width="100%" border="0" align="center" cellpadding="3" cellspacing="0">
      <tr>
        <td width="100" align="right" class="f-12"></td>
        <td class="f-12" align="left">
        <input name="upfile" id="upfile" maxlength="20" size="40" type="file" value="" /><input name="upmit" type="button" id="upmit" value="上传" onclick="sky_upfiles()"/>
        <font color="red" id="sky_txt"></font></td>
      </tr>      
    </form>
       
</body>
</html>

doupfiles.php文件

 代码如下 复制代码

<?php
/*
 * 1:成功上传
 *-1:文件超过规定大小
 *-2:文件类型不符
 *-3:移动文件出错
 */
if(is_uploaded_file($_FILES['upfile']['tmp_name'])){

 $photo_types=array('image/jpg', 'image/jpeg','image/png','image/pjpeg','image/gif','image/bmp','image/x-png');//定义上传格式
        $max_size=700000;    //上传照片大小限制,默认700k
        $photo_folder="upload/".date("Y")."/".date("m")."/".date("d")."/"; //上传照片路径
        ///////////////////////////////////////////////////开始处理上传
        if(!file_exists($photo_folder))//检查照片目录是否存在
        {
            mkdir($photo_folder, 0777, true);  //mkdir("temp/sub, 0777, true);
        }

$upfile=$_FILES['upfile'];
$name=$upfile['name'];
$type=$upfile['type'];
$size=$upfile['size'];
$tmp_name=$upfile['tmp_name'];

$file = $_FILES["upfile"];
$photo_name=$file["tmp_name"];
//echo $photo_name;
$photo_size = getimagesize($photo_name);

if($max_size < $file["size"])//检查文件大小
           echo "-1";       //echo "<script>alert('对不起,文件超过规定大小!');history.go(-1);</script>";
if(!in_array($file["type"], $photo_types))//检查文件类型
           echo "-2";       //echo "<script>alert('对不起,文件类型不符!');history.go(-1);</script>";
if(!file_exists($photo_folder))//照片目录
                  mkdir($photo_folder);
$pinfo=pathinfo($file["name"]);
$photo_type=$pinfo['extension'];//上传文件扩展名
$photo_server_folder = $photo_folder.time().".".$photo_type;//以当前时间和7位随机数作为文件名,这里是上传的完整路径


if(!move_uploaded_file ($photo_name, $photo_server_folder))
            {
             echo "-3"; //echo "移动文件出错";
                exit;
            }
$pinfo=pathinfo($photo_server_folder);
$fname=$pinfo['basename'];
echo "1";   //echo " 已经成功上传:".$photo_server_folder."<br />";

 


}
?>

最后把完整的php+jquery Ajax异步上传图片(ajaxSubmit)实例源码下载地址

 

下面一起来看一个PHP基于二分法的手机号码归属查询与传统查询效率比较,希望文章对各位要求性能高的朋友会提供不错的参考价值.

出于对算法对于系统的影响的好奇,决定实验性的在实际生产环境中研究一下算法对系统效率的影响。二分法最重要的是对有序数据的查询定位,例如手机号码就是一个很贴切的有序排列的数据例子。
如果数据量很小,例如只有10条有序数据,要查询其中的第9条数据,轮询查询需要查询9次确定结果,二分法查询次数为3次(分别是匹配第5、8、9条记录)即可确定结果。数据量越大,二分法所带来的效率就是程2的阶乘递增,可以大大提升服务器的运行效率、提升用户等待时间、节省服务器资源。
实验环境:LAMP
实验数据:国内手机号码归属地。手机号码前7位代表一个号段,生成从1300000到1590000之间的所有号段按从小到大排列,大约30万条数据。
传统查询:对于任意手机号码,截取前7位,从数据库中第一条记录开始循环向下匹配,如果对照,则返回查询结果。

 代码如下 复制代码
flock($fp,LOCK_SH);
$note = fread($fp,filesize('./data.php')); //读取数据
fclose($fp);
$note = explode("n",$note);
array_pop($note);
array_shift($note);
$num = count($note);
$_data = '';
//循环查询开始
for($i=1;$i<$num;$i++){
$row = explode(" ",$note[$i]);
if($m == $row[0]){
$_data = $row;
break;
}
}

实测结果:最快0.03512秒、最慢0.63043秒、平均查询用时约为0.4秒。

二分法查询:对于任意手机号码,截取前7位。首先匹配数据库中最中间的第100000条数据,根据二分法原则,若匹配结果比中间值大,重新选择第二次匹配第100000到200000的中间值----第150000条数据。以此类推,直到查询到最后一位正确的值返回结果。那么每次的查询次数小于或等于17次。

 代码如下 复制代码

flock($fp,LOCK_SH);
$note = fread($fp,filesize('./data.php')); //读取数据
fclose($fp);
$note = explode("n",$note);
array_pop($note);
array_shift($note);
$num = count($note); //统计数据库总记录数
$_data = '';
$low = 0; //二分法两端点变量
$hight = $num;
while($m < 1599999){
$num = ceil(($hight + $low)/2);
$row = explode(" ",$note[$num]);
if ($m == $row[0]){
return $_data = $row;
break;
}else{
$m >= $row[0] ? $low = $num : $hight = $num;
}
}

实测结果:每次查询都在0.034—0.035之间。

结论:本试验可以看出,二分法数据查询效率比传统效率快10倍以上。本实验数据只有30万条,在普通的应用性数据查询时,数据量越大,越能显示出二分法的优越性(理论上讲,上千万的数据查询次数不超过30次便可准确定位),在更大量的数据的时候,查询效率或许能真的给人直观的反应。

一篇用php实现memcache缓存实例详解,这里利用了很多我们以前可能很少使用到的可用扩展,在php中共享内存也一样。使用一些共享的函数,无需安装任何扩展,开发人员就能够轻松操作内存段。

概述
共享内存是一种在相同机器中的应用程序之间交换数据的有效方式。一个进程可创建一个可供其他进程访问的内存段,只要它分配了正确的权限。每个内存段拥有一个惟一的 ID(称为 shmid),这个 ID 指向一个物理内存区域,其他进程可在该区域操作它。创建并提供了合适的权限之后,同一台机器中的其他进程就可以操作这些内存段:读取、写入和删除。

这表明使用 C 语言编写的应用程序可与使用其他语言(比如 Java™ 或 PHP)编写的应用程序共享信息。它们都可以共享信息,只要它们可访问和理解该信息。共享内存在针对大部分语言的实现中得到了广泛使用,所以访问应该不是问题。要理解信息,我们可以使用一种标准格式,比如 XML 或 JSON。

共享内存的使用是一种在进程之间交换数据的快速方法,主要因为在创建内存段之后传递数据,不会涉及内核。这种方法常常称为进程间通信 (IPC)。其他 IPC 方法包括管道、消息队列、RPC 和套接字。当使用需要彼此通信的应用程序的生态系统时,这种在应用程序之间快速、可靠地交换数据的能力非常有用。取决于生态系统的大小,使用数据库在应用程序之间交换信息的常用方法常常会导致查询缓慢,甚至 I/O 阻塞。使用共享内存,没有 I/O 会减缓开发人员的进度。

本文的提议非常简单,学习如何使用 PHP 创建和操作共享内存段,使用它们存储可供其他应用程序使用的数据集。即使没有使用共享内存交换数据的计划,它本身也在许多好处,因为它使应用程序能够远离 I/O 问题。将数据集直接存储在内存中具有诸多优势,从 Web 服务数据缓存到会话共享。它是一个非常有用的概念,每个 PHP 开发人员都应该知道。

共享内存和 PHP
PHP 拥有丰富的可用扩展,共享内存也一样。使用一些共享的函数,无需安装任何扩展,开发人员就能够轻松操作内存段。

回页首

创建内存段
共享内存函数类似于文件操作函数,但无需处理一个流,您将处理一个共享内存访问 ID。第一个示例就是 shmop_open 函数,它允许您打开一个现有的内存段或创建一个新内存段。此函数非常类似于经典的 fopen 函数,后者打开用于文件操作的流,返回一个资源供其他希望读取或写入该打开的流的函数使用。让我们看看清单 1 中的 shmop_open。

清单 1. shmop_open 函数

 代码如下 复制代码

<?php

$systemid = 864; // System ID for the shared memory segment
$mode = "c"; // Access mode
$permissions = 0755; // Permissions for the shared memory segment
$size = 1024; // Size, in bytes, of the segment

$shmid = shmop_open($systemid, $mode, $permissions, $size);

?>

该函数中出现的第一个事物是系统 ID 参数。这是标识系统中的共享内存段的数字。第二个参数是访问模式,它非常类似于 fopen 函数的访问模式。您可以在 4 种不同的模式下访问一个内存段:

•模式 “a”,它允许您访问只读内存段
•模式 “w”,它允许您访问可读写的内存段
•模式 “c”,它创建一个新内存段,或者如果该内存段已存在,尝试打开它进行读写
•模式 “n”,它创建一个新内存段,如果该内存段已存在,则会失败
第三个参数是内存段的权限。您必须在这里提供一个八进制值。

第四个参数提供内存段大小,以字节为单位。在写入一个内存段之前,您必须在它之上分配适当的字节数。

请注意,此函数返回一个 ID 编号,其他函数可使用该 ID 编号操作该共享内存段。这个 ID 是共享内存访问 ID,与系统 ID 不同,它以参数的形式传递。请注意不要混淆这两者。如果失败,shmop_open 将返回 FALSE。

回页首

向内存段写入数据
使用 shmop_write 函数向共享内存块写入数据。此函数的使用很简单,它仅接受 3 个参数,如清单 2 所示。

清单 2. 使用 shmop_write 向共享内存块写入数据

 代码如下 复制代码

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);

?>

这个函数类似于 fwrite 函数,后者有两个参数:打开的流资源(由 fopen 返回)和您希望写入的数据。shmop_write 函数也执行此任务。

第一个参数是 shmop_open 返回的 ID,它识别您操作的共享内存块。第二个参数是您希望存储的数据,最后的第三个参数是您希望开始写入的位置。默认情况下,我们始终使用 0 来表示开始写入的位置。请注意,此函数在失败时会返回 FALSE,在成功时会返回写入的字节数。

回页首

从内存段读取数据
从共享内存段读取数据很简单。您只需要一个打开的内存段和 shmop_read 函数。此函数接受一些参数,工作原理类似于 fread。参见清单 3,读取一个 PHP 文件的内容。

清单 3. 使用 shmop_read 读取一个文件的内容

 代码如下 复制代码

<?php

$stream = fopen('file.txt', 'r+');
fwrite($stream, "Hello World!");
echo fread($stream, 11);

?>

读取共享内存段的内容的过程与此类似,如清单 4 所示:

清单 4. 读取共享内存段的内容

 代码如下 复制代码

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);
echo shmop_read($shmid, 0, 11);

?>

请留意这里的参数。shmop_read 函数将接受 shmop_open 返回的 ID,我们已知道它,不过它还接受另外两个参数。第二个参数是您希望从内存段读取的位置,而第三个是您希望读取的字节数。第二个参数可以始终为 0,表示数据的开头,但第三个参数可能存在问题,因为我们不知道我们希望读取多少字节。

这非常类似于我们在 fread 函数中的行为,该函数接受两个参数:打开的流资源(由 fopen 返回)和您希望从该流读取的字节数。使用filesize 函数(它返回一个文件中的字节数)来完整地读取它。

幸运的是,当使用共享内存段时,shmop_size 函数返回一个内存段的大小(以字节为单位),类似于 filesize 函数。参见清单 5。

清单 5. shmop_size 函数返回内存段大小,以字节为单位

 代码如下 复制代码

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);

$size = shmop_size($shmid);
echo shmop_read($shmid, 0, $size);

?>

回页首

删除内存段
我们学习了如何打开、写入和读取共享内存段。要完成我们的 CRUD 类,我们还需要学习如何删除内存段。该任务可使用 shmop_delete 函数轻松完成,该函数仅接受一个参数:我们希望删除的共享内存 ID。

清单 6. shmop_delete 标记要删除的内存段

 代码如下 复制代码

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);
shmop_delete($shmid);

?>

这不会实际删除该内存段。它将该内存段标记为删除,因为共享内存段在有其他进程正在使用它时无法被删除。shmop_delete 函数将该内存段标记为删除,阻止任何其他进程打开它。要删除它,我们需要关闭该内存段。

回页首

关闭内存段
打开一个共享内存段会 “附加” 到它。附加该内存段之后,我们可在其中进行读取和写入,但完成操作后,我们必须从它解除。这使用清单 7 中的 shmop_close 函数来完成。

这非常类似于处理文件时的 fclose 函数。打开包含一个文件的流并在其中读取或写入数据后,我们必须关闭它,否则将发生锁定。

清单 7. 使用 shmop_close 与一个内存段分开

 代码如下 复制代码

<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);
shmop_delete($shmid);
shmop_close($shmid);

?>

回页首

使用共享内存作为一个存储选项
有了共享内存和共享内存段上基本 CRUD 操作的基本知识,是时候应用此知识了。我们可以使用共享内存作为一种独特的存储选项,提供快速读/写操作和进程互操作性等优势。对于 Web 应用程序,这意味着:

•缓存存储(数据库查询、Web 服务数据、外部数据)
•会话存储
•应用程序之间的数据交换
在继续之前,我想介绍一个名为 SimpleSHM 小型库。SimpleSHM 是一个较小的抽象层,用于使用 PHP 操作共享内存,支持以一种面向对象的方式轻松操作内存段。在编写使用共享内存进行存储的小型应用程序时,这个库可帮助创建非常简洁的代码。要了解 SimpleSHM,请访问GitHub 页面。

您可以使用 3 个方法进行处理:读、写和删除。从该类中简单地实例化一个对象,可以控制打开的共享内存段。清单 8 展示了基本用途。

清单 8. SimpleSHM 基本用途

 代码如下 复制代码

<?php

$memory = new SimpleSHM;
$memory->write('Sample');
echo $memory->read();

?>

请注意,这里没有为该类传递一个 ID。如果没有传递 ID,它将随机选择一个编号并打开该编号的新内存段。我们可以以参数的形式传递一个编号,供构造函数打开现有的内存段,或者创建一个具有特定 ID 的内存段,如清单 9 所示。

清单 9. 打开一个特定的内存段

 代码如下 复制代码

<?php

$new = new SimpleSHM(897);
$new->write('Sample');
echo $new->read();

?>

神奇的方法 __destructor 负责在该内存段上调用 shmop_close 来取消设置对象,以与该内存段分离。我们将这称为 “SimpleSHM 101”。现在让我们将此方法用于更高级的用途:使用共享内存作为存储。存储数据集需要序列化,因为数组或对象无法存储在内存中。尽管这里使用了 JSON 来序列化,但任何其他方法(比如 XML 或内置的 PHP 序列化功能)也已足够。清单 10 给出了一个示例。

清单 10. 使用共享内存作为存储

 代码如下 复制代码

<?php

require('SimpleSHM.class.php');

$results = array(
 'user' => 'John',
 'password' => '123456',
 'posts' => array('My name is John', 'My name is not John')
);

$data = json_encode($results);

$memory = new SimpleSHM;
$memory->write($data);
$storedarray = json_decode($memory->read());

print_r($storedarray);

?>

我们成功地将一个数组序列化为一个 JSON 字符串,将它存储在共享内存块中,从中读取数据,去序列化 JSON 字符串,并显示存储的数组。这看起来很简单,但请想象一下这个代码片段带来的可能性。您可以使用它存储 Web 服务请求、数据库查询或者甚至模板引擎缓存的结果。在内存中读取和写入将带来比在磁盘中读取和写入更高的性能。

使用此存储技术不仅对缓存有用,也对应用程序之间的数据交换也有用,只要数据以两端都可读的格式存储。不要低估共享内存在 Web 应用程序中的力量。可采用许多不同的方式来巧妙地实现这种存储,惟一的限制是开发人员的创造力和技能

一个RTXServer web api接口的小实例,最后返回的是xml文件,与其它的区别不大,有兴趣的同学可参考学习。

109天没发表博客,破了记录,至从换了公司后就没有机会使用CI,重要的原因是自己懒惰了,下班后的时间几乎都在玩吉他,所以一直没有找到可以分享的技术点

不过在这109天里可以肯定的事情是:我变了

在新公司接触得最多的是oa与RTX,而RTX其实也是很多玩法,这里就先将前几天趁空闲的时间整理下来的RTX可以通过web方式调用的接口列一下


 

值得提醒的是这些接口都需要设置访问权限不然访问时会提醒“IP受限制”

RTX Server强加了SDK访问安性,因此通过http方式访问cgi文件需要在SDKProperty.xml添加远程访问机器的IP地址,如下图所示,允许192.168.10.100通过http方式访问cgi文件

 


以下为所有接口的清单,你也可以访问这个地方来查看相关的API http://iamlze.cn/demo/RTX-API/

GetImage.cgi
获取指定用户的状态图片

仅支持GET传值

@param string receiver RTX用户名

@return 用户状态图片

@example http://localhost:8012/GetImage.cgi?receiver=XXXX

GetMobile.cgi
获取指定用户的手机号码

支持GET与POST传值

@param string receiver RTX用户名

@return 用户手机

@example http://localhost:8012/GetMobile.cgi?receiver=XXXX

GetSession.cgi
获取指定用户的RTX session

支持GET与POST传值

@param string receiver RTX用户名

@return RTX用户session

@example http://localhost:8012/GetSession.cgi?receiver=XXXX

GetAllDepts.php
获取RTX所有部门数据

@return 所有部门数据(json)

@example http://localhost:8012/GetAllDepts.php

GetAllUsers.php
获取RTX所有用户数据

@return 所有用户数据(json)

@example http://localhost:8012/GetAllUsers.php

GetUserBasicInfo.php
获取指定用户基本信息

仅支持GET

@param string user RTX用户名

@return 所有用户数据(json)

@example http://localhost:8012/GetUserBasicInfo.php?user=XXXX

Login.php
判断指定用户ID与密码是否存在RTXserver中

仅支持GET

@param string user RTX用户名

@param string pwd RTX密码

@return string 正确输出true 用户或密码错误输出false 参数缺失输出params is null

@example http://localhost:8012/Login.php?user=XXXX&pwd=XXXX

SendIM.cgi
发送IM信息

支持GET与POST传值 参数顺序随意

@param string sender 发消息人RTXid

@param string pwd 发送消息人RTX密码

@param string receivers 接收人(多个接收人之间使用,隔开)

@param string msg 消息内容

@param string sessionid RTX session

@return string

@example http://localhost:8012/SendIM.cgi?sender=XXXX&pwd=XXX&receivers=A;B&msg=CS么&sessionid=XXXX

SendNotify.cgi
发送通知信息

支持GET与POST传值 参数顺序随意

@param string title 通知标题

@param string msg 通知内容

@param string receiver 接收人(多个接收人之间使用,隔开,若为空表示广播)[option]

@param int delaytime 消息提醒框的停留时间(毫秒),0表示不自动消失

@param string okurl 成功后IE自动定位到指定的url 格式类似为:okurl=rtx.tencent.com 或者okurl=http://tx.tencent.com 注意:这里的url必须为绝对地址[option]

@param string errurl 失败后IE自动定位到指定的url[option]

@example http://localhost:8012/SendNotify.cgi?title=XXXX&msg=吃饭了&receiver=A;B&delaytime=2000

SendSMS.cgi
发送短信信息

支持GET与POST传值 参数顺序随意

@param string msg 短信内容

@param string receiver 接收人(多个接收人之间使用,隔开)

@param string sender 发送人

@param string okurl 成功后IE自动定位到指定的url 格式类似为:okurl=rtx.tencent.com 或者okurl=http://tx.tencent.com 注意:这里的url必须为绝对地址[option]

@param string errurl 失败后IE自动定位到指定的url[option]

@example http://localhost:8012/SendNotify.cgi?title=XXXX&msg=吃饭了&receiver=A;B&delaytime=2000

SignAuth.cgi
验证签名 仅支持GET 参数顺序随意

@param string user RTX用户ID

@param string sign 签名

@return string 成功为success! 失败为failed!

@example http://localhost:8012/SignAuth.cgi?user=XXXX&sign=XXXX

getstatus.php
获取用户在线状态仅支持GET

@param string username RTX用户名

@return int 0不在线 1在线

@example http://localhost:8012/getstatus.php?username=XXXX

userlist.php
获取所有用户列表(只含id与name)

@return string 用户列表(json)

@example http://localhost:8012/userlist.php

在php中如果不仔细的去分析性能会发现file_get_contents与curl两个同很多共同点的,他们都可以采集文件打开文件,但是如果仔细一对比会发现很多不同点,下面我们一起来看看file_get_contents与curl区别。

PHP中fopen,file_get_contents,curl函数的区别:

1.fopen /file_get_contents 每次请求都会重新做DNS查询,并不对 DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen /file_get_contents 好很多。

2.fopen /file_get_contents 在请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。


3.fopen / file_get_contents 函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了,则该函数也就失效了。而curl不受该配置的影响。


4.curl 可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而fopen / file_get_contents只能使用get方式获取数据。

file_get_contents 获取远程文件时会把结果都存在一个字符串中 fiels函数则会储存成数组形式
因此,我还是比较倾向于使用curl来访问远程url。Php有curl模块扩展,功能很是强大。

说了半天大家可能说性能怎么没对比呢,那我们就来看看


最近需要获取别人网站上的音乐数据。用了file_get_contents函数,但是总是会遇到获取失败的问题,尽管按照手册中的 例子设置了超时,可多数时候不会奏效:

 

 代码如下 复制代码
$config['context'] = stream_context_create(array(‘http’ => array(‘method’ => “GET”,
   ’timeout’ => 5//这个超时时间不稳定,经常不奏效
   )
  ));

这时候,看一下服务器的连接池,会发现一堆类似的错误,让我头疼万分:

 代码如下 复制代码
file_get_contents(http://***): failed to open stream…

现在改用了curl库,写了一个函数替换:

 代码如下 复制代码
function curl_file_get_contents($durl){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $durl);
  curl_setopt($ch, CURLOPT_TIMEOUT, 5);
  curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);
  curl_setopt($ch, CURLOPT_REFERER,_REFERER_);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $r = curl_exec($ch);
  curl_close($ch);
   return $r;
}

如此,除了真正的网络问题外,没再出现任何问题。
这是别人做过的关于curl和file_get_contents的测试:
file_get_contents抓取google.com需用秒数:

 

2.31319094

2.30374217
2.21512604
3.30553889
2.30124092

curl使用的时间:

 

0.68719101

0.64675593
0.64326
0.81983113
0.63956594

差距很大?呵呵,从我使用的经验来说,这两个工具不只是速度有差异,稳定性也相差很大。

建议对网络数据抓取稳定性要求比较高的朋友使用上面的 curl_file_get_contents函数,不但稳定速度快,还能假冒浏览器欺骗目标地址哦


再看一个实例

后续贴出了curl和file_get_contents的对比结果,这边除了curl与file_get_contents的性能对比,还包含了他们的性能对比,讲之前看下如下的结果图:

curl与file_get_contents性能对比PHP源代码如下:

 代码如下 复制代码

<?php
/**
 
* 通过淘宝IP接口获取IP地理位置
 
* @param string $ip
 
* @return: string
 
**/
function getCityCurl($ip)
{
    $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
    $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);
 
    $ipinfo=json_decode($file_contents);
    if($ipinfo->code=='1'){
        return false;
    }
    $city = $ipinfo->data->region.$ipinfo->data->city;
    return $city;
}
 
function getCity($ip)
{
    $url="http://ip.taobao.com/service/getIpInfo.php?ip=".$ip;
    $ipinfo=json_decode(file_get_contents($url));
    if($ipinfo->code=='1'){
        return false;
    }
    $city = $ipinfo->data->region.$ipinfo->data->city;
    return $city;
}
 
// for file_get_contents
$startTime=explode(' ',microtime());
$startTime=$startTime[0] + $startTime[1];
for($i=1;$i<=10;$i++)
{
   echo getCity("121.207.247.202")."</br>";
}
$endTime = explode(' ',microtime());
$endTime = $endTime[0] + $endTime[1];
$totalTime = $endTime - $startTime;
echo 'file_get_contents:'.number_format($totalTime, 10, '.', "")." seconds</br>";
 
//for curl
$startTime2=explode(' ',microtime());
$startTime2=$startTime2[0] + $startTime2[1];
for($i=1;$i<=10;$i++)
{
   echo getCityCurl('121.207.247.202')."</br>";
}
$endTime2 = explode(' ',microtime());
$endTime2=$endTime2[0] + $endTime2[1];
$totalTime2 = $endTime2 - $startTime2;
echo "curl:".number_format($totalTime2, 10, '.', "")." seconds";
?>

测试访问

http://www.111cn.net

file_get_contents速度:4.2404510975 seconds
curl速度:2.8205530643 seconds

curl比file_get_contents速度快了30%左右,最重要的是服务器负载更低.

总结

file_get_contents处理频繁小的时候,用它感觉挺好的。没什么异常。如果你的文件被1k+人处理。那么你的服务器cpu就等着高升吧。所以建议自己和大家在以后写php代码的时候使用curl库。

 

[!--infotagslink--]

相关文章

  • php上传图片学习笔记与心得

    我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
  • php+jquery Ajax异步上传图片(ajaxSubmit)实例

    下面我们一起来看一个php+jquery Ajax异步上传图片(ajaxSubmit)实例,这个我们真正的利用了ajax而不是使用iframe之类的哦。 效果如下 ...2016-11-25
  • PHP:实现给上传图片加水印的程序代码

    用PHP给上传图片加水印的程序是通过判定文件类型建立图形,然后把其复制到原建立的图形上,填充并建立rectangle,以备写入imagestring()或是原已经定好的图像程序当中判定水...2016-11-25
  • vue实现上传图片添加水印

    这篇文章主要为大家详细介绍了vue实现上传图片添加水印,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-13
  • PHP上传图片时判断上传文件是否为可用图片的方法

    这篇文章主要介绍了PHP上传图片时判断上传文件是否为可用图片的方法,涉及php针对图片的后缀检测操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2016-11-01
  • 【帝国CMS插件】帝国CMS7.0图集批量上传插件 批量上传图片

    帝国CMS的图集上传一直是很蛋疼的事情。 猪先飞网以前发布过一款 图集批量上传插件 ,但可惜只支持6.6版。不支持7.0版。 而帝国CMS7.0版自2013年03月份发布以来,一直没有人放...2015-12-30
  • php检测上传图片的长度和宽度

    /* array getimagesize ( string $filename [, array &$imageinfo ] ) getimagesize()函数将确定任何给定的图像大小的文件,并返回随着文件类型和高度/宽度的文本字符串...2016-11-25
  • C#实现上传照片到物理路径,并且将地址保存到数据库的小例子

    这篇文章主要介绍了c#上传图片,并将地址保存到数据库中的简单实例,有需要的朋友可以参考一下...2021-09-22
  • 帝国7.0 多值字段修改为 可以上传图片的形式

    我们知道多值字段功能很强大,但不能上传图片确很操蛋,其实改吧改吧就可以了,只是帝国的大大们似乎不太注意这些小细节,只有靠自己来优化了。<script> function domvadd_ffff() {...2015-12-30
  • php+ajax实现带进度条的上传图片功能【附demo源码下载】

    这篇文章主要介绍了php+ajax实现带进度条的上传图片功能,涉及php文件传输及ajax无刷新提交的相关操作技巧,并附带demo源码供读者下载参考,需要的朋友可以参考下...2016-10-02
  • php ckeditor上传图片文件大小限制修改

    ckeditor编辑器在上传图片或文件时是没有大小限制的,下面我们来给大家介绍两种ckeditor上传图片文件大小限制问题解决办法。 一种可以通过修改PHP.INI配置文件上传...2016-11-25
  • PHP中FCK上传图片文件名乱码

    使用fck的朋友可能会碰这样一个情况就是如果上你的文件名为英文字母是没有任何问题,如果上传的是中文汉字就会出现中文名乱码了,下面我来给大家分析与介绍解决方法。...2016-11-25
  • thinkphp3.2实现上传图片的控制器方法

    这篇文章主要介绍了thinkphp3.2实现上传图片的控制器方法,结合实例形式分析了thinkPHP图片文件上传相关的文件类型判断,文件路径及相关属性操作技巧,需要的朋友可以参考下...2016-05-04
  • php ckeditor上传图片文件名乱码解决方法

    文件名乱码一般是中文导致的,因为ckeditor使用的是uft8编码如果我们页面使用的是gbk或gb2312就有可能出现乱码问题,解决办法只要对上传文件重命名即可。 打开editor...2016-11-25
  • CKeditor增加上传图片功能方法

    CKeditor可以配合CKfinder实现文件的上传及管理。但是往往我们上传的图片需要某些自定义的操作,比如将图片路径写入数据库,图片加水印等等操作。 实现原理:配置CKeditor...2016-09-20
  • jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象

    这篇文章主要介绍了jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象的相关资料,需要的朋友可以参考下...2016-01-25
  • asp.net MVC实现无组件上传图片实例介绍

    无组件实现上传图片使用input的file作为上传选择文件,具体实现如下:前后台代码很详细,感兴趣的朋友们可不要错过了哈...2021-09-22
  • PHP文件上传与上传图片加水印例子

    文章介绍的PHP文件上传与上传图片加水印例子是分开来写的了,先是介绍文件上传代码,而后介绍了一个上传图片加水印代码,大家可以整理成一个类来方便调用了。 先来看一...2016-11-25
  • Vue组件封装上传图片和视频的示例代码

    这篇文章主要介绍了Vue封装上传图片和视频的组件,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-07-31
  • swfupload ajax无刷新上传图片实例代码

    在这里上传图片就需要用到ajax无刷新上传图片,这里面包含的东西不是一点半点。这里用到的是一个插件swfupload实现无刷新上传图片,感兴趣的朋友可以参考下哈...2021-09-22