php中Curl函数常用的两个例子(登陆/soap)

 更新时间:2016年11月25日 16:20  点击:2266
curl在php中在性能方法要比较其它相同功能函数要高得多,下面我给大家介绍我自己常用的函数一个使用PHP curl 来做登陆后的抓取时使用;一个使用PHP curl来实现soap;我想你会感兴趣有哦。

例子, 模拟登陆

 代码如下 复制代码
/**
* 模拟登陆
* $url 请求地址
* $post 需要POST的数据
* $cookie 登陆时取的的COOKIE
* $cookiejar cookie要存到的位置 例如/tmp/test.cookie
* $referer 上页地址
*
**/
function vcurl($url, $post = '', $cookie = '', $cookiejar = '', $referer = ''){
$tmpInfo = '';
//用来存放cookie的文件
//初始化curl
$curl = curl_init();
//设定目标网址
curl_setopt($curl, CURLOPT_URL, $url);
//使用目前所用的浏览器代理
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
//curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
//如果有Ref参数,则设置Referer头,否则自动设置Referer头
if($referer) {
curl_setopt($curl, CURLOPT_REFERER, $referer);
} else {
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
}
//如果有post数据参数,则方法为POST,并且设置数据,否则为GET
if($post) {
//发送一个常规的POST请求,默认类型为:application/x-www-form-urlencoded,www.111cn.net表单提交
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
}
//如果有cookie参数,则设置
if($cookie) {
curl_setopt($curl, CURLOPT_COOKIE, $cookie);
}
//如果有cookie文件参数,则设置存取Cookie文件名
if($cookiejar) {
curl_setopt($curl, CURLOPT_COOKIEJAR, $cookiejar);
curl_setopt($curl, CURLOPT_COOKIEFILE, $cookiejar);
}
//如果是302转移,则返回转移后的网址及内容
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
//设置执行的最大秒数
curl_setopt($curl, CURLOPT_TIMEOUT, 100);
//返回内容中是否包含头信息
curl_setopt($curl, CURLOPT_HEADER, 0);
//把返回的结果存在文件或者变量中,而不是直接显示在浏览器
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//执行函数后的返回结果
$tmpInfo = curl_exec($curl);
//如果出错,显示错误信息
if (curl_errno($curl)) {
$tmpInfo = '<pre><b>错误:</b><br />'.curl_error($curl);
}
//关闭curl对象
curl_close($curl);
//返回结果
return $tmpInfo;
}

例子、soap

 

 代码如下 复制代码
function vcurlsoap($url, $SoapRequest, $SoapAction) {
$ch = curl_init (); //initiate the curl session
curl_setopt ( $ch, CURLOPT_URL, $url ); //set to url to post to
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); // return data in a variable
curl_setopt ( $ch, CURLOPT_HEADER, 0 );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $SoapRequest ); // post the xml
curl_setopt ( $ch, CURLOPT_TIMEOUT, 60 ); // set timeout in seconds
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
$header = array ("Content-Type: text/xml" );
$header [] = "Content-Length: ".strlen($SoapRequest);
if (! is_null ( $SoapAction ))
$header [] = 'SOAPAction: "' . $SoapAction . '"';
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header );
$xmlResponse = curl_exec ( $ch );
curl_close ( $ch );
return $xmlResponse;
}
只在php5.3以后的版本才真正的可以使用多线程序了,以前都是假的curl实现的多线程工作,下面我来给各位介绍几个多线程抓取信息测试例子,希望对各位会有帮助。

PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程。多线程在处理重复性的循环任务,能够大大缩短程序执行时间。

PHP扩展下载:https://github.com/krakjoe/pthreads
PHP手册文档:http://php.net/manual/zh/book.pthreads.php

1、扩展的编译安装(Linux),编辑参数 --enable-maintainer-zts 是必选项:

cd /Data/tgz/php-5.3.8
./configure --prefix=/Data/apps/php --with-config-file-path=/Data/apps/php/etc --with-mysql=/Data/apps/mysql --with-mysqli=/Data/apps/mysql/bin/mysql_config --with-iconv-dir --with-freetype-dir=/Data/apps/libs --with-jpeg-dir=/Data/apps/libs --with-png-dir=/Data/apps/libs --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-mbstring --with-mcrypt=/Data/apps/libs --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-opcache --with-pdo-mysql --enable-maintainer-zts
make clean
make
make install       
 
unzip pthreads-master.zip
cd pthreads-master
/Data/apps/php/bin/phpize
./configure --with-php-config=/Data/apps/php/bin/php-config
make
make install

