PHP几点精华 - php语言 -

PHP几点精华

时间:2010-02-25 10:29:27   来源:   评论:加载中...   点击:加载中...
我发现很多的PHP程序员,尤其是学习还不是很久的,都不知道PHP的精华所在。Perl当年如何在商界出名? 其强大的正则表达式。而PHP呢?他...

    我发现很多的PHP程序员,尤其是学习还不是很久的,都不知道PHP的精华所在。Perl当年如何在商界出名? 其强大的正则表达式。而PHP呢?他是一门从Unix下发展起来的语言,当然也就继承了Perl的很多特点,同时C的优点都有。快速、简洁、明了,尤其是 C程序员,PHP是至爱,我就是深爱着“PHP”(都忘了女友了:))。这里,我想来写一篇PHP的变量、数组应用技巧和PHP的正则表达式、PHP的模 板应用,以后有时间再写PHP与COM、PHP与XML的完全结合。  

1、变量、数组的应用技巧
(1)很多人用得不多的数组函 数。foreach、list、each。分别举几个例子,应该就能知道了。例:  
<?php 
$data = array('a' => 'data1', 'b' => 'data2', 'c' => 'data3');  
while(list($subscript, $value) = each($data))  
{  
  echo "$subscript => $value :: ";  
  echo "$subscript => $valuen<br>";  
}  

