Archive for the ‘PHP/Mysql’ Category

php5.3开始出现的Function ereg() is deprecated Error问题解决办法

星期天, 二月 28th, 2010

PHP 5.3 ereg() 无法正常使用,提示“Function ereg() is deprecated Error”。问题根源是php中有两种正则表示方法,一个是posix,一个是perl,php6打算废除posix的正则表示方法所以后来就加了个preg_match。此问题解决办法很简单,在ereg前加个过滤提示信息符号即可:把ereg()变成@ereg()。这样屏蔽了提示信息,但根本问题还是没有解决,php在5.2版本以前ereg都使用正常,在5.3以后,就要用preg_match来代替ereg。所以就需要变成这样,原来:

ereg("^[0-9]*$",$page)

变成:

preg_match("/^[0-9]*$/",$page)

特别提醒:posix与perl的很明显的表达区别就是是否加斜杠,所以与ereg相比,后者在正则的前后分别增加了两个”/”符号,不能缺少。
Tips:此问题在php5.2之前版本不会出现。
=====================================
好心情不知从何而来,打开窗子暮然发现:下雪了。
=====================================
从蜘蛛发现discuz X在http://www.discuz.org开始测试了

discuz in iphone

星期六, 二月 27th, 2010

这两天一直在搞这个,话不多说,先上图:
0123

PHP基于二分法的手机号码归属查询与传统查询效率比较

星期一, 二月 1st, 2010

作者:刘华栋(xhat),2010年2月,个人原创,转载请注明出处
出于对算法对于系统的影响的好奇,决定实验性的在实际生产环境中研究一下算法对系统效率的影响。二分法最重要的是对有序数据的查询定位,例如手机号码就是一个很贴切的有序排列的数据例子。
如果数据量很小,例如只有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次便可准确定位),在更大量的数据的时候,查询效率或许能真的给人直观的反应。

附:本文程序演示地址:
基于二分法:http://www.liuhuadong.com/other/phone
基于传统算法查询:http://www.liuhuadong.com/other/phone/2.php
随后提供:模拟数据实验环境程序下载、生产环境下基于二分法的手机号码归属地查询程序下载

php对中文字符串的精准截取

星期三, 八月 19th, 2009

php在操作字符串的问题时间无非两个问题:
1.判断字符串编码是gbk还是unicode。
2.对相应编码采取相应截取方法。
下边3个函数即可实现此两点以达到精确截取中文字符串的目的:

// gbk截取中文字符串
function gbksub($str, $len) {
    
$tmpstr = "";
    
$strlen = $len;
    
for($i = 0; $i < $strlen; $i++) {
        
if(ord(substr($str, $i, 1)) > 0xa0) {
            
$tmpstr .= substr($str, $i, 2);
            
$i++;
        
} else
            
$tmpstr .= substr($str, $i, 1);
    
}
    
echo $tmpstr;
}
 
// utf-8 截取中文字符
function utfsub($str,$len)
{
    
for($i=0;$i<$len;$i++)
    
{
        
$temp_str=substr($str,0,1);
        
if(ord($temp_str) > 127)
        
{
            
$i++;
            
if($i<$len)
            
{
                
$new_str[]=substr($str,0,3);
                
$str=substr($str,3);
            
}
        
}
        
else
        
{
            
$new_str[]=substr($str,0,1);
            
$str=substr($str,1);
        
}
    
}
    
return join($new_str);
}
//判断字符编码
function is_gb2312($str)
{
    
for($i=0; $i<strlen($str); $i++) {
        
$v = ord( $str[$i] );
        
if( $v > 127) {
            
if( ($v >= 228) && ($v <= 233) )
            
{
                
if( ($i+2) >= (strlen($str) - 1)) return true;
                
$v1 = ord( $str[$i+1] );
                
$v2 = ord( $str[$i+2] );
                
if( ($v1 >= 128) && ($v1 <=191) && ($v2 >=128) && ($v2 <= 191) ) // utf编码
                    
return false;
                
else
                    
return true;
            
}
        
}
    
}
    
return true;
}

ajax计数器的实现

星期天, 七月 12th, 2009

本文代码实现页面计数器在无刷新情况下自动更新同步计数器数据。

<script language="javascript">
var xmlHttp;
function create(){
    
if(window.ActiveXObject){
        
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    
}
    
else if(window.XMLHttpRequest){
        
xmlHttp=new XMLHttpRequest();
    
}
}
function count(){
    
create();
    
xmlHttp.open("GET","http://www.xxx.com/3.php?aa="+Math.random());
    
xmlHttp.onreadyStatechange=handle;
    
xmlHttp.send(null);
}
function handle(){
    
if(xmlHttp.readyState==4){
        
if(xmlHttp.status==200){document.getElementById("jishu").innerHTML=escape(xmlHttp.responseText);}
    
}
}
function myShow(){
    
window.setInterval(count,5000);
}
<
/script>
<body onload="count();myShow();">
共有<span id="jishu"><
/span>人访问
<
/body>

需要注意的是xmlhttp在刷新的时间会使用缓存,所以需要在请求的地址上加随机数(Math.random)以防止使用缓存数据。另外setInterval与setTimeout的区别是前者为间隔循环执行,后者为定时执行一次。