初期就这些需求,然后根据网上的资料,采用了一种阶段式抽取的方法,大家下面看一下整体的程序:
该程序是在ThinkPHP框架下完成的,使用了一些框架自带的类库和函数,下面我会逐一进行说明,控制器部分
抽奖算法需要满足的需求如下:
1.可以控制中奖的概率
2.具有随机性
3.最好可以控制奖品的数量
4.根据用户ID或者ip、手机号、QQ号等条件限制抽奖次数
初期就这些需求,然后根据网上的资料,采用了一种阶段式抽取的方法,大家下面看一下整体的程序:
该程序是在ThinkPHP框架下完成的,使用了一些框架自带的类库和函数,下面我会逐一进行说明,控制器部分:
代码如下 |
复制代码 |
<?php
/**
*
*
* @lanfengye <zibin_5257@163.com>
*/
class ChoujiangAction extends Action {
//抽奖的开始时间
var $begin_time="2012-12-25 14:00:00"; //开始时间 0-不限制
//抽奖的结束时间
var $stop_time="0"; //结束时间 0-不限制
//本次抽奖的奖项信息,必须按照从大到小的顺序进行填写,id为奖次,prize为中奖信息,v为中奖概率,num为奖品数量
//需要注意的是,该处也必须包含不中奖的信息,概率从小到大进行排序
var $prize_arr = array(
'0' => array('id' => 1, 'prize' => '44元购买1G/年空间', 'v' => 1,'num'=>1),
'1' => array('id' => 2, 'prize' => '55元购买1G/年空间', 'v' => 2,'num'=>2),
'2' => array('id' => 3, 'prize' => '66元购买1G/年空间', 'v' => 5,'num'=>2),
'3' => array('id' => 4, 'prize' => '77元购买1G/年空间', 'v' => 10,'num'=>3),
'4' => array('id' => 5, 'prize' => '88元购买1G/年空间', 'v' => 15,'num'=>4),
'5' => array('id' => 6, 'prize' => '99元购买1G/年空间', 'v' => 67,'num'=>10),
);
//首页显示方法
public function index(){
//连接数据库,去获取本次中奖的人员名单
$Choujiang=M('Choujiang');
$this->assign('list', $Choujiang->where("rid>0")->order('id desc')->select());
unset($Choujiang);
//在首页中显示抽奖的开始时间
$this->assign('begin_time',$this->begin_time);
$this->display();
}
/**
* 生成中奖信息,ajax进行请求该方法,需要客户填写QQ号码
*/
public function make() {
$qq_no= trim($_POST['qq_no']);
import('ORG.Util.Input');
$qq_no=Input::getVar($qq_no);
if(empty($qq_no)){
$this->ajaxReturn(1, '请正确填写QQ号码!');
exit;
}
if(!empty($this->begin_time) && time()<strtotime($this->begin_time)){
$this->ajaxReturn(1, '抽奖还没有开始,开始时间为:'.$this->begin_time);
exit;
}
if(!empty($this->stop_time) && time()>strtotime($this->stop_time)){
$this->ajaxReturn(1, '本次抽奖已经结束,结束时间为:'.$this->stop_time);
exit;
}
//获取奖项信息数组,来源于私有成员
$prize_arr= $this->prize_arr;
foreach ($prize_arr as $key => $val) {
$arr[$val['id']] = $val['v'];
}
//$rid中奖的序列号码
$rid = $this->get_rand($arr); //根据概率获取奖项id
$str = $prize_arr[$rid - 1]['prize']; //中奖项
$Choujiang=M('Choujiang');
//从数据库中获取特定QQ号已经参加抽奖的次数,如果大于等于3则提示次数用完
if($Choujiang->where("qq_no='{$qq_no}'")->count()>=3){
$str='您3次抽奖机会已经用完!';
$rid=0;
//从数据库中获取特定奖项序号的次数,大于等于设置的最大次数则提示奖品被抽完,如果需要一直中最后一个纪念奖,则修改该处即可
}elseif ($Choujiang->where("rid={$rid}")->count()>=$prize_arr[$rid-1]['num']) {
$str='很抱歉,您所抽中的奖项已经中完!';
$rid=0;
}
//生成一个用户抽奖的数据,用来记录到数据库
$data=array(
'rid'=>$rid,
'pop'=>$str,
'qq_no'=>$qq_no,
'input_time'=>time()
);
//将用户抽奖信息数组写入数据库
$Choujiang->add($data);
unset($Choujiang);
//ajax返回信息
$this->ajaxReturn(1, $str);
}
/**
* 根据概率获取中奖号码
*/
private function get_rand($proArr) {
$result = '';
//概率数组的总概率精度
$proSum = array_sum($proArr);
//概率数组循环
foreach ($proArr as $key => $proCur) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur) {
$result = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset($proArr);
return $result;
}
}
?> |
该算法简单使用,并发访问性能非常好,稍加改动就可以用于各种场合,结合用户登录等信息可有效控制每个人的抽奖次数。将开始和结束之间更改为数组,就可以完善成为每天特定时间抽奖的程序。
本文章来给各位同学介绍一个不错的需要登录的php 文件上传管理系统,功能简单有需要了解的同学可参考。
代码如下 |
复制代码 |
<?php
$admin_pw="admin";//管理密码
$uploaddir="upload";//上传目录
session_start();
if($_GET['action']=="getcode")
{
setcode();
exit();
}
if($_POST['password']==$admin_pw && $_POST['yz']==$_SESSION['yzcode'])
{
$_SESSION['logined']=$admin_pw;
}
if($_GET['action']=="logout")
{
$_SESSION['logined']="";
header("location: ".$_SERVER['PHP_SELF']);
exit();
}
if($_SESSION['logined']!=$admin_pw)
{
?>
<!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>请登录</title>
</head>
<body>
<form action="" method="post">
输入密码:<input type="password" name="password" style="width:100px;" /><br />验证字符:<input type="text" style="width:40px;" name="yz" /><a href="#" onclick="document.tzm.src='?action=getcode';"><img" width=100% src="?action=getcode" alt="验证码" id="tzm" name="tzm" /></a><br /><input type="submit" value="进入管理" />
</form>
</body>
</html>
<?php
}
else
{
?>
<!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>文件上传</title>
</head>
<body>
<?php
if($_POST['ac']=="upload")
{
$fileall=explode('.',$_FILES['file']['name']);
$filetype=$fileall[count($fileall)-1];
$filename=$uploaddir."/".$_FILES['file']['name']."_".rand(1,999999999).".".$filetype;
$fileexists=file_exists($filename);
while($fileexists==true)
{
$filename=$uploaddir."/".$_FILES['file']['name']."_".rand(1,999999999).".".$filetype;
$fileexists=file_exists($filename);
}
if(move_uploaded_file($_FILES["file"]["tmp_name"],$filename))
{
$url="http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
echo "文件:".$filename." 上传成功!<br>文件地址:<input type=text style='width:350px;' value=".dirname($url)."/".$filename." /><a href=".dirname($url)."/".$filename." target="_blank">测试</a>";
}
else
{
echo "文件".$filename."上传失败!";
}
}
?>
<form action="" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="file" id="file" width="100px" /><input type="hidden" name="ac" value="upload" /><input type="submit" value="上传" />
</form>
<p><a href="?action=logout">退出登录</a></p>
</body>
</html>
<?php
}
function setcode()
{
Header("Content-type: image/gif");
$border = 0; //是否要边框 1要:0不要
$how = 4; //验证码位数
$w = $how*15; //图片宽度
$h = 20; //图片高度
$fontsize = 5; //字体大小
$alpha = "abcdefghijkmnopqrstuvwxyz"; //验证码内容1:字母
$number = "0123456789"; //验证码内容2:数字
$randcode = ""; //验证码字符串初始化
srand((double)microtime()*1000000); //初始化随机数种子
$im = ImageCreate($w, $h); //创建验证图片
$bgcolor = ImageColorAllocate($im, 255, 255, 255); //设置背景颜色
ImageFill($im, 0, 0, $bgcolor); //填充背景色
if($border)
{
$black = ImageColorAllocate($im, 0, 0, 0); //设置边框颜色
ImageRectangle($im, 0, 0, $w-1, $h-1, $black);//绘制边框
}
for($i=0; $i<$how; $i++)
{
$alpha_or_number = mt_rand(0, 1); //字母还是数字
$str = $alpha_or_number ? $alpha : $number;
$which = mt_rand(0, strlen($str)-1); //取哪个字符
$code = substr($str, $which, 1); //取字符
$j = !$i ? 4 : $j+15; //绘字符位置
$color3 = ImageColorAllocate($im, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100)); //字符随即颜色
ImageChar($im, $fontsize, $j, 3, $code, $color3); //绘字符
$randcode .= $code; //逐位加入验证码字符串
}
$_SESSION['yzcode'] = $randcode;
Imagegif($im);
ImageDestroy($im);
}
?>
|
在php中fsockopen函数可以模仿用户去访问一些网站并且还可以带一些常用的信息,如果浏览器,IP,post,get 等等数据,下面我分别一来给大家介绍介绍。
如果你要使用fsockopen函数我们必须在php.ini中把allow_url_fopen = On 设置为开启状态。
例
fsockopen() Example
代码如下 |
复制代码 |
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />n";
} else {
$out = "GET / HTTP/1.1rn";
$out .= "Host: www.example.comrn";
$out .= "Connection: Closernrn";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
|
伪造post
POST HTTP请求(URL)并获取返回值
代码如下 |
复制代码 |
<?php
$srv_ip = '192.168.1.5';//你的目标服务地址.
$srv_port = 80;//端口
$url = 'http://localhost/fsock.php'; //接收你post的URL具体地址
$fp = '';
$errno = 0;//错误处理
$errstr = '';//错误处理
$timeout = 10;//多久没有连上就中断
$post_str = "username=demo&password=hahaha";//要提交的内容.
//打开网络的 Socket 链接。
$fp = fsockopen($srv_ip,$srv_port,$errno,$errstr,$timeout);
if (!$fp){
echo('fp fail');
}
$content_length = strlen($post_str);
$post_header = "POST $url HTTP/1.1rn";
$post_header .= "Content-Type: application/x-www-form-urlencodedrn";
$post_header .= "User-Agent: MSIErn";
$post_header .= "Host: ".$srv_ip."rn";
$post_header .= "Content-Length: ".$content_length."rn";
$post_header .= "Connection: closernrn";
$post_header .= $post_str."rnrn";
fwrite($fp,$post_header);
$inheader = 1;
while(!feof($fp)){//测试文件指针是否到了文件结束的位置
$line = fgets($fp,1024);
//去掉请求包的头信息
if ($inheader && ($line == "n" || $line == "rn")) {
$inheader = 0;
}
if ($inheader == 0) {
echo $line;
}
}
fclose($fp);
unset ($line);
?>
|
简要说明:代码第二行是你的IP地址或域名,第四行是你要POST的页面的具体地址,本例用的是fsock.php,fsock.php内容如下:
代码如下 |
复制代码 |
<?php
echo "username:".$_POST['username']."<br/>";
echo "password:".$_POST['password'];
?>
|
结果为:
username:demo
password:hahaha
伪造get
同时伪造post,get方法。
代码如下 |
复制代码 |
<?php
//fsocket模拟post提交
$purl = "http://localhost/netphp/test2.php?uu=rrrrrrrrrrrr";
print_r(parse_url($url));
sock_post($purl,"uu=55555555555555555");
//fsocket模拟get提交
function sock_get($url, $query)
{
$info = parse_url($url);
$fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
$head = "GET ".$info['path']."?".$info["query"]." HTTP/1.0rn";
$head .= "Host: ".$info['host']."rn";
$head .= "rn";
$write = fputs($fp, $head);
while (!feof($fp))
{
$line = fread($fp,4096);
echo $line;
}
}
sock_post($purl,"uu=rrrrrrrrrrrrrrrr");
function sock_post($url, $query)
{
$info = parse_url($url);
$fp = fsockopen($info["host"], 80, $errno, $errstr, 3);
$head = "POST ".$info['path']."?".$info["query"]." HTTP/1.0rn";
$head .= "Host: ".$info['host']."rn";
$head .= "Referer: http://".$info['host'].$info['path']."rn";
$head .= "Content-type: application/x-www-form-urlencodedrn";
$head .= "Content-Length: ".strlen(trim($query))."rn";
$head .= "rn";
$head .= trim($query);
$write = fputs($fp, $head);
while (!feof($fp))
{
$line = fread($fp,4096);
echo $line;
}
}
?>
|
因为工作需我们需要在php中生成加密然后在asp.net中接受过来的密码再解密,下面我找到一个PHP与asp.net C#可共用的可逆加密算法,有需要了解的同学可参考。
php加密算法
代码如下 |
复制代码 |
<?php
class DES
{
var $key;
var $iv; //偏移量
function DES($key = '11001100', $iv=0 ) {
//key长度8例如:1234abcd
$this->key = $key;
if( $iv == 0 ) {
$this->iv = $key; //默认以$key 作为 iv
} else {
$this->iv = $iv; //mcrypt_create_iv ( mcrypt_get_block_size (MCRYPT_DES, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM );
}
}
function encrypt($str) {
//加密,返回大写十六进制字符串
$size = mcrypt_get_block_size ( MCRYPT_DES, MCRYPT_MODE_CBC );
$str = $this->pkcs5Pad ( $str, $size );
return strtoupper( bin2hex( mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv ) ) );
}
function decrypt($str) {
//解密
$strBin = $this->hex2bin( strtolower( $str ) );
$str = mcrypt_cbc( MCRYPT_DES, $this->key, $strBin, MCRYPT_DECRYPT, $this->iv );
$str = $this->pkcs5Unpad( $str );
return $str;
}
function hex2bin($hexData) {
$binData = "";
for($i = 0; $i < strlen ( $hexData ); $i += 2) {
$binData .= chr ( hexdec ( substr ( $hexData, $i, 2 ) ) );
}
return $binData;
}
function pkcs5Pad($text, $blocksize) {
$pad = $blocksize - (strlen ( $text ) % $blocksize);
return $text . str_repeat ( chr ( $pad ), $pad );
}
function pkcs5Unpad($text) {
$pad = ord ( $text {strlen ( $text ) - 1} );
if ($pad > strlen ( $text ))
return false;
if (strspn ( $text, chr ( $pad ), strlen ( $text ) - $pad ) != $pad)
return false;
return substr ( $text, 0, - 1 * $pad );
}
}
?>
|
asp.net程序代码
代码如下 |
复制代码 |
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace WindowsFormsApplication1
{
/// <summary>
/// DES加密解密字符串
/// </summary>
public class DesEncryption
{
/// <summary>
/// DES加密字符串
/// </summary>
/// <param name="encryptString">待加密的字符串</param>
/// <param name="encryptKey">加密密钥,要求为8位</param>
/// <returns>加密成功返回加密后的字符串,失败返回null</returns>
public static string EncryptDES(string encryptString, string encryptKey = "11001100")
{
try
{
byte[] rgbKey = ASCIIEncoding.ASCII.GetBytes(encryptKey.Substring(0, 8));
byte[] rgbIV = rgbKey;
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in mStream.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
ret.ToString();
return ret.ToString();
}
catch
{
return null;
}
}
/// <summary>
/// DES解密字符串
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
/// <returns>解密成功返回解密后的字符串,失败返回null</returns>
public static string DecryptDES(string decryptString, string decryptKey = "11001100")
{
try
{
byte[] rgbKey = ASCIIEncoding.ASCII.GetBytes(decryptKey);
byte[] rgbIV = rgbKey;
byte[] inputByteArray = new byte[decryptString.Length / 2];
for (int x = 0; x < decryptString.Length / 2; x++)
{
int i = (Convert.ToInt32(decryptString.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Encoding.UTF8.GetString(mStream.ToArray());
}
catch
{
return null;
}
}
}
}
|
多线程是java中一个很不错的东西,很多朋友说在php中不可以使用PHP多线程了,其实那是错误的说法PHP多线程实现方法和fsockopen函数有关,下面我们来介绍具体实现程序代码,有需要了解的同学可参考。
当有人想要实现并发功能时,他们通常会想到用fork或者spawn threads,但是当他们发现php不支持多线程的时候,大概会转换思路去用一些不够好的语言,比如perl。
其实的是大多数情况下,你大可不必使用 fork 或者线程,并且你会得到比用 fork 或 thread 更好的性能。
假设你要建立一个服务来检查正在运行的n台服务器,以确定他们还在正常运转。你可能会写下面这样的代码:
代码如下 |
复制代码 |
<?php
$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com");
$timeout = 15;
$status = array();
foreach ($hosts as $host) {
$errno = 0;
$errstr = "";
$s = fsockopen($host, 80, $errno, $errstr, $timeout);
if ($s) {
$status[$host] = "Connectedn";
fwrite($s, "HEAD / HTTP/1.0rnHost: $hostrnrn");
do {
$data = fread($s, 8192);
if (strlen($data) == 0) {
break;
}
$status[$host] .= $data;
} while (true);
fclose($s);
} else {
$status[$host] = "Connection failed: $errno $errstrn";
}
}
print_r($status);
?>
|
它运行的很好,但是在fsockopen()分析完hostname并且建立一个成功的连接(或者延时$timeout秒)之前,扩充这段代码来管理大量服务器将耗费很长时间。
因此我们必须放弃这段代码;我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname(所以直接使用ip更加明智),不过将在打开一个连接之后立刻返回,继而我们就可以连接下一台服务器。
有两种方法可以实现;PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本,你需要自己动手,用sockets扩展解决问题。
下面是PHP5中的解决方法:
它运行的很好,但是在fsockopen()分析完hostname并且建立一个成功的连接(或者延时$timeout秒)之前,扩充这段代码来管理大量服务器将耗费很长时间。
因此我们必须放弃这段代码;我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname(所以直接使用ip更加明智),不过将在打开一个连接之后立刻返回,继而我们就可以连接下一台服务器。
有两种方法可以实现;PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本,你需要自己动手,用sockets扩展解决问题。
下面是PHP5中的解决方法:
代码如下 |
复制代码 |
<?php
$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com");
$timeout = 15;
$status = array();
$sockets = array();
/* Initiate connections to all the hosts simultaneously */
foreach ($hosts as $id => $host) {
$s = stream_socket_client("
$
$host:80", $errno, $errstr, $timeout,
STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
if ($s) {
$sockets[$id] = $s;
$status[$id] = "in progress";
} else {
$status[$id] = "failed, $errno $errstr";
}
}
/* Now, wait for the results to come back in */
while (count($sockets)) {
$read = $write = $sockets;
/* This is the magic function - explained below */
$n = stream_select($read, $write, $e = null, $timeout);
if ($n > 0) {
/* readable sockets either have data for us, or are failed
* connection attempts */
foreach ($read as $r) {
$id = array_search($r, $sockets);
$data = fread($r, 8192);
if (strlen($data) == 0) {
if ($status[$id] == "in progress") {
$status[$id] = "failed to connect";
}
fclose($r);
unset($sockets[$id]);
} else {
$status[$id] .= $data;
}
}
/* writeable sockets can accept an HTTP request */
foreach ($write as $w) {
$id = array_search($w, $sockets);
fwrite($w, "HEAD / HTTP/1.0rnHost: "
. $hosts[$id] . "rnrn");
$status[$id] = "waiting for response";
}
} else {
/* timed out waiting; assume that all hosts associated
* with $sockets are faulty */
foreach ($sockets as $id => $s) {
$status[$id] = "timed out " . $status[$id];
}
break;
}
}
foreach ($hosts as $id => $host) {
echo "Host: $hostn";
echo "Status: " . $status[$id] . "nn";
}
?>
|
我们用stream_select()等待sockets打开的连接事件。stream_select()调用系统的select(2)函数来工作:前面三个参数是你要使用的streams的数组;你可以对其读取,写入和获取异常(分别针对三个参数)。stream_select()可以通过设置$timeout(秒)参数来等待事件发生-事件发生时,相应的sockets数据将写入你传入的参数。
下面是PHP4.1.0之后版本的实现,如果你已经在编译PHP时包含了sockets(ext/sockets)支持,你可以使用根上面类似的代码,只是需要将上面的streams/filesystem函数的功能用ext/sockets函数实现。主要的不同在于我们用下面的函数代替stream_socket_client()来建立连接:
代码如下 |
复制代码 |
<?php
// This value is correct for Linux, other systems have other values
define('EINPROGRESS', 115);
function non_blocking_connect($host, $port, &$errno, &$errstr, $timeout) {
$ip = gethostbyname($host);
$s = socket_create(AF_INET, SOCK_STREAM, 0);
if (socket_set_nonblock($s)) {
$r = @socket_connect($s, $ip, $port);
if ($r || socket_last_error() == EINPROGRESS) {
$errno = EINPROGRESS;
return $s;
}
}
$errno = socket_last_error($s);
$errstr = socket_strerror($errno);
socket_close($s);
return false;
}
?>
|
现在用socket_select()替换掉stream_select(),用socket_read()替换掉fread(),用socket_write()替换掉fwrite(),用socket_close()替换掉fclose()就可以执行脚本了!
PHP5的先进之处在于,你可以用stream_select()处理几乎所有的stream-例如你可以通过include STDIN用它接收键盘输入并保存进数组,你还可以接收通过proc_open()打开的管道中的数据。
下面来分享一个PHP多线程类
代码如下 |
复制代码 |
* @title: PHP多线程类(Thread)
* @version: 1.0
* @author: phper.org.cn < web@phper.org.cn >
* @published: 2010-11-2
*
* PHP多线程应用示例:
* require_once 'thread.class.php';
* $thread = new thread();
* $thread->addthread('action_log','a');
* $thread->addthread('action_log','b');
* $thread->addthread('action_log','c');
* $thread->runthread();
*
* function action_log($info) {
* $log = 'log/' . microtime() . '.log';
* $txt = $info . "rnrn" . 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn";
* $fp = fopen($log, 'w');
* fwrite($fp, $txt);
* fclose($fp);
* }
*/
class thread {
var $hooks = array();
var $args = array();
function thread() {
}
function addthread($func)
{
$args = array_slice(func_get_args(), 1);
$this->hooks[] = $func;
$this->args[] = $args;
return true;
}
function runthread()
{
if(isset($_GET['flag']))
{
$flag = intval($_GET['flag']);
}
if($flag || $flag === 0)
{
call_user_func_array($this->hooks[$flag], $this->args[$flag]);
}
else
{
for($i = 0, $size = count($this->hooks); $i < $size; $i++)
{
$fp=fsockopen($_SERVER['HTTP_HOST'],$_SERVER['SERVER_PORT']);
if($fp)
{
$out = "GET {$_SERVER['PHP_SELF']}?flag=$i HTTP/1.1rn";
$out .= "Host: {$_SERVER['HTTP_HOST']}rn";
$out .= "Connection: Closernrn";
fputs($fp,$out);
fclose($fp);
}
}
}
}
}
|
标签:[!--infotagslink--]