添加扩展:


 vi /Data/apps/php/etc/php.ini

 extension = "pthreads.so"

一段PHP多线程、与For循环,抓取百度搜索页面的PHP代码示例:

 代码如下 复制代码
<?php 
  class test_thread_run extends Thread  
  { 
      public $url; 
      public $data; 
 
      public function __construct($url) 
      { 
          $this->url = $url; 
      } 
 
      public function run() 
      { 
          if(($url = $this->url)) 
          { 
              $this->data = model_http_curl_get($url); 
          } 
      } 
  } 
 
  function model_thread_result_get($urls_array)  
  { 
      foreach ($urls_array as $key => $value)  
      { 
          $thread_array[$key] = new test_thread_run($value["url"]); 
          $thread_array[$key]->start(); 
      } 
 
      foreach ($thread_array as $thread_array_key => $thread_array_value)  
      { 
          while($thread_array[$thread_array_key]->isRunning()) 
          { 
              usleep(10); 
          } 
          if($thread_array[$thread_array_key]->join()) 
          { 
              $variable_data[$thread_array_key] = $thread_array[$thread_array_key]->data; 
          } 
      } 
      return $variable_data; 
  } 
 
  function model_http_curl_get($url,$userAgent="")  
  { 
      $userAgent = $userAgent ? $userAgent : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)';  
      $curl = curl_init(); 
      curl_setopt($curl, CURLOPT_URL, $url); 
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
      curl_setopt($curl, CURLOPT_TIMEOUT, 5); 
      curl_setopt($curl, CURLOPT_USERAGENT, $userAgent); 
      $result = curl_exec($curl); 
      curl_close($curl); 
      return $result; 
  } 
 
  for ($i=0; $i < 100; $i++)  
  {  
      $urls_array[] = array("name" => "baidu", "url" => "http://www.baidu.com/s?wd=".mt_rand(10000,20000)); 
  } 
 
  $t = microtime(true); 
  $result = model_thread_result_get($urls_array); 
  $e = microtime(true); 
  echo "多线程:".($e-$t)."n"; 
 
  $t = microtime(true); 
  foreach ($urls_array as $key => $value)  
  { 
      $result_new[$key] = model_http_curl_get($value["url"]); 
  } 
  $e = microtime(true); 
  echo "For循环:".($e-$t)."n"; 
?>

例子,采集数据

 

 代码如下 复制代码

<?php
$urls = array(
'http://www.111cn.net/',
'http://www.sohu.com/',
'http://www.163.com/'
);

$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");

$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 设置不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}

do {
curl_multi_exec($mh,$active);
} while ($active);

foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件。当然,也可以不写入文件,比如存入数据库
} // 获得数据变量,并写入文件

foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}

curl_multi_close($mh);
fclose($st);
?>

下面一起来看一个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+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实现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 应用程序中的力量。可采用许多不同的方式来巧妙地实现这种存储,惟一的限制是开发人员的创造力和技能

[!--infotagslink--]

相关文章

  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
  • PHP函数strip_tags的一个bug浅析

    PHP 函数 strip_tags 提供了从字符串中去除 HTML 和 PHP 标记的功能,该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。由于 strip_tags() 无法实际验证 HTML,不完整或者破损标签将导致更多的数...2014-05-31
  • SQL Server中row_number函数的常见用法示例详解

    这篇文章主要给大家介绍了关于SQL Server中row_number函数的常见用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08
  • PHP加密解密函数详解

    分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: /* *功能:对字符串进行加密处理 *参数一:需要加密的内容 *参数二:密钥 */ function passport_encrypt($str,$key){ //加密函数 srand(...2015-10-30
  • php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法

    最近遇到一个问题,就是在使用php的mail函数发送utf-8编码的中文邮件时标题出现乱码现象,而邮件正文却是正确的。最初以为是页面编码的问题,发现页面编码utf-8没有问题啊,找了半天原因,最后找到了问题所在。 1.使用 PEAR 的...2015-10-21
  • C#中加载dll并调用其函数的实现方法

    下面小编就为大家带来一篇C#中加载dll并调用其函数的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#虚函数用法实例分析

    这篇文章主要介绍了C#虚函数用法,实例分析了C#中虚函数的功能与基本使用技巧,需要的朋友可以参考下...2020-06-25
  • PHP编码转换函数mb_convert_encoding与iconv用法

    文章来实现一个PHP编码转换函数mb_convert_encoding与iconv用法,希望例子能帮助到各位。 将一个短信接口代码从apache迁移到nginx+php-fpm后,发现无法发出短信了,查...2016-11-25