??xml version="1.0" encoding="utf-8" standalone="yes"?>
1.不要依赖register_global=ON的环境,从你刚懂得配|phpq行环境甚至不明白register_global的ON/OFF会对自己有什么媄响的那天P应该勇敢地把它设ؓOFF.
2.写程序前看看怎么用error_reporting.
3.不懂问本n没错Q但你需要在那之前查查手册?br />4.当然Q你需要懂得用手册。手册上找不到答案的时候,应该考虑下网l上的搜索引擎?br />5.刚学会php+mysql之后Q不要叫L要写论坛Q要写XXX。要明白Q刚学会写汉字ƈ不表CZ有能力写诗?br />6.在学web~程的时候,你应该先去认识htmlq个朋友?br />7.有点能力后,试着回答新手的问题,不要看到自己懂的而别Z懂就沾沾自喜Q扔下一名“简单,那是基本的东襎쀝就走更要不得?br />8.思考是一个好习惯Q不动手dq于空惻I什么也没有?br />9.写好一D늨序,如果觉得很满意,一周后再看一遍,也许你会认ؓ它应该有所改变
10.有空多看看别人的E序Q找Z人的不或优点,自己掂量?br />
? 各取所需
1.善于使用“引用?它能直接影响到程序的效率?br />
2.善于用三元运子,可以让程式较_有效率?br />比如:
PHP代码:
if ($data[$i]['nickname'])
{
$nickname = $data[$i]['nickname'];
}
else
{
$nickname = $data[$i]['ip'];
}
可以写成:
PHP代码:
$nickname = $data[$i]['nickname'] ? $data[$i]['nickname'] : $data[$i]['ip'];
3.善于l织if...else...回圈
比如:
PHP代码:
$ext_name = strtolower(str_replace(".", "", strrchr($upfilename, ".")));
if (!empty($type))
{
if (!strpos($type, $ext_name))
{
echo "Please upload the file of $type form.";
exit();
}
}
上面的代码你应该写成q样:
PHP代码:
$ext_name = strtolower(str_replace(".", "", strrchr($upfilename, ".")));
if (!($type==='') && strpos($type, $ext_name)===false)
{
echo "Please upload the file of $type form.";
exit();
}
4.量让你的代码清淅些
如果写成q样Q是比较让h头痛?
PHP代码:
$foo=$_post["foo"];
$username=$_post["user"];
$group=$_POST["group"];
if ($group=="wheel"){
$username=$username."wheel";
}
同样的代码,q样比较让人看得舒服了:
PHP代码:
$foo = $_post["foo"];
$username = $_post["username"];
$group = $_POST["group"];
if ($group=="wheel")
{
$username = $username."wheel";
}
当然Q有一定基后,你应该要写成q样:
PHP代码:
$foo = &$_POST['foo'];
$username = $_POST["group"]!='wheel' ? $_POST["username"] : $_POST["username"].'wheel';
5.~写规范的mysql 语句?br />字段和表名用"`"引v来,避免保留字的影响?br />如果看到下面q样的一个sql queryQ会让h比较头痛:
PHP代码:
$query="select `flash_comment`.`content` , `flash_comment`.`nickname` , `flash_comment`.`date` , `flash_comment`.`ip` , `product`.`p_name` , `sgflash`.`fid` from `flash_comment` left join `product` on ( `flash_comment`.`p_no` = `product`.`p_no` ) left join `sgflash` on ( `product`.`p_name` = `sgflash`.`f_name` ) where `flash_comment`.`p_no` != '' order by `flash_comment`.`date`";
同样的一个query,写成q样׃o人看得明白得多了:
PHP代码:
$query = "SELECT `flash_comment`.`content` , `flash_comment`.`nickname` , `flash_comment`.`date` , `flash_comment`.`ip` , `product`.`p_name` , `sgflash`.`fid`
FROM `flash_comment`
LEFT JOIN `product` ON ( `flash_comment`.`p_no` = `product`.`p_no` )
LEFT JOIN `sgflash` ON ( `product`.`p_name` = `sgflash`.`f_name` )
WHERE `flash_comment`.`p_no` != ''
ORDER BY `flash_comment`.`date`";
?
以上每一步的转化都需要正的~码格式转化Q才能最l不出现q现象?br /> B、EJBcd不可以直接运行的支持c?如JavaBeanc?
׃EJBcd不可以直接运行的支持c,它们一般不与用L接交互输入和输出Q它们常怸其它的类q行交互输入和输出,所以它们在W二步被~译后,Ş成了内容是UNICODE~码的类保存在操作系l中了,以后只要它与其它的类之间的交互在参数传递过E中没有丢失Q则它就会正的q行?br />q种EJBcd不可以直接运行的支持c? 它的转化q程可用?更加明确的表C出来:
?
C、JSP代码和Servletc?br /> l过W二步后QJSP文g也被转化为ServletscLӞ只不q它不像标准的Servlets一校存在于classes目录中,它存在于WEB容器的时目录中Q故q一步中我们也把它做为Servlets来看?br /> 对于ServletsQ客Lh它时QWEB容器调用它的JVM来运行ServletQ首先,JVM把Servlet的classcMpȝ中读出ƈ装入内存中,内存中是以UNICODE~码的Servletcȝ代码Q然后JVM在内存中q行该Servletc,如果Servlet在运行的q程中,需要接受从客户端传来的字符如:表单输入的值和URL中传入的|此时如果E序中没有设定接受参数时采用的编码格式,则WEB容器会默认采用ISO-8859-1~码格式来接受传入的值ƈ在JVM中{化ؓUNICODE格式的保存在WEB容器的内存中。Servletq行后生成输出,输出的字W串是UNICODE格式的,紧接着Q容器将Servletq行产生的UNICODE格式的串Q如html语法Q用戯出的串等Q直接发送到客户端浏览器上ƈ输出l用P如果此时指定了发送时输出的编码格式,则按指定的编码格式输出到览器上Q如果没有指定,则默认按ISO-8859-1~码发送到客户的浏览器上。这UJSP代码和Servletc,它的转化q程可用?更加明确地表C出来:
?
D、JavaE序和数据库之间
对于几乎所有数据库的JDBC驱动E序Q默认的在JAVAE序和数据库之间传递数据都是以ISO-8859-1为默认编码格式的Q所以,我们的程序在向数据库内存储包含中文的数据ӞJDBC首先是把E序内部的UNICODE~码格式的数据{化ؓISO-8859-1的格式,然后传递到数据库中Q在数据库保存数据时Q它默认即以ISO-8859-1保存Q所以,q是Z么我们常常在数据库中d的中文数据是q?br /> 对于JAVAE序和数据库之间的数据传递,我们可以用图4清晰地表C出?/p>
?
3、分析常见的JAVA中文问题几个必须清楚的原?/b>
首先Q经q上面的详细分析Q我们可以清晰地看到QQ何JAVAE序的生命期中,其编码{换的关键q程是在于:最初编译成class文g的{码和最l向用户输出的{码过E?br /> 其次Q我们必M解JAVA在编译时支持的、常用的~码格式有以下几U:
*ISO-8859-1Q?-bit, ?859_1,ISO-8859-1,ISO_8859_1{编?br /> *Cp1252Q美国英语编码,同ANSI标准~码
*UTF-8Q同unicode~码
*GB2312Q同gb2312-80,gb2312-1980{编?br /> *GBK , 同MS936Q它是gb2312的扩?br /> 及其它的~码Q如韩文、日文、繁体中文等。同Ӟ我们要注意这些编码间的兼容关体系如下Q?br /> unicode和UTF-8~码是一一对应的关pRGB2312可以认ؓ是GBK的子集,即GBK~码是在gb2312上扩展来的。同ӞGBK~码包含?0902个汉字,~码范围为:0x8140-0xfefeQ所有的字符可以一一对应到UNICODE2.0中来?br /> 再次Q对于放在操作系l中?java源程序文Ӟ在编译时Q我们可以指定它内容的编码格式,具体来说?encoding来指定。注意:如果源程序中含有中文字符Q而你?encoding指定为其它的~码字符Q显然是要出错的。用-encoding指定源文件的~码方式为GBK或gb2312Q无论我们在什么系l上~译含有中文字符的JAVA源程序都不会有问题,它都会正地中文{化ؓUNICODE存储在class文g中?br />
然后Q我们必L楚,几乎所有的WEB容器在其内部默认的字W编码格式都是以ISO-8859-1为默认值的Q同Ӟ几乎所有的览器在传递参数时都是默认以UTF-8的方式来传递参数的。所以,虽然我们的Java源文件在出入口的地方指定了正的~码方式Q但其在容器内部q行时还是以ISO-8859-1来处理的?br />
4、中文问题的分类及其最优解军_?/b>
了解以上JAVA处理文g的原理之后,我们可以提Z一套徏议最优的解决汉字问题的办法?br /> 我们的目标是Q我们在中文pȝ中编辑的含有中文字符串或q行中文处理的JAVA源程序经~译后可以移值到M其它的操作系l中正确q行Q或拿到其它操作pȝ中编译后能正运行,能正地传递中文和英文参数Q能正确地和数据库交中英文字符丌Ӏ?br /> 我们的具体思\是:在JAVAE序转码的入口和出口及JAVAE序同用h输入输出转换的地斚w制编码方法之正即可?br /> 具体解决办法如下Q?br /> 1?针对直接在console上运行的c?br /> 对于q种情况Q我们徏议在E序~写Ӟ如果需要从用户端接收用L可能含有中文的输入或含有中文的输出,E序中应该采用字W流来处理输入和输出Q具体来_应用以下面向字符型节ҎcdQ?br /> ҎӞFileReaderQFileWrieter
其字节型节点类型ؓQFileInputStreamQFileOutputStream
对内存(数组Q:CharArrayReaderQCharArrayWriter
其字节型节点类型ؓQByteArrayInputStreamQByteArrayOutputStream
对内存(字符ԌQStringReaderQStringWriter
对管道:PipedReaderQPipedWriter
其字节型节点类型ؓQPipedInputStreamQPipedOutputStream
同时Q应该用以下面向字符型处理流来处理输入和输出Q?br /> BufferedWriterQBufferedReader
其字节型的处理流为:BufferedInputeStreamQBufferedOutputStream
InputStreamReaderQOutputStreamWriter
其字节型的处理流为:DataInputStreamQDataOutputStream
其中InputStreamReader和InputStreamWriter用于字节流按照指定的字W编码集转换到字W流Q如Q?br /> InputStreamReader in = new InputStreamReader(System.inQ?GB2312")Q?br /> OutputStreamWriter out = new OutputStreamWriter (System.outQ?GB2312")Q?br /> 例如Q采用如下的CZJAVA~码pC要求Q?br />//Read.java
import java.io.*;
public class Read {
public static void main(String[] args) throws IOException {
String str = "\n中文试Q这是内部硬~码的串"+"\ntest english character";
String strin= "";
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in,"gb2312")); //讄输入接口按中文编?br />BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(System.out,"gb2312")); //讄输出接口按中文编?br />stdout.write("误?");
stdout.flush();
strin = stdin.readLine();
stdout.write("q是从用戯入的Ԍ"+strin);
stdout.write(str);
stdout.flush();
}}
同时Q在~译E序Ӟ我们用以下方式来q行Q?br /> javac -encoding gb2312 Read.java
其运行结果如?所C:
?
2?针对EJBcd不可以直接运行的支持c?如JavaBeanc?
׃q种cd们本w被其它的类调用Q不直接与用户交互,故对q种cL_我们的徏议的处理方式是内部程序中应该采用字符来处理E序内部的中文字W串Q具体如上面一节中一PQ同Ӟ在编译类时用-encoding gb2312参数指示源文件是中文格式~码的即可?br /> 3?针对Servletc?br /> 针对ServletQ我们徏议用以下ҎQ?br /> 在编译Servletcȝ源程序时Q用-encoding指定~码为GBK或GB2312Q且在向用户输出时的~码部分用response对象的setContentType("text/html;charset=GBK");或gb2312来设|输出编码格式,同样在接收用戯入时Q我们用request.setCharacterEncoding("GB2312")Q这h论我们的servletcȝ植到什么操作系l中Q只有客L的浏览器支持中文昄Q就可以正确昄。如下是一个正的CZQ?br />//HelloWorld.java
package hello;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet
{
public void init() throws ServletException { }
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
request.setCharacterEncoding("GB2312"); //讄输入~码格式
response.setContentType("text/html;charset=GB2312"); //讄输出~码格式
PrintWriter out = response.getWriter(); //使用PrintWriter输出
out.println("< hr >");
out.println("Hello World! This is created by Servlet!试中文!");
out.println("< hr >");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
request.setCharacterEncoding("GB2312"); //讄输入~码格式
response.setContentType("text/html;charset=GB2312"); //讄输出~码格式
String name = request.getParameter("name");
String id = request.getParameter("id");
if(name==null) name="";
if(id==null) id="";
PrintWriter out = response.getWriter(); //使用PrintWriter输出
out.println("< hr >");
out.println("你传入的中文字串是:" + name);
out.println("< hr >你输入的id是:" + id);
out.println("< hr >");
}
public void destroy() { }
}
Ljavac -encoding gb2312 HelloWorld.java来编译此E序?br /> 试此Servlet的程序如下所C:
< %@page contentType="text/html; charset=gb2312"% >
< %request.setCharacterEncoding("GB2312");% >
< html >< head >< title >< /title >
< Script language="JavaScript" >
function Submit() {
//通过URL传递中文字W串值给Servlet
document.base.action = "./HelloWorld?name=中文";
document.base.method = "POST";
document.base.submit();
}
< /Script >
< /head >
< body bgcolor="#FFFFFF" text="#000000" topmargin="5" >
< form name="base" method = "POST" target="_self" >
< input name="id" type="text" value="" size="30" >
< a href = "JavaScript:Submit()" >传给Servlet< /a >
< /form >< /body >< /html >
其运行结果如?所C:
?
4?JAVAE序和数据库之间
为避免JAVAE序和数据库之间数据传递出Cؕ码现象,我们采用以下最优方法来处理Q?br /> 1?对于JAVAE序的处理方法按我们指定的方法处理?br /> 2?把数据库默认支持的编码格式改为GBK或GB2312的?br /> 如:在mysql中,我们可以在配|文件my.ini中加入以下语句实玎ͼ
在[mysqld]区增加:
default-character-set=gbk
q增加:
[client]
default-character-set=gbk
在SQL Server2K中,我们可以数据库默认的语a讄为Simplified Chinese来达到目的?br /> 5?针对JSP代码
׃JSP是在q行Ӟ由WEB容器q行动态编译的Q如果我们没有指定JSP源文件的~码格式Q则JSP~译器会获得服务器操作系l的file.encoding值来对JSP文g~译的,它在UL时最Ҏ出问题,如在中文win2k中可以很好运行的jsp文g拿到英文linux中就不行Q尽客L都是一LQ那是因为容器在~译JSP文g时获取的操作pȝ的编码不同造成的(在中文wink中的file.encoding和在英文Linux中file.encoding是不同的Q且英文Linux的file.encoding对中文不支持Q所以编译出来的JSPcd会有问题Q。网l上讨论的大多数是此c问题,多是因ؓJSP文gULq_时不能正显C的问题Q对于这c问题,我们了解了JAVA中程序编码{换的原理Q解册v来就Ҏ多了。我们徏议的解决办法如下Q?br /> 1、我们要保证JSP向客L输出时是采用中文~码方式输出的,x论如何我们首先在我们的JSP源代~中加入以下一行:
< %@page contentType="text/html; charset=gb2312"% >
2、ؓ了让JSP能正获得传入的参数Q我们在JSP源文件头加入下面一句:
< %request.setCharacterEncoding("GB2312");% >
3、ؓ了让JSP~译器能正确地解码我们的含有中文字符的JSP文gQ我们需要在JSP源文件中指定我们的JSP源文件的~码格式Q具体来_我们在JSP源文件头上加入下面的一句即可:
< %@page pageEncoding="GB2312"% >?amp;lt %@page pageEncoding="GBK"% >
q是JSP规范2.0新增加的指o?br /> 我们使用此方法来解JSP文g中的中文问题Q下面的代码是一个正做法的JSP文g的测试程序:
//testchinese.jsp
< %@page pageEncoding="GB2312"% >
< %@page contentType="text/html; charset=gb2312"% >
< %request.setCharacterEncoding("GB2312");% >
< %
String action = request.getParameter("ACTION");
String name = "";
String str = "";
if(action!=null && action.equals("SENT"))
{
name = request.getParameter("name");
str = request.getParameter("str");
}
% >
< html >
< head >
< title >< /title >
< Script language="JavaScript" >
function Submit()
{
document.base.action = "?ACTION=SENT&str=传入的中?;
document.base.method = "POST";
document.base.submit();
}
< /Script >
< /head >
< body bgcolor="#FFFFFF" text="#000000" topmargin="5" >
< form name="base" method = "POST" target="_self" >
< input type="text" name="name" value="" size="30" >
< a href = "JavaScript:Submit()" >提交< /a >
< /form >
< %
if(action!=null && action.equals("SENT"))
{
out.println("< br >你输入的字符为:"+name);
out.println("< br >你通过URL传入的字WؓQ?+str);
}
% >
< /body >
< /html >
如图7是此E序q行的结果示意图Q?br />
?
5、ȝ
在上面的详细分析中,我们清晰地给ZJAVA在处理源E序q程中的详细转换q程Qؓ我们正确解决JAVA~程中的中文问题提供了基。同Ӟ我们l出了认为是最优的解决JAVA中文问题的办法?br /> 6、参考资?/b>
1、段明辉.Java ~程技术中汉字问题的分析及解决.
http://www-900.ibm.com/developerWorks/cn/java/java_chinese/index.shtml
2?周竞?关于Java中文问题的几条分析原?br /> http://www-900.ibm.com/developerWorks/cn/java/l-javachinese/index.shtml
7、作者介l?/b>
作者:abnerchaiQ高U程序员Q作者联pL法:josserchai@yahoo.com
Z实现web层(strutsQ和持久层(HibernateQ之间的松散耦合Q我们采用业务代表(Business DelegateQ和DAOQData Access ObjectQ两U模式。DAO模式Z减少业务逻辑和数据访问逻辑之间的耦合Q当一个持久曾框架被应用时Q该模式会减少业务对象和该框架之间的耦合Q这h们可以不修改业务对象而选择不同的持久层框架的实现。实际上在DAO模式中包含两U结构模式:桥(BridgeQ模式和适配器(AdaptorQ模式。?/font>
对表现层Q我们?/font>
Struts
Q业务层使用
Spring
Q对于持久层我们使用的是
Hibernate
。你可以取代这里的某个框架而用你喜欢的框架已辑ֈ同样的效果。下图显CZ框架被整合v来时Q从最高层ơ看到的视图?br />
应用?/strong>
许多设计良好的web应用Q可以被按职责分为四层。这些层ơ是表现层、持久层、业务层、和领域模型层。每一个层ơ都有其独特的职责,不能把各自的功能与其它层ơ相混合。每一个应用层都应该和其它层隔d来,但允怋用接口在层间q行通信。我们开始来看看每个层,q讨Z下它们各自都应该提供什么和不应该提供什么?/font>
表现?/strong>
一个典型的web 应用的末端是表现层。许多Java 开发者都知道Struts提供了什么东ѝ然而,太多时候,耦合代码比如业务逻辑被放qorg.apache.struts.Action中。所以,我们先ȝ一下Struts之类的框架应该提供什么。下面就是Struts 的职责所在:
下面是一些经常可以用Strutsq行~码但是不应该和表现层关联的事情Q?/font>
在表现层中引入这些类型的代码导致类型耦合和维护负担?/font>
持久?/strong>
一个典型Web应用的另一端是持久层。这也是应用中最Ҏ很快失控的地斏V开发者通常低估了自己构q持久层框架的挑战。一个定制的Q内部开发的持久层不仅需要大量的开发时_q且通常~Z功能和难以管理。目前有许多解决q些问题的开源对象关pL?(ORM) 框架。特别地QHibernate 框架允许Java中的对象-关系的持久性和查询服务。Hibernate 对已l熟悉了SQL 和JDBC API的Java开发者来或具有中度的学习曲线。Hibernate 的持久对象基于POJO和Java集QcollectionsQ。此外,使用Hibernate 不和你的IDE接口。下面列Z你需要在持久性框架中~写的代码类型:
下面是应该在持久层避免的一些事情:
业务层应该负责下面的问题Q?/font>
private long id;
private String name;
public void setId(long id) {
this.id = id;
}
public void setName(String name) {
this.name=name;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
}
POJO对象有时也被UCؓData对象Q大量应用于表现现实中的对象?