php对中文字符串的精准截取
星期三, 八月 19th, 2009php在操作字符串的问题时间无非两个问题:
1.判断字符串编码是gbk还是unicode。
2.对相应编码采取相应截取方法。
下边3个函数即可实现此两点以达到精确截取中文字符串的目的:
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本文代码实现页面计数器在无刷新情况下自动更新同步计数器数据。
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的区别是前者为间隔循环执行,后者为定时执行一次。
php判断ip黑名单
星期三, 七月 8th, 2009学校的新闻系统要求有些新闻只开放校内ip浏览,于是重写了一个代码来实现此功能,实现后的结果是,只要把允许访问的ip列入ip.txt这个文件中即可,同时支持c类ip,例如:
192.168
211.67.188
211.67.191.25
代码如下:
/*
* ip地址黑名单、白名单
* 判断访客地址的ip是否在ip.txt中,支持c类ip
* By xhat
*/
$ip = $_SERVER['REMOTE_ADDR'];
$ipArray = preg_replace("#\r\n?|\n#","",file('ip.txt'));
foreach ($ipArray as $ipTest) {
if (substr_count($ip, $ipTest) != "0") {
echo "ok"; //执行相关命令
die();
}
}
?>
php如何判断用户通过手机wap访问还是电脑直接访问
星期三, 四月 22nd, 2009最近做一个手机查询系统,自然就牵扯到了此问题,那我就根据对wap的认识浅谈下通过php判断用户访问方式是通过wap访问还是电脑直接访问。
首先说最根本的解决方法:
手机访问时,会附带发送user-agent信息,这个信息里面会有手机号码信息,那么如果能取得手机号码,则可以肯定是通过手机wap访问的。但是目前中国移动已经屏蔽了user-agent信息,所以获取不到手机号码。有关系的朋友可以联系移动公司,把wap网站服务器的ip提交给中国移动,加入白名单后即可取得ua信息。目前中国联通可以直接取到手机号,对联通用户此方案可完美实施。
接下来说我的解决方案:
手机访问,原理是手机通过移动公司的代理服务器进行的访问。那么我们就可以理解是一台普通电脑使用了代理服务器。当手机通过代理服务器访问的时候,http头信息会毫无疑问的包含一个信息:via。这个信息提供了有价值的判断信息。
例如河南移动取得的via信息是:
河南联通的via信息是:
其他各省的http头信息和这个大同小异,判断是否手机访问的方案就出来了:获取http的via信息字符串看是否包含wap字符,如果有则是通过手机访问。这样做的结果是没有人能伪造手机访问,判断绝对准确。自然,这样对于网上流行的手机wap模拟器也做了屏蔽—-从根本上屏蔽。
操作代码也很简单:
function check_wap() {
return stristr($_SERVER['HTTP_VIA'],"wap") ? true : false;
}
// check over
从我查阅的资料来看,目前此方法应该是迄今互联网上准确率最高、最简单的判断手机访问方法。
Mysql编码从latin1到utf8的转换
星期二, 十月 16th, 2007前一段时间有人要xctc旧bbs的数据库,我都不好意思给,原因是数据库编码问题我一直没有解决,给了别人打开肯定是一堆垃圾乱码。今天无论如何我是要解决这个问题,搞不定这个数据库誓不为人。
xctc这个数据库不像一般的数据库,编码中途经过很多次转换,采用的转换方法不全相通,而且mysql版本也不同,所以有一些表正常有一些表不正常,转来转去,总会出现一些乱码错误。当n年后的今天我重新打开这个数据库时,已经忘记了它的字符集,忘了它存在的版本,甚至忘了其中各表的含义。我的环境是mysql5.0.45,xctc数据库创建的时候应该是在 2001年,那时候的mysql最多算3.x,经过了4.x后的mysql5,不知道还有什么兼容性问题没(其实毫无疑问,大大的有)。首先把数据库加入到mysql5中,已经忘了当时的vbb的版本是多少,只好找个最新版本升级之,中间出错。分析表、修复表、优化表,再升级,升级成功,只是内容全是乱码。网上找很多资料,转换数据库字符集了很多次,都没有解决办法。最后根据对vbb的理解加上n多资料,终于解决这个问题。
字符集问题,导入数据库后phpmyadmin直接显示了数据库字符集为:latin1。这就好办了,把latin1转换为utf8就可以了。转的时候由于mysql版本的差异,所以导出时候需要加入 “–compatible=mysql40″参数。
D:\mysql5\bin>mysqldump -uroot -p --quick --compatible=mysql40 --default-character-set=latin1 --extended-insert=FALSE xctc > d:/xctc.sql
导出后,在phpmyadmin中新建一个数据库xctc2,字符编码设为utf8-general-ci。然后执行下列语句:
mysql -uroot -p --default-character-set=utf8 xctc2 < d:/xctc.sql
一般数据库导入不会有问题,但是xctc这个数据库中间转换太多,会有错误。错在word表,里面所有字段都是乱码,导入时会认为乱码部分为空,即所有字段内容都是空,这样就会出现记录重复。好在vbb对word表要求不高,只是一个关键词的表。解决办法是清空之,回头升级好了重建关键词即可。这样,数据库xctc2就是一个完整的utf8字符集的数据了。上传,修复,升级,重建,恢复模板。一切搞定。
新的数据已经在xctcbbs.cn上了(注:空间已挂,数据丢失) 。
discuz! 6.0 用email地址或用户名和密码登陆论坛
星期五, 九月 28th, 2007在我心目中,没有什么论坛能与vbb媲美了,但这不能决定我们论坛就必须要用vbb。与vbb相比,discuz论坛还是很有本地特色的,它们的关系就如google与baidu,各有出色之处。我一直关注vbb,因为它的强大,代码结构紧促,但并不高效。discuz解决了这个问题,代码依然强大,利用缓存大大提升了论坛性能。加之discuz开发团队在国内的专注与论坛本身的流行,国内的应用几乎可以完全用discuz取代vbb了。
这几天调试discuz,遇到一个问题。用email和密码登陆,而不是uid或用户名。在discuz官方搜了半天,也没发现解决方案,只好自己动手。仔细研究发现uid其实是一个多余的东西,完全没必要存在于表现层,只不过后台验证密码全部统一到uid上而已。我敢断定,discuz在不久的将来肯定会取消uid的登陆方式,要么不用,要么换成email登陆。废话少说,开始说标题提出问题的解决办法。
discuz!6现有的是用户名登陆,查看discuz的代码后发现,全部登陆都归结于uid的登陆。这样的话我们同样可以用email来检测数据库,以此作为用户名的补充。这时候可能出现email与用户名重复的可能,仔细查看源代码分析就能清楚,其实这无关紧要。例如用户名如果是email地址:a@b.com,email地址也是用户名所用的email:a@b.com,这样登陆的时候无论是用哪一个(用户名还是email)都是一个地址,登陆正常。如果用户名是email地址:aa@bb.com,而注册填的email为另外一个email如:aaa@bbb.com,这样登陆的时候无论用哪个地址登陆都返回正常。其实说白了,这只是一个视觉感受问题,与后台验证没什么关系;我们可能不愿意带有@或点的用户名,如果实在不爽,干脆去修改过滤代码去掉这两个东西就ok了。
言归正传,修改方法:打开根目录下logging.php,约在107行代码为:
把代码:WHERE m.$field=’$username’ ");
修改为:WHERE m.$field=’$username’ or m.email=’$username’");
修改完即可,不用其他多余操作。当然,登陆界面可以在用户名旁边加个用email也可以登陆的提示。
ok,但愿这个小动作能为你的论坛的用户增加一些新体验。
PHPer为什么被认为是草根
星期五, 三月 30th, 2007看到一篇文章:http://www.phpchina.com/?1/action_viewspace_itemid_2520.html
标题是:PHPer为什么被认为是草根?
看后受一些启发,给我自己有一些启发,也给我对更多phper有一层新的认识:说phper大部分是草根,是由于自己没有深入开发的结果,或说是大部分phper只是浅尝辄止。
程序员是辛苦的,是值得尊敬的,这是前提。
其实看待程序员还是要从技术角度结合人性两个方面考虑。我就见过很多程序员,利用浅尝辄止的技术开发出业务,不经意中蒙蔽了管理者,管理者又以不完整的思 维来控制团队和项目,形成一个阻止创新和发展的恶性循环;人性方面,作为程序员(当然有一批敢于创新且思进取),其自身的懒惰心理也导致了平庸的发生,其 实写程序就如做人,甚至在某些方面高于做人。
但愿更多的phper能摆脱草根的称号。
PHP判断来访者浏览器
星期六, 二月 10th, 2007前一段时间需要判断访问者是通过何种浏览器访问的,网上很多代码都不是很满意,看到有很多网友问到类似google的访问方式是怎么自动判断用户是手机还是pc访问的呢?没有找到答案,索性自己写个,自我感觉良好。
strstr($HTTP_USER_AGENT, "MSIE") ||
strstr(strtolower($HTTP_USER_AGENT), "avantgo") ||
strstr(strtolower($HTTP_USER_AGENT), "pendragonweb") ||
strstr(strtolower($HTTP_USER_AGENT), "j-"))
{
//html下判断浏览器类型
if(preg_match('/firefox\/(\S+)/si',$_SERVER['HTTP_USER_AGENT'],$tmp)){
echo "你的是Firefox浏览器,版本是 $tmp[1]";
}
else {
echo "你的是IE浏览";
}
//判断浏览器类型 end
}
else {
//判断为wap浏览器,打开页面wap.php
echo "你正在用手机浏览本站";
}
?>