关于Apache默认编码错误,导致网站乱码的解决方案

最近经常有同学在使用LAMP/WAMP时,遇到这样的编码错误问题:

A网站程序编码UTF-8编码安装成功,运行成功。

B网站程序编gb2312也要安装在同一服务器上。

这样就出现问题了,Apache默认编码UTF-8在解析A网站的时候没有任何问题,当运行B网站时出现的”蝌蚪文”乱码问题。

单纯的修改Apache默认编码为gb2312这样就导致A网站出现”蝌蚪文”。

问题分析:

如果你在网上搜索 “apache配置”,搜到的页面大多都会建议你在httpd.conf中加上这么一句:AddDefaultCharset GB2312。

对于新手而且是只用GB2312编码的开发人来说,这么做是ok的。但是如果要想使用UTF-8字符集的话,比如 在test.php文件中需要有 meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ 这段代码。

这时你再打开浏览器访问test.php页面的话,你看到的是正确的页面。但是如果实际上浏览器还是以GB2312编码解释从服务器返回的response,为什么呢?原因是浏览器是根据http应答消息头部中的 Content-type: text/html; charset=GB2312 来决定使用何种编码解释应答,也就是说apache服务器仍然用GB2312编码传递数据。

所以说如果apache的默认字符集被设置成了GB2312,即使在页面中声明使用UTF-8编码,apache服务器还是会按照GB2312编码来传送http response。没关系,我们把AddDefaultCharset GB2312 改成 AddDefaultCharset UTF-8,看看什么结果?

如果你看到乱码恭喜你,你还知道是乱码问题;如果你看到是空白页面,那么你就惨了,你可能会以为这是其他什么原因造成的,而不会从编码的角度去考虑怎么解决问题。这是为什么?原因在于php文件本身是用系统字符集来编码的,中文的windows XP都是用GB2312,每一个文件头部都有字段指示该文件是用何种方式编码的。当apache接到浏览器的请求后,会让php去解释所请求的页面,比如 test.php。php会识别出test.php的编码方式是GB2312后(就像我们用javac编译java源文件时,编译器默认用系统编码读源文件里的内容。

如果源文件不是用系统编码来保存的,可以用命令javac -encoding指定具体的编码),把数据以GB2312的编码格式传递给apache,而apache服务器不会改变从php传来的数据,只是在应答消息头部中把字符集设置成UTF-8: Content-type: text/html; charset=UTF-8. 也就是说你传递的是GB2312编码的数据,而浏览器却以UTF-8编码来解释应答消息。

由于UTF-8为3个字节表示一个汉子,而普通的GB2312或BIG5是两个。页面输出时,由于上述原因,出现半个汉字的情况,这时该半个汉字会和的>结合成一个乱码字,导致IE无法读完的话,会发现实际上整个叶面全部已经输出了。如果使用的是Mozilla、Mozilla Firefox、Sarafi的浏览器这不会造成这个问题,而是一堆乱码。这是由于Firefox浏览器和IE解析网页编码的策略不同产生的。OK,我们把test.php以UTF-8保存,再用浏览器访问时,就没有问题了。

可这样做,会使得apache目录下的所有web应用只能用同一种编码。如何搞定?

解决办法:

首先,可以使用AddDefaultCharset off来关闭默认文件编码,这样apache服务器就不会在http应答消息头部设置charset,只是设置Content-type: text/html. 而浏览器就会依靠html文件中设置的harset来决定编码。

其次,脚本php.ini文件中的default_charset = “UTF-8″作用同httpd.conf文件,把该行注释掉,使php自动识别文件的编码方式。

这样不论你用什么编码方式,只要test.php中的meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ 与你test.php文件编码方式相同,就不会产生乱码问题。用户提交数据的编码浏览器提交的字符编码由客户端的characher encoding决定。

例如,当前浏览器的编码是Gb2312,用户提交数据后,无论apache设置的编码方式是GB2312还是UTF-8,这时在服务器端接收到的仍是以Gb2312编码的数据。

如果要在返回页面上显示用户刚才提交的数据,而该页面是用UTF-8编码的或者要在数据库中存储的用户提交的数据,而数据库是UTF-8编码的,那就要做字符转换了。

 

转载自:http://www.cnblogs.com/wendywu/archive/2011/12/06/2278537.html

浅析PHP模板引擎之二

上篇文章我简要的介绍下模板引擎的运行机理,但是过于简单不太实用,下面我继续扩展这一问题,并使它成为轻量型引擎。

首先我们建立三个目录 ./templates ./templates_c    ./lib 这三个目录分别放模板文件、经过编译后生成的文件、引擎代码文件