reset($data);  
foreach($data as $subscript => $value)  
{  
  echo "$subscript => $value :: ";  
  echo "$subscript => $valuen<br>";  
}  
(2) 函数的变量、变量的变量、变量的“指针”:看下例:  
<?php 
//变量的变量 
$var = "this is a var"; 
$varname = "var"; 
echo $$varname; 
// 函数的变量 
function fun1($str) { 
echo $str; 

$funname = "fun1"; 
$funname("This is a function !"); 
?>  
变 量的“指针”。这个指针加上了双引号,表明他不是真正的指针。看看下例:  
<?php 
function($a) { 
$a ++; 

$c = 0; 
function($c); 
echo $c; //$c 仍为0 
function(&$a) { 
$a ++; 

$c = 0; 
echo $c; //$c 为1 
?>  
之所以称其为“指针”,就是因为他有了和C语言中指针相同的功能。但这又不是真正的指针,只能够是这样的去理 解。  

 


2、正则表达式  
正则表达式是一个非常大的题目,Perl的正则表达式的强大是闻了名的。而PHP也不弱,他继承了 Perl的正则表达式法则,还有自己的一套法则。这里只说PHP自己的正则表达式。  
正则表达式是最基本的元素。简单地说就是一套规则,用于去 判定其它的元素是不是符合自身的规则,或者说是不是有相同的特征描述。  
正则表达式的开始符:^,结尾符$,这两个符号间的是匹配的元素。如检 查一个电话号码是不是打往北京的号,用正则表达式表示就是“^010$”。只要前3位区号是010,就是北京的号,后面的电话号码就不用管了。然后,用正 则表达式匹配函数ereg来判断,例:  
<?php 
$pattern = "^010$"; 
$phone = "01080718828"; 
if(ereg($pattern, $phone)) 
echo " 打往北京的号"; 
else 
echo "不是打往北京的号"; 
?>  
这就是正则表达式。北京的电话都是8位 数字的,那我要知道这个号码是不是正确了?假如他按了9位号呢?如果判断正误?这就要用到正则表达式的字符簇。那么上例的正则表达式就要这样 写:^010[0-9]$,就能同时判断号码是不是符合规则。正则表达式有很多的应用,像LBB、VBB论坛在发贴时的所谓VBB代码LBB代码的解析, 都是用正则表达式完成的。  

3、模板 
知道了正则表达式的功能,那么就可以知道模板了。什么是模板?举个例子吧?一般写网页用 到了后台程序的时候,都是在网页里面插入程序代码。如PHP。这就是HTML和PHP的混写。这样的优点是读取速度快,缺点是如果大家分工合作做网站,那 么非程序员就不会改网了。  
而用模板,则可以达到分工的最合理化。美工只做页面,程序只写后台,然后再合起来。优秀的Jsp提供了自定义标签的 功能很好地完成了模板功能。而主流的PHP如何做到呢?就是利用正则表达式来做到的。可以去网上下载一个PHPLIB,里面的PHP目录下有一个 template.inc的源代码文件,那就是用PHP实现模板套用的类。

由于篇幅有限,这里只是简单地说一说这些内容,如果真的想学的 话,还请看专门的教材。如光要讲清楚正则表达式就可以写上一本小书。
3.11. 记录所有的空语句 

总是记录下for或者是 while的空块语句,以便清楚的知道该段代码是漏掉了,还是故意不写的。 

while ($dest++ = $src++) 
; // VOID 

3.12. 不 要采用缺省方法测试非零值 

不要采用缺省值测试非零值,也就是使用: 

if (FAIL != f()) 
比下 面的方法好: 

if (f()) 

即使 FAIL 可以含有 0 值 ,也就是PHP认为false的表示。在某人决定 用-1代替0作为失败返回值的时候,一个显式的测试就可以帮助你了。就算是比较值不会变化也应该使用显式的比较;例如:if (! ($bufsize % strlen($str)))应该写成:if (($bufsize % strlen($str)) == 0)以表示测试的 数值(不是布尔)型。一个经常出问题的地方就是使用strcmp来测试一个字符等式,结果永远也不会等于缺省值。 
非零测试采用基于缺省值的做 法,那么其他函数或表达式就会受到以下的限制: 
· 只能返回0表示失败,不能为/有其他的值。 
· 命名以便让一个真(true)的返 回值是绝对显然的,调用函数IsValid()而不是Checkvalid()。 

3.13. 布尔逻辑类型 

大部分函 数在FALSE的时候返回0,但是发挥非0值就代表TRUE,因而不要用1(TRUE,YES,诸如此类)等式检测一个布尔值,应该用 0(FALSE,NO,诸如此类)的不等式来代替: 

if (TRUE == func()) { ... 
应该写成: 

if (FALSE != func()) { ... 

3.14. 通 常避免嵌入式的赋值 

有时候在某些地方我们可以看到嵌入式赋值的语句,那些结构不是一个比较好的少冗余,可读**强的方法。 

while ($a != ($c = getchar())) 

process the character 

++ 和--操作符类似于赋值语句。因此,出于许多的目的,在使用函数的时候会产生副作用。使用嵌入式赋值提高运行时**能是可能的。无论怎样,程序员在使用嵌 入式赋值语句时需要考虑在增长的速度和减少的可维护**两者间加以权衡。例如: 

a = b + c; 
d = a + r; 
不 要写成: 

d = (a = b + c) + r; 

虽然后者可以节省一个周期。但在长远来看,随着程序的维护费用渐 渐增长,程序的编写者对代码渐渐遗忘,就会减少在成熟期的最优化所得。 


4. 帮助与共享 

4.1. 重用您和 其他人的艰苦工作 

跨工程的重用在没有一个通用结构的情况下几乎是不可能的。对象符合他们现有的服务需求,不同的过程有着不同的服务需求 环境,这使对象重用变得很困难。 
开发一个通用结构需要预先花费许多的努力来设计。当努力不成功的时候,无论出于什么原因,有几种办法推荐使 用: 

4.2. 请教!给群组发Email求助 

这个简单的方法很少被使用。因为有些程序员们觉得如果他向其他人求助, 会显得自己水平低,这多傻啊!做新的有趣的工作,不要一遍又一遍的做别人已经做过的东西。 
如果你需要某些事项的源代码,如果已经有某人做过的 话,就向群组发email求助。结果会很惊喜哦! 
在许多大的群组中,个人往往不知道其他人在干什么。你甚至可以发现某人在找一些东西做,并且自 愿为你写代码,如果人们在一起工作,外面就总有一个金矿。 

4.3. 告诉!当你在做事的时候,把它告诉所有人 

如果你 做了什么可重用的东西的话,让其他人知道。别害羞,也不要为了保护自豪感而把你的工作成果藏起来。一旦养成共享工作成果的习惯,每个人都会获得更多。 

4.4. 小 型代码库 

对于代码重用,一个常见的问题就是人们不从他们做过的代码中做库。一个可重用的类可能正隐蔽在一个程序目录并且决不会有被分享 的激动,因为程序员不会把类分拆出来加入库中。 
这样的其中一个原因就是人们不喜欢做一个小库,对小库有一些不正确感觉。把这样的感觉克服掉吧, 电脑才不关心你有多少个库呢。 
如果你有一些代码可以重用,而且不能放入一个已经存在的库中,那么就做一个新的库吧。如果人们真的考虑重用的话, 库不会在很长的一段时间里保持那么小的。 

4.5. 知识库 

很多公司不清楚现有什么代码可用,而且大多数程序员仍然没 有通过沟通他们已经做过了什么,或者一直在询问现存什么代码可用。解决这个的方法是有一个可用的知识库。 
理想的情况是,程序员可以到一个WEB 页,浏览或者查询打包的知识库列表,找到他们所要的。建立一个程序员可以自动维护的知识库系统,是一个很不错的做法。如果有一个专门的管理员来负责维护这 个知识库,那当然更好。 
另一种方法是自动的从代码中产生知识库的做法。把通用的类、方法和标头(subsystem headers)作为手册 或者是知识库的一个条目。 


5. 书写注释 


5.1. 讲一个故事 

把你的注释当作描 述系统的一个故事。并且使得你的注释能被机器解析后,以固定的格式放到手册中去。类的注释是故事的一部分,方法的名称、方法的注释、方法的实现也是故事一 部分。所有的这些部分编织在一起,使得人们在以后的时间里能够准确的知道你干了什么,为什么这么做。 

5.2. 归档注释 

注 释的要归档才有意义,否则,假如在一个地方放一条注释描述你做了什么选择和你为什么这么做,只有考古学家才能发现这是最有用的信息。(如何归档另行规 范) 

5.3. 注释结构 

工程的每部分都有特定的注释结构。 程序中的注释,这里给出示例作为规范,注释中 以 * @ 为关键字的开始,以:为注释关键字结尾。 

5.3.1. 预定义关键字 

关键字 含义 
Purpose 表 示类、属**、方法要做些什么或者什么含义。 
Package Name 类名 
Author 作者 
Modifications 修 改记录(编号规则为“No”+日期+“-”+序号) 
See 参考 
Method Name 方法名 
Parameter 参数 名(包括类型) 
Return 返回值(包括类型) 
Attribute/Variable Name 属**/变量名 
Type 属**/ 变量类型 

5.3.2. 类的注释 

/** 
* @ Purpose: 
* 访问数据库的类,以 ODBC作为通用访问接口 
* @Package Name: Database 
* @Author: Forrest Gump gump@crtvu.edu.cn 
* @Modifications: 
* No20020523-100: 
* odbc_fetch_into() 参数位置第二和第三个位置调换 
* John Johnson John@crtvu.edu.cn 
* @See: (参 照) 
*/ 
class Database 

…… 


5.3.3. 方法注释 

/** 
* @Purpose: 
* 执 行一次查询 
* @Method Name: Query() 
* @Parameter: string $queryStr SQL 查询字符串 
* @Return: mixed 查询返回值(结果集对象) 
*/ 
function($queryStr) 

5.3.4. 属** 或变量注释 

/** 
* @Purpose: 
* 数据库连接用户名 
* @Attribute/Variable Name: mDbUserName 
* @Type: string 
*/ 
var mDbUserName; 

5.3.5. if (0) 来注释外部代码块 

有时需要注释大段的测试代码,最简单的方法就是使用if (0)块: 
function example() 

great looking code 

if (0) { 
lots of code 


more code 

你 不能使用/**/,因为注释内部不能包含注释,而大段的程序中可以包含注释。 

5.3.6. 目录文档 

所有的目录下都 需要具有README文档,其中包括: 
· 该目录的功能及其包含内容 
· 一个对每一文件的在线说明(带有link),每一个说明通常 还应该提取文件标头的一些属**名字。 
· 包括设置、使用说明 
· 指导人们如何连接相关资源: 
o 源文件索引 
o 在 线文档 
o 纸文档 
o 设计文档 
· 其他对读者有帮助的东西 
考虑一下,当每个原有的工程人员走了,在6个月之内来 的一个新人,那个孤独受惊吓的探险者通过整个工程的源代码目录树,阅读说明文件,源文件的标头说明等等做为地图,他应该有能力穿越整个工程。 


6. 其 他 


· 采用面向对象的设计方法; 

理由 
毫无疑问这是最接近人们自然思维的方法,可能前期会觉得没有 直接书写来得快,能否试着保留自己的看法?好戏在后头! 

· 类的定义采用一个文件一个类,并且类名和文件名相同; 

理 由 
o 越来越多的人接受了这种做法 
o 事实证明这种方法使得项目的逻辑结构更清晰 

· 类定义文件中,定义体之外不 得出现诸如echo、print等输出语句; 

理由 
出现这样的语句,应该当做出现bug来看。 

· 输出网页 的页面不出现SQL语句 

理由 
这是n层结构的编程思想所致,每层的任务不同,虽然可以越权行使,可能这样很快捷,但我们不赞成 这么干。 

· 进行SQL执行的数据必须进行有效**检测 

特殊符号: 
对于 MS SQL Server,’%_[ ] 这些符号都是在书写SQL语句中的特殊含义字符,在SQL执行前需要对这些字符进行处理。 
脚本符 号: 
对于PHP脚本标记, 如<??><%%><?php?><script lang<script language="php"& gt;</script>,在进入数据库前需要检测处理。 
理由 
这是数据库编程的一个约定,很多参考书上也是这么说,这里 需要强调一下。 

· 在HTML网页中尽量不要穿插PHP代码 

循环代码和纯粹变量输出(类似 于<?=$UserName?>)除外。 
理由 
o 需要说明的是我们工作的上游,页面设计者的工作,假如在页面中穿插代 码,将破坏结构,这应当是我们需要避免的。 
o 在这里的PHP代码只负责显示,多余的代码显然是不应该的。 

· 没有含义的数 字 

一个在源代码中使用了的赤裸裸的数字是不可思议的数字,因为包括作者,在三个月内,没人它的含义。例如: 
if (22 == $foo) { start_thermo_nuclear_war(); } 
else if (19 == $foo) { refund_lotso_money(); } 
else if (16 == $foo) { infinite_loop(); } 
else { cry_cause_im_lost(); } 
在 上例中22和19的含义是什么呢?如果一个数字改变了,或者这些数字只是简单的错误,你会怎么想? 
使用不可思议的数字是该程序员是业余运动员的 重要标志.
你应该用define()来给你想表示某样东西的数值一个真正的名字,而不是采用赤裸裸的数字,例如: 
define("PRESIDENT_WENT_CRAZY", "22"); 
define("WE_GOOFED", "19"); 
define("THEY_DIDNT_PAY", "16"); 

if (PRESIDENT_WENT_CRAZY == $foo) { start_thermo_nuclear_war(); } 
else if (WE_GOOFED == $foo) { refund_lotso_money(); } 
else if (THEY_DIDNT_PAY == $foo) { infinite_loop(); } 
else { happy_days_i_know_why_im_here(); } 
现 在不是变得更好了么?


7. PHP文件扩展名 


常见的PHP文件的扩展名 有:html, .php, .php3, .php4, .phtml, .inc, .class... 
这里我们约定: 

· 所 有浏览者可见页面使用.html 
· 所有类、函数库文件使用.php 

理由 

· 扩展名描述的是那种数据是用 户将会收到的。PHP是解释为HTML的。 


8. PHP代码标记 

统一使用<?php ?>,只 输出变量时<?=$username?>



相关热词搜索:

 
上一篇:PHP环境配置IIS5.0+PHP5.23+MYSQL5+phpMyAdmin
下一篇:PHP用XML-RPC构造Web Service
收藏 将此文推荐给朋友
分享到: