手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

完美解决PHP中文乱码

关于以下内容,我对于数据库那段还真的不知道。。。原来可以通过这样的方式来强制执行我们一直会遗忘的那句话:set names utf8。。。

PHP中文乱码一般是字符集问题,编码主要有下面几个问题。

一.首先是PHP网页的编码

1.     php文件本身的编码与网页的编码应匹配

a.     如果欲使用gb2312编码,那么php要输出头:header(“Content-Type: text/html; charset=gb2312"),静态页面添加<meta http-equiv="Content-Type" content="text/html; charset=gb2312">,所有文件的编码格式为ANSI,可用记事本打开,另存为选择编码为ANSI,覆盖源文件。

b.     如果欲使用utf-8编码,那么php要输出头:header(“Content-Type: text/html; charset=utf-8"),静态页面添加<meta http-equiv="Content-Type" content="text/html; charset=utf-8">,所有文件的编码格式为utf-8。保存为utf-8可能会有点麻烦,一般utf-8文件开头会有BOM,如果使用 session就会出问题,可用editplus来保存,在editplus中,工具->参数选择->文件->UTF-8签名,选择总 是删除,再保存就可以去掉BOM信息了。

2.     php本身不是Unicode的,所有substr之类的函数得改成mb_substr(需要装mbstring扩展);或者用iconv转码。

二.PHP与Mysql的数据交互

PHP与数据库的编码应一致

1.     修改mysql配置文件my.ini或my.cnf,mysql最好用utf8编码

SQL代码
  1. [mysql]  
  2. default-character-set=utf8  
  3. [mysqld]  
  4. default-character-set=utf8  
  5. default-storage-engine=MyISAM  
  6. 在[mysqld]下加入:  
  7. default-collation=utf8_bin  
  8. init_connect='SET NAMES utf8'  

2.     在需要做数据库操作的php程序前加mysql_query("set names '编码'");,编码和php编码一致,如果php编码是gb2312那mysql编码就是gb2312,如果是utf-8那mysql编码就是 utf8,这样插入或检索数据时就不会出现乱码了

三.PHP与操作系统相关

         Windows和Linux的编码是不一样的,在Windows环境下,调用PHP的函数时参数如果是utf-8编码会出现错误,比如 move_uploaded_file()、filesize()、readfile()等,这些函数在处理上传、下载时经常会用到,调用时可能会出现下 面的错误:

PHP代码
  1. Warning: move_uploaded_file()[function.move-uploaded-file]:failed to open stream: Invalid argument in ...  
  2.   
  3. Warning: move_uploaded_file()[function.move-uploaded-file]:Unable to move '' to '' in ...  
  4.   
  5. Warning: filesize() [function.filesize]: stat failed for ... in ...  
  6.   
  7. Warning: readfile() [function.readfile]: failed to open stream: Invalid argument in ..  

 

     在Linux环境下用gb2312编码虽然不会出现这些错误,但保存后的文件名出现乱码导致无法读取文件,这时可先将参数转换成操作系统识别的编码,编码 转换可用mb_convert_encoding(字符串,新编码,原编码)或iconv(原编码,新编码,字符串),这样处理后保存的文件名就不会出现 乱码,也可以正常读取文件,实现中文名称文件的上传、下载。

    其实还有更好的解决方法,彻底与系统脱离,也就不用考虑系统是何编码。可以生成一个只有字母和数字的序列作为文件名,而将原来带有中文的名字保存在数据库 中,这样调用move_uploaded_file()就不会出现问题,下载的时候只需将文件名改为原来带有中文的名字。实现下载的代码如下

PHP代码
  1. header("Pragma: public");  
  2. header("Expires: 0");  
  3. header("Cache-Component: must-revalidate, post-check=0, pre-check=0");  
  4. header("Content-type: $file_type");  
  5. header("Content-Length: $file_size");  
  6. header("Content-Disposition: attachment; filename=\"$file_name\"");  
  7. header("Content-Transfer-Encoding: binary");  
  8. readfile($file_path);    

$file_type是文件的类型,$file_name是原来的名字,$file_path是保存在服务上文件的地址。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wufongming/archive/2008/11/08/3256186.aspx

一小段代码

群内突然有人【桔子】提问:

PHP代码
  1. $str = '0001';//这个数有可能是'001020'……请问怎么取到前导有多少个'0'?('0001'结果为3,'001020'结果为2)  

然后自问自答,说这些是他同事写的:

PHP代码
  1. //算法1  
  2. $str = '001020';  
  3. echo strlen(str_replace((int)$str''$str));  
  4.   
  5. //算法2  
  6. $text = '0001';  
  7. $zero = strlen($text) - strlen(ltrim($text'0'));  
  8. return $zero;  

然后说了他自己写的:

PHP代码
  1. $string = '000 012012';  
  2. $string = str_replace(' '''$string);  
  3. $length = strlen($string);  
  4.   
  5. $x = 0;  
  6. for ($i = 0; $i < $length$i++)  
  7. {  
  8. $currentStr = $string{$i};  
  9. if ($currentStr != 0)  
  10. {  
  11. break;  
  12. }  
  13. $x++;  
  14. }  
  15. echo $x;  

 

最后我也写了两个,一个正则,一个是利用现有函数:

 

PHP代码
  1. $str = '00 0 000100002000';  
  2. preg_match( "/^0{0,}/"str_replace" """$str ), $out );  
  3. echo$out[0] );  
  4.   
  5. $str = '00 0 000100002000';  
  6. $tt = str_word_count(str_replace" """$str ),1,'0');  
  7. echo$tt[0] );  

之所以要用str_replace,也是因为桔子说的,以防当中有空格。但事实上,如果出这种题目,应该是不会有空格的吧?

 

哈哈完事。。。

thinksns在整合Ucenter的时候注意事项

thinksns在整合ucenter的时候难度并不大。主要有几个思路,不要错过就行了

1、不要想着把thinkphp框架整合进去,那样只会让你效率大低
2、合理应用thinksns提供的API,在API里面有取得当前登录用户的资料等信息,而且也有一个比较完整的数据库操作类【主要是不需要再调用config等配置了】

3、利用ucenter整合的时候,只能利用thinksns的一个cookie: remembor【开始为了这个我折腾了半天,我一直都打成remember。。。。汗一下先】(由于现在我是在一台机器上试,对于$_SERVER['USER_AGENT']是否一致还没有完全测试。。。)

4、整合的两个重要环节就是同步登录和退出。登录的时候要注意一下,两边的密码机制不一样,第一次同步资料的时候需要注意一下,否则一旦整合就不能使用原来的密码了。

5、同步登录的时候,如果需要强制注册,则必须要调用$api->user_add($data)这样的方法,具体的变量参数可以参考thinksns的lib中的indexAction.class.php ,顺便说一下,它的代码,注册中的隐私,其实没有插数据库。。。。骗子啊

6、起初的时候,我考虑需要读系统配置,就调用了$api->option_get()结果出错,由于ucenter api的出错是不显示的。调试了半天,才发现。原来是option_get()调用的get方法中,居然有一个ts_cache函数,而这个函数却是在api的范围之外,即它是属于thinksns的common方法中,在api中并没有被包含进来。。导致无法执行出错。

其他就没啥了。。至于feed同步啥的,则需要一点点的测试和更新,以同步到thinksns的feed库中。是个劳心劳力的过程。

PS:我会把本文同步到http://www.ucapi.com/wiki/上

Tags: thinksns, ucenter

WordPress 2.9 beta1 发布

套用网上流行的一句:哥聊的不是天,哥聊的是寂寞,我也要在这里说,我讨论的不是wordpress,我讨论的是sablog

其实很有意思啦,明明是wordpress的新闻发布,结果评论却是sablog的拥护者在与wordpress拥护者火拼。偶尔也插上一个bo-blog用户的感慨
当然,这几个程序我都用过,最早在bo-blog出mysql版前,我也用过文本版的,那时候的程序很简单,安全性和实用性也一般。现在当然不一样了。
SAblog嘛,我就不说了,你看我的博客建立有多久,sablog就用了有多久。除了改过一些模版,程序我就几乎没有动过(当然前段时间sablog评论被攻击的时候,还是改了一下程序),虽然程序简单,但也毕竟几乎2年没有出过啥大漏洞。挺不错了除了模版是类似 phpwind 我不习惯外,其他都好
wordpress嘛。大而全,普通人上手也能用,后台也可以自动安装插件等,确实不错,只是后台嘛,略慢一点。别说我没有发言权,我在现在的服务器上有正好有三个BLOG,大家可以尝试一下
1、sablog ,就是本勃客啦。。。
2、bo-blog,http://www.fotonomad.org
3、wordpress,http://g.52cd.net

以下内容来自cnbeta。。。
WordPress 2.8.6安全更新刚刚几天,今天,11月16日,WordPress官方发布了WordPress 2.9的第一个测试版本:WordPress 2.9 beta 1。
beta版本都不太稳定,不喜欢折腾的朋友可以暂时不用升级,等正式版出来了再说;喜欢折腾的朋友,可以试试Wopus下面几篇文章中提到的新功能,特别 是WordPress 2.9提供的数据库修复、优化功能。现在WordPress官方还为在后台提示更新(目前的提示更新版本依然是:WordPress 2.8.6),所以需要测试的朋友,可以在文章最底下下载WordPress 2.9 beta 1,解压,上传覆盖。

两个老生常谈的问题:升级前请备份数据库;测试请尽量用官方英文版,请不要使用中文版。

WordPress 2.9对空间欢迎的要求:

数据库版本: MySQL 4.1.2 or 更高 (老版本只需要 4.0),之前Wopus也有过一篇文章:WordPress 2.9对空间环境要求更高:

WordPress 2.9对空间环境要求:

  • PHP 5
  • MySQL 4.1.2 or greater
  • The mod_rewrite Apache module


WordPress 2.9新增功能:(功能详解请查看原文)

WordPress 2.9功能:在线编辑图片

WordPress 2.9新功能:回收站

WordPress 2.9新功能:批量升级插件

WordPress 2.9新功能:修复、优化数据库

除了Wopus列出来的,还有很多功能,但基本上我们都体会不到,也就没有再一一列举。除此之外,WordPress 2.9对主题和插件的函数也有改动。详细请查看这里

比较引人瞩目的是,WordPress官方目前提供了两种下载格式,一种是IIS的,也就是Win系统服务器。现在加上伪静态的模块,Win系统服务器也可以完美的支持WordPress了。

WordPress 2.9 beta 1下载:

官方下载:Linux服务器版本 | IIS版本

地址为:http://www.cnbeta.com/articles/97982.htm

Tags: wordpress, sablog, bo-blog

Web应用中的轻量级消息队列

这个,又是老王的文章,队列,确实还是需要用到的。不过,我倒真没有想过用专业的队列消息数据库等来处理。我最初只是想把一些要队列的信息用SQLITE来处理,一边是往里推,一边是往外拉。拉一条删除一条。等到数据量太大的时候,就清除掉。

老王还是有介绍的,我在PHPRPC群里也听缘起缘灭和廖羽雷他们谈过专业的队列处理,但,我目前做的事情,还是用不了专业的队列处理,所以也就没有放在心上,不过,既然老王有介绍,也可以稍看看【原本我计划做个短信定时发送也就是准备用队列处理的,但最后没做,因为139邮箱里居然有类似功能,NND,抢我饭碗】

Web应用中为什么会需要消息队列?主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update 之类的请求同时到达mysql,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。在Web2.0的时代,高并发的情况越来越常见,从而使消息 队列有成为居家必备的趋势,相应的也涌现出了很多实现方案,像Twitter以前就使用RabbitMQ实现消息队列服务,现在又转而使用Kestrel来实现消息队列服务,此外还有很多其他的选择,比如说:ActiveMQZeroMQ等。

上述消息队列的软件中,大多为了实现AMQP,STOMP,XMPP之类的协议,变得极其重量级,但在很多Web应用中的实际情况是:我们只是想找到一个缓解高并发请求的解决方案,不需要杂七杂八的功能,一个轻量级的消息队列实现方式才是我们真正需要的。

第一感觉是能不能使用memcached来 实现消息队列?稍加考虑后就会发现它不合适,因为memcached仅仅支持键值方式的操作,没有排序之类的功能,所以如果要用它来实现消息队列,则必须 自己通过某个键来保存数组形式的队列,不过这样的话,在操作队列的时候很容易丢失数据,比如说我们要添加一个消息,则需先取出现有队列,然后把消息保存到 队列尾部,最后保存队列,单纯使用memcached的话,由于我们无法保证整个过程的原子性,所以当处理若干个并发请求时,各个请求间可能会互相覆盖, 丢失数据就在所难免。另外,memcached只是内存键值缓存而已,一旦宕机,数据就消失了。

memcacheq的出现解决了上面的问题,它在memcached的基础上实现了消息队列,以php客户端为例:

消息从尾部入栈:memcache_set
消息从头部出栈:memcache_get

memcacheq依附于memcached之上,所以你可以通过现有的memcached工具来操作它,这无疑是它的一大优势,但它也有一个很大的缺点,那就是memcacheq本身的开发维护似乎并不活跃,如果遇到问题的话,你很可能需要自己动手解决。

目前看来,我更推荐下面这种解决方案,那就是redis,如果不了解,可以参考我以前的文章,表面上看,redis和memcached差不多,也是键值操作,但是redis本身实现了list,相关操作也可以保证是原子的,所以可以很自然的通过list来实现消息队列:

消息从尾部入栈:RPUSH
消息从头部出栈:LPOP

redis本身虽然是一个新项目,但很有朝气,开发维护也很活跃,如果你的下一个Web应用里需要使用轻量级的消息队列,不妨使用它。

此外,还有不少其他的选择可供尝试,比如说MySQL第三方的Q4M引擎,通过扩展SQL语法来操作消息队列,也是一个不错的选择。

套用网络流行语:那些重量级软件实现的不是你要的功能,而只是独在高处不胜寒的寂寞,所以不必迷恋其中,它们只是传说而已。

--EOF--

原文链接:http://hi.baidu.com/thinkinginlamp/blog/item/27a18202578f3d054bfb511f.html