下面放上运行原理图:

下面写上各个部分代码:

1.模板引擎template.class.php代码:

< ?php  class template{  private $template_c;  private $data=array();  public function __set($name,$value){  if(!array_key_exists($name,$this->data)){
$this->data[$name]=$value;
}else{
$this->data[$name]=$value;
}

}
public function display($templatename){
$this->template_c=file_get_contents('./templates/'.$templatename);
foreach($this->data as $name => $value){

$this->template_c=str_replace('{'.$name.'}',$value,$this->template_c);

}
echo $this->template_c;

}

}

模板test.tpl代码:

我的名字是 {name}
 手机号 {telephone}
 性别{sex}
 口头禅是{say}

index.php代码:

< ?php  Header('Content-type:text/html;charset=utf-8'); require_once  "./lib/template.class.php"; $template= new template; $template->name="lvxinwei";
$template->telephone=15151827622;
$template->sex="男";
$template->say="我勒个去";
$template->display('test.tpl');

显示效果:
我的名字是 harold
手机号 151518276xx
性别男
口头禅是我勒个去
在第三节,我会继续扩展该问题,使之能进行智能化的页面缓存;

浅析PHP模板引擎运行的机理

PHP有相当多的模板引擎,比较出名的也是笔者比较喜欢的有smarty引擎。

模板引擎的机理是分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目的就是要使PHP程序员同前端人员分离,使程序员改变程序的逻辑内容不会影响到前端人员的页面设计,前端人员重新修改页面不会影响到程序的程序逻辑,这在多人合作的项目中显的尤为重要。

下面我通过编写的一个类简要的说明运行机理。

首先我说下大致的使用过程:

1.引入模板引擎,可以通过类中的–autoload()方法自动加载相应类。

2.给相应的要生成的动态内容赋值。例如在smarty中通过$smarty->assign(“name”,$value);给name赋予$value值,但是查询
name的值的过程交给程序员做。

3.调用方法生成动态内容。$smarty->display(“test.tpl”);

下面写上我写的一个缩小型模板引擎

class template {

private $vars=array();
public function setattributes($name,$value){
$this->vars[$name]=$value;

}
public function getHtml($html){
foreach($this->vars as $name=>$value){
$html=str_replace(‘{‘.$name.’}’,$value,$html);
}
return $html;

}
}
$template =new template;
$template->setattributes(“name”,”lvxinwei”);
echo $template->getHtml(“I am  {name} “);

可以看到我输入“ I am {name}” 输出“my lvxinwei”;

原理就是将变量值以key-value对储存起来。然后处理输入用键值替换键名。

当然这个引擎不是很实用但是说明了模板引擎运行机理。


svn在linux下的使用(svn命令行) 删除 新增 添加 提交 状态查询 恢复

 

1、将文件checkout到本地目录
svn checkout path(path是服务器上的目录)
例如:svn checkout svn://192.168.1.1/pro/domain
简写:svn co

2、往版本库中添加新的文件
svn add file
例如:svn add test.php(添加test.php)
svn add *.php(添加当前目录下所有的php文件)

3、将改动的文件提交到版本库

svn commit -m “LogMessage” [-N] [–no-unlock] PATH(如果选择了保持锁,就使用–no-unlock开关)
例如:svn commit -m “add test file for my test” test.php
简写:svn ci

4、加锁/解锁
svn lock -m “LockMessage” [–force] PATH
例如:svn lock -m “lock test file” test.php
svn unlock PATH

5、更新到某个版本
svn update -r m path
例如:
svn update如果后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本。
svn update -r 200 test.php(将版本库中的文件test.php还原到版本200)
svn update test.php(更新,于版本库同步。如果在提交的时候提示过期的话,是因为冲突,需要先update,修改文件,然后清除svn resolved,最后再提交commit)
简写:svn up

6、查看文件或者目录状态
1)svn status path(目录下的文件和子目录的状态,正常状态不显示)
【?:不在svn的控制中;M:内容被修改;C:发生冲突;A:预定加入到版本库;K:被锁定】
2)svn status -v path(显示文件和子目录状态)
第一列保持相同,第二列显示工作版本号,第三和第四列显示最后一次修改的版本号和修改人。
注:svn status、svn diff和 svn revert这三条命令在没有网络的情况下也可以执行的,原因是svn在本地的.svn中保留了本地版本的原始拷贝。
简写:svn st

