1,配置文件 复制代码代码如下: <?php define('PATH',dirname($_SERVER['SCRIPT_NAME'])); //聊天室目录 define('CHAT_NAME','PHP聊天室'); //聊天室名称 define("MESS", "mess.txt"); //聊天信息 define("PERSON", "person.txt"); //在线人名单 define("RETIME",3); //刷新时间 define("LINE",11); //公共窗口显示的行数 define("PRLINE",5); //私聊窗口显示的行数 define("MAX",50); //聊天室人数限制 define("MAXTIME",600000); //最大不发言时间,单位是毫秒 define("WELCOME","<font color=blue>欢迎光临".CHAT_NAME.",请遵守聊天室规则,不要恶意刷新,不要使用不文明用语。</font>"); //欢迎语 ?> 2,公共函数文件 (1)chklogin()函数检查用户昵称是否重复。参数$user是登录用户的昵称。当函数返回值为True时,昵称不可用;返回值为False时,昵称可用。 复制代码代码如下: function chklogin($file,$user){ $boo = false; if(file_exists($file)){ $userarr = file($file); /* 判断昵称是否重复 */ foreach($userarr as $value){ //判断昵称是否重复 $tmparr = explode('#',$value); //使用“#”作为分隔符来拆分字符串 if($user == $tmparr[0]){ //如果用户数组中包含此用户 $boo = true; break; } } } return $boo; } (2)addlogin()函数将登录的用户昵称写入文件中,保存格式为:昵称#IP#性别,参数$file是保存的文件地址,$user是用户昵称,$ip是登陆IP,$sex表示用户性别。 复制代码代码如下: function addlogin($file,$user,$ip,$sex){ $tmp = $user.'#'.$ip.'#'.$sex.chr(13).chr(10); //chr(13) 是一个回车,Chr(10) 是个换行符,chr(32) 是一个空格符 $fp = fopen($file,'a'); //写入方式在文件末尾追加信息 $boo = fwrite($fp,$tmp); fclose($fp); return $boo; } (3)storeuser()函数的作用是将用户信息存为一个数组。格式为“用户名,用户性别”,参数$file是用户列表文件。代码如下: 复制代码代码如下: function storeuser($file){ $tmparr = file($file); //将文件内容写入数组 $userarr = array(); //创建数组 foreach($tmparr as $value){ //循环输出数组内容 $tmparr = explode('#',$value); //使用#拆分字符串 $userarr[] = $tmparr[0].','.$tmparr[2]; //将用户名和用户性别保存到新数组中 } return $userarr; } (4)addmess()函数将发言内容写入文件中。参数$file是保存的文件地址,$mess是要保存的内容 复制代码代码如下: function addmess($file,$mess){ $fp = fopen($file,'a'); //以追加的形式打开文件 $boo = fwrite($fp,$mess.chr(13).chr(10)); //将信息写入文件中 fclose($fp); //关闭文件 return boo; } (5)deluser()函数的作用是删掉用户。参数$file是保存的文件地址,$user是要删除的用户 复制代码代码如下: function deluser($file,$user){ $tmparr = file($file); //将文件内容写入数组 $rearr = array(); //创建数组 foreach($tmparr as $value){ //循环输出数组内容 $tmp = explode('#',$value); //使用#拆分字符串 if($tmp[0] != $user){ //如果变量中的用户名和当前用户不相等 $rearr[] = $value; //将该用户信息保存到新数组中 } } $fp = fopen($file,'w+'); //以只写的方式打开文件 foreach($rearr as $value){ //循环数组 fwrite($fp,$value); //写入数组内容 } fclose($fp); //关闭文件 } (6)getRows()函数的作用是返回文件的行数,参数$file是文件名 复制代码代码如下: function getRows($file){ if(file_exists($file)){ //如果文件存在 $fl = file($file); //将文件按行写入数组 return count($fl); //求出数组长度并返回 }else{ return 0; //如果文件不存在,返回0
你这个的话 index.php 得这么写
<?phpheader('content-type:text/html;charset=utf-8');$actio = $_GET['actio']; $do = $_GET['do']; include $actio.'/'.$do.'.php';
<?php //直接输出 echo exp(-0.5)?>
php有可用的websocket库,不需要php-fpm。
目前比较成熟的有swoole(swoole.com),和workman(workman.net)
swoole是c写的php扩展, 效率比nodejs还要高,workman是纯php实现,两者都号称可以实现并发百万TCP连接。
给你个例子:
这个要通过cmd运行的 具体带的参数有点忘记了<?php error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); //创建一个socket连接 设置参数 绑定 监听 并且返回 $master = WebSocket("localhost",12345); //标示是否已经进行过握手了 $is_shaked = false; //是否已经关闭 $is_closed = true; //将socket变为一个可用的socket while(true){ //如果是关闭状态并且是没有握手的话 则创建一个可用的socket(貌似第二个条件可以去除) if($is_closed && !$is_shaked){ if(($sock = socket_accept($master)) < 0){ echo "socket_accept() failed: reason: " . socket_strerror($sock) . "\n"; } //将关闭状态修改为false $is_closed = false; } //开始进行数据处理 process($sock); } //处理请求的函数 function process($socket){ //先从获取到全局变量 global $is_closed, $is_shaked; //从socket中获取数据 $buffer = socket_read($socket,2048); //如果buffer返回值为false并且已经握手的话 则断开连接 if(!$buffer && $is_shaked){ disconnect($socket); }else{ //如果没有握手的话则握手 并且修改握手状态 if($is_shaked == false){ $return_str = dohandshake($buffer); $is_shaked = true; }else{ //如果已经握手的话则送入deal函数中进行相应处理 $data_str = decode($buffer); //解析出来的从前端送来的内容 console($data_str); $return_str = encode(deal($socket, $data_str)); //$return_str = encode($data_str); } //将应该返回的字符串写入socket返回 socket_write($socket,$return_str,strlen($return_str)); } } function deal($socket, $msgObj){ $obj = json_decode($msgObj); foreach($obj as $key=>$value){ if($key == 'close'){ disconnect($socket); console('close success'); return 'close success'; }else if($key == 'msg'){ console($value."\n"); return $value; } } } //获取头部信息 function getheaders($req){ $r=$h=$o=null; if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; } if(preg_match("/Host: (.*)\r\n/" ,$req,$match)){ $h=$match[1]; } if(preg_match("/Origin: (.*)\r\n/",$req,$match)){ $o=$match[1]; } if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$req,$match)){ $key=$match[1]; } if(preg_match("/\r\n(.*?)\$/",$req,$match)){ $data=$match[1]; } return array($r,$h,$o,$key,$data); } function WebSocket($address,$port){ $master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed"); socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed"); socket_bind($master, $address, $port) or die("socket_bind() failed"); socket_listen($master,20) or die("socket_listen() failed"); echo "Server Started : ".date('Y-m-d H:i:s')."\n"; echo "Master socket : ".$master."\n"; echo "Listening on : ".$address." port ".$port."\n\n"; return $master; } function dohandshake($buffer){ list($resource,$host,$origin,$key,$data) = getheaders($buffer); echo "resource is $resource\n"; echo "origin is $origin\n"; echo "host is $host\n"; echo "key is $key\n\n"; $response_key = base64_encode(sha1($key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); $return_str = "HTTP/1.1 101 Switching Protocols\r\n". "Upgrade: websocket\r\n". "Connection: Upgrade\r\n". "Sec-WebSocket-Accept: $response_key\r\n\r\n"; return $return_str; } function console($msg){ $msg = transToGBK($msg); echo "$msg\n"; return $msg; } function decode($msg="") { $mask = array(); $data = ""; $msg = unpack("H*",$msg); $head = substr($msg[1],0,2); if (hexdec($head{1}) === 8){ $data = false; } else if (hexdec($head{1}) === 1){ $mask[] = hexdec(substr($msg[1],4,2)); $mask[] = hexdec(substr($msg[1],6,2)); $mask[] = hexdec(substr($msg[1],8,2)); $mask[] = hexdec(substr($msg[1],10,2)); $s = 12; $e = strlen($msg[1])-2; $n = 0; for ($i= $s; $i<= $e; $i+= 2){ $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2))); $n++; } } return $data; } function encode($msg=""){ $frame = array(); $frame[0] = "81"; $msg .= ' is ok'; $len = strlen($msg); $frame[1] = $len<16?"0".dechex($len):dechex($len); $frame[2] = ord_hex($msg); $data = implode("",$frame); return pack("H*", $data); } function transToGBK($s){//UTF8->GBK //echo $s; return iconv("UTF-8", "GBK", $s); return $s; } function ord_hex($data){ $msg = ""; $l = strlen($data); for ($i=0; $i<$l; $i++){ //ord是返回字符串第一个字符的ascii值 //dechex把十进制转换为十六进制 $msg .= dechex(ord($data{$i})); } return $msg; } function disconnect($socket){ global $is_shaked, $is_closed; $is_shaked = false; $is_closed = true; socket_close($socket); }?>
两种方式:
第一:使用一个文本文档
每次读取这个文本文档的数,然后加1,再覆盖写入
关键代码:
<?php$txt_db = 'jsb.txt';$nums = file_get_contents($txt_db);$nums++;file_put_contents($txt_db,$nums);?>
第二:使用数据库,设计数据表,每次更新数据库。
个人建议:使用第一种方法。
原因:需求简单,所以尽可能少占资源,抗压力强。
<!DOCTYPE html>body{<body><?php//设置级别错误,通知类除外error_reporting('E_ALL&~E_NOTICE'); /**1---传入页码,使用GET获取**/$page=$_GET['p'];/**2---根据页码取出数据:php->mysql处理**/$host="localhost";$username="root";$password="root";$db="db4"; //数据库$mysql_table="person"; //数据表$table_guanjianzi="think"; //关键字$pageSize=10;$showPage=5; //连接数据库,面向过程$conn=mysqli_connect($host,$username,$password);if(!$conn){echo "数据库连接失败";exit;}//选择所要操作的数据库mysqli_select_db($conn,$db);//设置数据库编码格式mysqli_query($conn,"SET NAMES UTF8");//编写sql获取分页数据 SELECT * FROM 表名 LIMIT 起始位置,显示条数//注意:以下id,name,age,say都是字段节点名,person是表名,db4是数据库名,think是指定的关键字.$sql = "SELECT id, name, age, sayFROM personWHERE say LIKE '%{$table_guanjianzi}%' order by id ASC LIMIT ".($page-1)*$pageSize .",{$pageSize}"; //双引号能包单引号,反过来不行,会出错./// $sql = 'SELECT id, name, age, say// FROM person// WHERE say LIKE "%'think'%" order by id ASC LIMIT '.($page-1)*$pageSize .",{$pageSize}";// 节点名 关键字 节点名 可指定数量limit后可写一个指定的数字//$sql="select * from $mysql_table"//$sql='select * from data where Id='.$id.' order by '.$item.' desc';//把sql语句传送到数据库$result=mysqli_query($conn,$sql);//将数据显示到table中,并未table设置格式echo "<div class='content'>";echo "<table border=1 cellspacing=0 width=30% align=center>";echo "<tr><td>ID</td><td>NAME</td><td>say</td></tr>";while ($row = mysqli_fetch_assoc($result)) {echo "<tr>";echo "<td>{$row['id']}</td>";echo "<td>{$row['name']}</td>";echo "<td>{$row['say']}</td>";echo "<tr>";}echo "</table>";echo "</div>";//释放结果mysqli_free_result($result);//获取数据总条数$total_sql="SELECT COUNT(*)FROM $mysql_table";$total_result=mysqli_fetch_array(mysqli_query($conn,$total_sql));$total=$total_result[0];$total_pages=ceil($total/$pageSize);//关闭数据库mysqli_close($conn);/**3---显示数据+显示分页条**/$page_banner="<div class='page'>";//计算偏移量$pageoffset=($showPage-1)/2;//两种情况下 首页、上一页 的显示效果if($page>1){$page_banner .= "<a href='".$_SERVER['PHP_SELF']."?p=1'>首页</a>";$page_banner .= "<a href='".$_SERVER['PHP_SELF']."?p=" .($page-1) . "'><上一页</a>";}else{$page_banner .="<span class='disable'>首页</span>";$page_banner .="<span class='disable'><上一页</span>";}//显示$start=1;$end=$total_pages;//当总条数大于分页数时if($total_pages>$showPage){if($page>$pageoffset+1){$page_banner .="...";}if($page>$pageoffset){$start=$page-$pageoffset;$end=$total_pages>$page+$pageoffset?$page+$pageoffset:$total_pages;//三段式}//最前面几个特殊页号的显示。当前指的是页号1或者2时else{$start=1;$end=$showPage;}//最后面几个特殊页号的显示,当前显示的是页号7和8if($page+$pageoffset>$total_pages){$start=$start-($page+$pageoffset-$end);//注意理解这一句}}//显示页码for($i=$start;$i<=$end;$i++){//当前页页码上显示背景色if($page==$i){$page_banner .="<span class='current'>{$i}</span>";}//非当前页码显示else{$page_banner .= "<a href='".$_SERVER['PHP_SELF']."?p=" .$i . "'>{$i}</a>"; } }if($total_pages>$showPage&&$total_pages>$page+$pageoffset){$page_banner .="..."; }//两种情况下的尾页、下一页 的显示效果if($page<$total_pages){$page_banner .= "<a href='".$_SERVER['PHP_SELF']."?p=" .($page+1) . "'>下一页></a>";$page_banner .= "<a href='".$_SERVER['PHP_SELF']."?p=$total_pages'>尾页</a>";}else{$page_banner .="<span class='disable'>尾页</span>";$page_banner .="<span class='disable'>下一页></span>";}$page_banner .= "共{$total_pages}页,";$page_banner .= "<form action='mypage.php' method='get'>";$page_banner .= " 到第<input type='text' size=2 value='1' name='p'>页";$page_banner .= "<input type='submit' value='确定'>";$page_banner .= "</form>";$page_banner .= "</div>";echo $page_banner;?></body></html>
代码如下:</form> <script>$("input[name='res']").click(); </script>
1、冒泡排序function bubble_sort($arr) { $n=count($arr); for($i=0;$i<$n-1;$i ){ for($j=$i 1;$j<$n;$j ) { if($arr[$j]<$arr[$i]) { $temp=$arr[$i]; $arr[$i]=$arr[$j]; $arr[$j]=$temp; } } } return $arr;}2、归并排序function Merge(&$arr, $left, $mid, $right) { $i = $left; $j = $mid 1; $k = 0; $temp = array(); while ($i <= $mid && $j <= $right) { if ($arr[$i] <= $arr[$j]) $temp[$k ] = $arr[$i ]; else $temp[$k ] = $arr[$j ]; } while ($i <= $mid) $temp[$k ] = $arr[$i ]; while ($j <= $right) $temp[$k ] = $arr[$j ]; for ($i = $left, $j = 0; $i <= $right; $i , $j ) $arr[$i] = $temp[$j];} function MergeSort(&$arr, $left, $right){ if ($left < $right) { $mid = floor(($left $right) / 2); MergeSort($arr, $left, $mid); MergeSort($arr, $mid 1, $right); Merge($arr, $left, $mid, $right); }}3、二分查找-递归function bin_search($arr,$low,$high,$value) { if($low>$high) return false; else { $mid=floor(($low $high)/2); if($value==$arr[$mid]) return $mid; elseif($value<$arr[$mid]) return bin_search($arr,$low,$mid-1,$value); else return bin_search($arr,$mid 1,$high,$value); }}4、二分查找-非递归function bin_search($arr,$low,$high,$value) { while($low<=$high) { $mid=floor(($low $high)/2); if($value==$arr[$mid]) return $mid; elseif($value<$arr[$mid]) $high=$mid-1; else $low=$mid 1; } return false;}5、快速排序function quick_sort($arr) { $n=count($arr); if($n<=1) return $arr; $key=$arr[0]; $left_arr=array(); $right_arr=array(); for($i=1;$i<$n;$i ) { if($arr[$i]<=$key) $left_arr[]=$arr[$i]; else $right_arr[]=$arr[$i]; } $left_arr=quick_sort($left_arr); $right_arr=quick_sort($right_arr); return array_merge($left_arr,array($key),$right_arr);}6、选择排序function select_sort($arr) { $n=count($arr); for($i=0;$i<$n;$i ) { $k=$i; for($j=$i 1;$j<$n;$j ) { if($arr[$j]<$arr[$k]) $k=$j; } if($k!=$i) { $temp=$arr[$i]; $arr[$i]=$arr[$k]; $arr[$k]=$temp; } } return $arr;}7、插入排序function insertSort($arr) { $n=count($arr); for($i=1;$i<$n;$i ) { $tmp=$arr[$i]; $j=$i-1; while($arr[$j]>$tmp) { $arr[$j 1]=$arr[$j]; $arr[$j]=$tmp; $j--; if($j<0) break; } } return $arr;}
<?php /** * Memcache 消息队列类 */ class QMC { const PREFIX = 'ASDFASDFFWQKE'; /** * 初始化mc * @staticvar string $mc * @return Memcache */ static private function mc_init() { static $mc = null; if (is_null($mc)) { $mc = new Memcache; $mc->connect('127.0.0.1', 11211); } return $mc; } /** * mc 计数器,增加计数并返回新的计数 * @param string $key 计数器 * @param int $offset 计数增量,可为负数.0为不改变计数 * @param int $time 时间 * @return int/false 失败是返回false,成功时返回更新计数器后的计数 */ static public function set_counter( $key, $offset, $time=0 ){ $mc = self::mc_init(); $val = $mc->get($key); if( !is_numeric($val) || $val < 0 ){ $ret = $mc->set( $key, 0, $time ); if( !$ret ) return false; $val = 0; } $offset = intval( $offset ); if( $offset > 0 ){ return $mc->increment( $key, $offset ); }elseif( $offset < 0 ){ return $mc->decrement( $key, -$offset ); } return $val; } /** * 写入队列 * @param string $key * @param mixed $value * @return bool */ static public function input( $key, $value ){ $mc = self::mc_init(); $w_key = self::PREFIX.$key.'W'; $v_key = self::PREFIX.$key.self::set_counter($w_key, 1); return $mc->set( $v_key, $value ); } /** * 读取队列里的数据 * @param string $key * @param int $max 最多读取条数 * @return array */ static public function output( $key, $max=100 ){ $out = array(); $mc = self::mc_init(); $r_key = self::PREFIX.$key.'R'; $w_key = self::PREFIX.$key.'W'; $r_p = self::set_counter( $r_key, 0 );//读指针 $w_p = self::set_counter( $w_key, 0 );//写指针 if( $r_p == 0 ) $r_p = 1; while( $w_p >= $r_p ){ if( --$max < 0 ) break; $v_key = self::PREFIX.$key.$r_p; $r_p = self::set_counter( $r_key, 1 ); $out[] = $mc->get( $v_key ); $mc->delete($v_key); } return $out; } } /** 使用方法: QMC::input($key, $value );//写入队列 $list = QMC::output($key);//读取队列 */ ?>