php中异步处理数据我们最简单的方法就是使用fsockopen了,下面我来介绍基于fsockopen函数实现的异步处理,希望对各位会带来帮助。
例子
test.php
代码如下 |
复制代码 |
<?php
$domain = "localhost";
$url = '/platform_php_sdk/test4.php';
$header = "POST $url HTTP/1.0\r\n";
$header .= "Content-Type:application/x-www-form-urlencoded\r\n";
$par = "email=zhangzenglun@163.com";
$header .="Content-Length:".strlen($par)."\r\n\r\n";
$fp = @fsockopen($domain,80,$errno,$errstr,30);
fputs($fp, $header.$par);
fclose($fp);
echo 'send ok!';
?>
|
test4.php
代码如下 |
复制代码 |
<?php
set_time_limit ( 0 );
ignore_user_abort ( true );
$i = 0;
while ( $i ++ < 50 ) {
file_put_contents ( $i . '.php', $_REQUEST['email'].$i);
sleep ( 3 );
}
?>
|
补充一个异步处理类
该类可以请求HTTP和HTTPS协议,还可以处理301、302重定向以及GZIP压缩等。
代码如下
asynHandle.class.php:
代码如下 |
复制代码 |
<?php
class AsynHandle {
public $url = ''; //传入的完整请求url,包括"http://"或"https://"
public $cookie = array(); //传入的cookie数组,须是键值对
public $post = array(); //传入的post数组,须是键值对
public $timeout = 30; //超时秒数
public $result = ''; //获取到的数据
private $gzip = true; //是否开启gzip压缩
private $fop = NULL; //fsockopen资源句柄
private $host = ''; //主机
private $port = ''; //端口
private $referer = ''; //伪造来路
private $requestUri = ''; //实际请求uri
private $header = ''; //头信息
private $block = 1; //网络流状态.1为阻塞,0为非阻塞
private $limit = 128; //读取的最大字节数
//构造函数
public function __construct(){
ignore_user_abort(TRUE);//忽略用户中断.如果客户端断开连接,不会引起脚本abort
//set_time_limit(0);//取消脚本执行延时上限
}
//解析URL并创建资源句柄
private function analyzeUrl(){
if ($this->url == ''){return false;}
$url_array = parse_url($this->url);
!isset($url_array['host']) && $url_array['host'] = '';
!isset($url_array['path']) && $url_array['path'] = '';
!isset($url_array['query']) && $url_array['query'] = '';
!isset($url_array['port']) && $url_array['port'] = 80;
$this->host = $url_array['host'];
$this->port = $url_array['port'];
$this->referer = $url_array['scheme'].'://'.$this->host.'/';
$this->requestUri = $url_array['path'] ?
$url_array['path'].($url_array['query'] ? '?'.$url_array['query'] : '') : '/';
switch($url_array['scheme']){
case 'https':
$this->fop = fsockopen('ssl://'.$this->host, 443, $errno, $errstr, $this->timeout);
break;
default:
$this->fop = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
break;
}
if(!$this->fop){
$this->result = "$errstr ($errno)<br />\n";
return false;
}
return true;
}//analyzeUrl end
//拼装HTTP的header
private function assHeader(){
$method = empty($this->post) ? 'GET' : 'POST';
$gzip = $this->gzip ? 'gzip, ' : '';
//cookie数据
if(!empty($htis->cookie)){
$htis->cookie = http_build_cookie($htis->cookie);
}
//post数据
if(!empty($this->post)){
$this->post = http_build_query($this->post);
}
$header = "$method $this->requestUri HTTP/1.0\r\n";
$header .= "Accept: */*\r\n";
$header .= "Referer: $this->referer\r\n";
$header .= "Accept-Language: zh-cn\r\n";
if(!empty($this->post)){
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
}
$header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
$header .= "Host: $this->host\r\n";
if(!empty($this->post)){
$header .= 'Content-Length: '.strlen($this->post)."\r\n";
}
$header .= "Connection: Close\r\n";
$header .= "Accept-Encoding: {$gzip}deflate\r\n";
$header .= "Cookie: $this->cookie\r\n\r\n";
$header .= $this->post;
$this->header = $header;
}//assHeader end
//返回状态检测,301、302重定向处理
private function checkRecvHeader($header){
if(strstr($header,' 301 ') || strstr($header,' 302 ')){//重定向处理
preg_match("/Location:(.*?)$/im",$header,$match);
$url = trim($match[1]);
preg_match("/Set-Cookie:(.*?)$/im",$header,$match);
$cookie = (empty($match)) ? '' : $match[1];
$obj = new AsynHandle();
$result = $obj->Get($url, $cookie, $this->post);
$this->result = $result;
return $result;
}elseif(!strstr($header,' 200 ')){
//找不到域名或网址
return false;
}else return 200;
}//checkRecvHeader end
//gzip解压
private function gzdecode($data){
$flags = ord(substr($data, 3, 1));
$headerlen = 10;
$extralen = 0;
$filenamelen = 0;
if ($flags & 4) {
$extralen = unpack('v' ,substr($data, 10, 2));
$extralen = $extralen[1];
$headerlen += 2 + $extralen;
}
if ($flags & 8) $headerlen = strpos($data, chr(0), $headerlen) + 1;
if ($flags & 16) $headerlen = strpos($data, chr(0), $headerlen) + 1;
if ($flags & 2) $headerlen += 2;
$unpacked = @gzinflate(substr($data, $headerlen));
if ($unpacked === FALSE) $unpacked = $data;
return $unpacked;
}//gzdecode end
//请求函数,只请求,不返回
public function Request($url, $cookie=array(), $post=array(), $timeout=3){
$this->url = $url;
$this->cookie = $cookie;
$this->post = $post;
$this->timeout = $timeout;
if(!$this->analyzeUrl()){
return $this->result;
}
$this->assHeader();
stream_set_blocking($this->fop, 0);//非阻塞,无须等待
fwrite($this->fop, $this->header);
fclose($this->fop);
return true;
}//Request end
//获取函数,请求并返回
public function Get($url, $cookie=array(), $post=array(), $timeout=30){
$this->url = $url;
$this->cookie = $cookie;
$this->post = $post;
$this->timeout = $timeout;
if(!$this->analyzeUrl()){
return $this->result;
}
$this->assHeader();
stream_set_blocking($this->fop, $this->block);
stream_set_timeout($this->fop, $this->timeout);
fwrite($this->fop, $this->header);
$status = stream_get_meta_data($this->fop);
if(!$status['timed_out']){
$h='';
while(!feof($this->fop)){
if(($header = @fgets($this->fop)) && ($header == "\r\n" || $header == "\n")){
break;
}
$h .= $header;
}
$checkHttp = $this->checkRecvHeader($h);
if($checkHttp!=200){return $checkHttp;}
$stop = false;
$return = '';
$this->gzip = false;
if(strstr($h,'gzip')) $this->gzip = true;
while(!($stop && $status['timed_out'] && feof($this->fop))){
if($status['timed_out']) return false;
$data = fread($this->fop, ($this->limit == 0 || $this->limit > 128 ? 128 : $this->limit));
if($data == ''){//有些服务器不行,须自行判断FOEF
break;
}
$return .= $data;
if($this->limit){
$this->limit -= strlen($data);
$stop = $this->limit <= 0;
}
}
@fclose($this->fop);
$this->result = $this->gzip ? $this->gzdecode($return) : $return;
return $this->result;
}else{
return false;
}
}//Get end
}
|
在php页面加服务器端用户验证时碰到使用session页面出现Warning: session_start() [function.session-start]: Cannot send session cache limiter...错误了,在网上看了一圈发现方法很简单。
今天在使用php 的session 的时候,出现了如下提示:
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started ..
因为在session_start(); 语句之前有其他的html代码
解决办法:
修改php.ini中的session.auto_start = 0 为 session.auto_start = 1
设置变量
代码如下 |
复制代码 |
session_register("user");
$_SESSION["user"]=$name;
获取
session_start();
echo $_SESSION["user"];
|
如果上面还是无法解决我们可以看看是不是编码问题。
1、将出错档案转换为 UTF-8 编码无 BOM 格式(我一般是用 Notepad++ 来转)
2、以 ob_start() 开启缓?区将输出资讯写入缓?区,可避免 headers 先于 session_start() 输出
代码如下 |
复制代码 |
<?php
ob_start()
echo "test"
session_start()
ob_end_flush()
?>
|
补充有朋友说:session.save_path = "C:/phpsession" [后边的路径自己设置,并且要保证存在,其实这个是错误的了我们配置好php时就己经配置好了,如果其它程序没有问题千万不要去修改session.save_path保存路径了。
把html转换成纯文本我们可以使用很多方法,不过最简单的就是使用strip_tags函数,但是还有一些朋友会发现可以使用自定义函数过滤掉,下面整理了一些方法。
将HTML转换为纯文本
有时候可能需要将HTML文本转换为纯文本。可以使用strip_tags()函数达到这个目的,该函数删除字符串中的所有HTML和PHP标记,只剩下文本实体。其形式为:
string strip_tags(string str[,string allowable_tags])
可选的参数allowable_tags指定在此过程中可以跳过的标记。下面的例子使用了strip_tags()删除字符串中的所以HTML标记:
代码如下 |
复制代码 |
$input = "Email example@example.com";
echo strip_tags($input);
?>
这回返回以下结果:
Email example@example.com
下面的例子删除<a>标记之外的所有标记:
$input = "This example
is yanshare!";
echo strip_tags($input, "");
?>
|
返回结果如下:
This example
is yanshare!
PHP版将html中的<br />换行符转换为文本框中的换行符:
代码如下 |
复制代码 |
function br2nl($text){
return preg_replace('/<br\\s*?\/??>/i','',$text);
}
或者:
function br2nl($text){
$text=preg_replace('/<br\\s*?\/??>/i',chr(13),$text);
return preg_replace('/ /i',' ',$text);
}
|
代码如下 |
复制代码 |
<?php
// $document 应包含一个 HTML 文档。
// 本例将去掉 HTML 标记,javascript 代码
// 和空白字符。还会将一些通用的
// HTML 实体转换成相应的文本。
$search = array ("'<script[^>]*?>.*?</script>'si", // 去掉 javascript
"'<[/!]*?[^<>]*?>'si", // 去掉 HTML 标记
"'([rn])[s]+'", // 去掉空白字符
"'&(quot|#34);'i", // 替换 HTML 实体
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'&(iexcl|#161);'i",
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'&#(d+);'e"); // 作为 PHP 代码运行
$replace = array ("",
"",
"1",
""",
"&",
"<",
">",
" ",
chr(161),
chr(162),
chr(163),
chr(169),
"chr(1)");
$text = preg_replace ($search, $replace, $document);
?>
<?php
$mystr=<<<SATO
此处省略几十行HTML代码^_^
SATO;
$str=strip_tags($mystr);
//到这里就已经达到我的HTML转为TXT文本的目的了,哈哈,使用这个函数真方便
//下面是插件的一些切词等操作,这里就不多说了
?>
|
后来我从网上看到了一个使用PHP写的方法,使用这个方法也可以实现将HTML转为TXT文本,个人觉得也还蛮实用的,在这里分享一下,代码如下:
代码如下 |
复制代码 |
function HtmlToText($str){
$str=preg_replace("/<sty(.*)\/style>|<scr(.*)\/script>|<!--(.*)-->/isU","",$str);//去除CSS样式、JS脚本、HTML注释
$alltext="";//用于保存TXT文本的变量
$start=1;//用于检测<左、>右标签的控制开关
for($i=0;$i<strlen($str);$i++){//遍历经过处理后的字符串中的每一个字符
if(($start==0)&&($str[$i]==">")){//如果检测到>右标签,则使用$start=1;开启截取功能
$start=1;
}else if($start==1){//截取功能
if($str[$i]=="<"){//如果字符是<左标签,则使用<font color='red'>|</font>替换
$start=0;
$alltext.="<font color='red'>|</font>";
}else if(ord($str[$i])>31){//如果字符是ASCII大于31的有效字符,则将字符添加到$alltext变量中
$alltext.=$str[$i];
}
}
}
//下方是去除空格和一些特殊字符的操作
$alltext = str_replace(" "," ",$alltext);
$alltext = preg_replace("/&([^;&]*)(;|&)/","",$alltext);
$alltext = preg_replace("/[ ]+/s"," ",$alltext);
return $alltext;
}
|
使用上面这个方法也可以实现将简答的HTML代码转换为TXT文本
PHP获取IP的地理位置都是使用相关函数+正则表达式来获取指定网页中的信息了,下面我整理几个常用的接口与获取方法,有需要了解的朋友可进入参考。
用php file_get_contents 获取ip地址后如何获取地理位置,看下下面代码:
使用file_get_contents和fopen必须空间开启allow_url_fopen。方法:编辑php.ini,设置allow_url_fopen = On,allow_url_fopen关闭时fopen和file_get_contents都不能打开远程文件。
例子
代码如下 |
复制代码 |
function get_ip_place()
{
$ip=file_get_contents("http://fw.qq.com/ipaddress");
$ip=str_replace('"',' ',$ip);
$ip2=explode("(",$ip);
$a=substr($ip2[1],0,-2);
$b=explode(",",$a);
return $b;
}
|
还有一种办法:
来看看
代码如下 |
复制代码 |
function get_ip_arr()
{
$ip=file_get_contents("http://fw.qq.com/ipaddress");
preg_match_all("/"(.*)"/",$ip,$arr);
return $arr;
}
|
返回来的是个数组,里面可以任意去取地区或者是ip
/使用curl:
使用curl必须空间开启curl。方法:windows下修改php.ini,将extension=php_curl.dll前面的分号去掉,而 且需要拷贝ssleay32.dll和libeay32.dll到C:/WINDOWS/system32下;Linux下要安装curl扩展
例子
代码如下 |
复制代码 |
function getIPLoc($queryIP){
$url = 'http://ip.qq.com/cgi-bin/searchip?searchip1='.$queryIP;
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_ENCODING ,'gb2312');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
$result = curl_exec($ch);
$result = mb_convert_encoding($result, "utf-8", "gb2312"); // 编码转换,否则乱码
curl_close($ch);
preg_match("@<span>(.*)</span></p>@iU",$result,$ipArray);
$loc = $ipArray[1];
return $loc;
}
|
php_sapi_name函数是一个可以返回php所运行的web服务器环境的字符串,下面我们来看两个关于php_sapi_name函数测试出php运行环境的例子。
代码:
<?php
echo php_sapi_name();
?>
在apache环境下面输出的结果是“apache2handler”;
在cgi模式下输出的结果是“cgi-fcgi”
要是在命令行模式下面运行的话,那么输出的结果是:”cli”
如果在nginx中运行就是 nginx字符了。