7、删除文件
svn delete path -m “delete test fle”
例如:svn delete svn://192.168.1.1/pro/domain/test.php -m “delete test file”
或者直接svn delete test.php 然后再svn ci -m ‘delete test file‘,推荐使用这种
简写:svn (del, remove, rm)

8、查看日志
svn log path
例如:svn log test.php 显示这个文件的所有修改记录,及其版本号的变化

9、查看文件详细信息
svn info path
例如:svn info test.php

10、比较差异
svn diff path(将修改的文件与基础版本比较)
例如:svn diff test.php
svn diff -r m:n path(对版本m和版本n比较差异)
例如:svn diff -r 200:201 test.php
简写:svn di

11、将两个版本之间的差异合并到当前文件
svn merge -r m:n path
例如:svn merge -r 200:205 test.php(将版本200与205之间的差异合并到当前文件,但是一般都会产生冲突,需要处理一下)

12、SVN 帮助
svn help
svn help ci

——————————————————————————

以上是常用命令,下面写几个不经常用的

——————————————————————————

13、版本库下的文件和目录列表
svn list path
显示path目录下的所有属于版本库的文件和目录
简写:svn ls

14、创建纳入版本控制下的新目录

svn mkdir: 创建纳入版本控制下的新目录。
用法: 1、mkdir PATH…
2、mkdir URL…
创建版本控制的目录。
1、每一个以工作副本 PATH 指定的目录,都会创建在本地端,并且加入新增
调度,以待下一次的提交。
2、每个以URL指定的目录,都会透过立即提交于仓库中创建。
在这两个情况下,所有的中间目录都必须事先存在。

15、恢复本地修改

svn revert: 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。revert:
用法: revert PATH…
注意: 本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复
被删除的目录

16、代码库URL变更

svn switch (sw): 更新工作副本至不同的URL。
用法: 1、switch URL [PATH]
2、switch –relocate FROM TO [PATH…]

1、更新你的工作副本,映射到一个新的URL,其行为跟“svn update”很像,也会将
服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的
方法。
2、改写工作副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变动
(比如方案名或是主机名称变动),但是工作副本仍旧对映到同一仓库的同一目录时使用
这个命令更新工作副本与仓库的对应关系。

17、解决冲突

svn resolved: 移除工作副本的目录或文件的“冲突”状态。
用法: resolved PATH…
注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的
相关文件,然后让 PATH 可以再次提交。

18、输出指定文件或URL的内容。

svn cat 目标[@版本]…如果指定了版本,将从指定的版本开始查找。
svn cat -r PREV filename > filename (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)

在linux ftp操作命令

FTP>ascii: 设定以ASCII方式传送文件(缺省值)

FTP>bell: 每完成一次文件传送,报警提示.

FTP>binary: 设定以二进制方式传送文件.

FTP>bye: 终止主机FTP进程,并退出FTP管理方式.

FTP>case: 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母.

FTP>cd: 同UNIX的CD命令.

FTP>cdup: 返回上一级目录.

FTP>chmod: 改变远端主机的文件权限.

FTP>close: 终止远端的FTP进程,返回到FTP命令状态, 所有的宏定义都被删除.

FTP>delete: 删除远端主机中的文件.

FTP>dir [remote-directory] [local-file] 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件.

FTP>get [remote-file] [local-file] 从远端主机中传送至本地主机中.

FTP>help [command] 输出命令的解释.

FTP>lcd: 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录.

FTP>ls [remote-directory] [local-file] 同DIR.

FTP>macdef: 定义宏命令.

FTP>mdelete [remote-files] 删除一批文件.

FTP>mget [remote-files] 从远端主机接收一批文件至本地主机.

FTP>mkdir directory-name 在远端主机中建立目录.

FTP>mput local-files 将本地主机中一批文件传送至远端主机.

FTP>open host [port] 重新建立一个新的连接.

FTP>prompt: 交互提示模式.

FTP>put local-file [remote-file] 将本地一个文件传送至远端主机中.

FTP>pwd: 列出当前远端主机目录.

FTP>quit: 同BYE.

FTP>recv remote-file [local-file] 同GET.

FTP>rename [from] [to] 改变远端主机中的文件名.

FTP>rmdir directory-name 删除远端主机中的目录.

FTP>send local-file [remote-file] 同PUT.

FTP>status: 显示当前FTP的状态.

FTP>system: 显示远端主机系统类型.

FTP>user user-name [password] [account] 重新以别的用户名登录远端主机.

FTP>? [command]: 同HELP. [command]指定需要帮助的命令名称。如果没有指定 command,ftp 将显示全部命令的列表。

FTP>! 从 ftp 子系统退出到外壳。