同任何语言一样,开发人员用PHP编写的代码可以有优劣之分。养成良好的编程习惯,可以帮助你编写出更有效的代码,可谓事半功倍。一个好的开发人员凭借他的经验和良好的工作习惯可以编写更有效率的代码。
当不好的编程习惯渗透到你的代码中则会降低代码的效用。本文演示了一些良好的编程习惯,有助于你成为更好的程序员。
除了让您建立的代码更有成效,这些习惯还可以实现程序中代码的可持续利用。你很可能大部分时间都花在维护程序上;应用程序维护是一笔很大的开支。养成良好的编码习惯将提高模块化设计等要素,而您的代码也更容易被理解,因此,维护起来就更便宜更容易了。
不良的编码习惯似乎与有缺陷的代码如影随形,它可能导致代码难以改变。以下五个良好的习惯,在你使用PHP编码时可以帮助你避免这些陷阱
适当命名
适当命名是最重要的习惯,因为描述性的名称使代码更易于阅读和理解。易懂的代码最终决定它是否能够一直保存下去。如果你的代码很容易理解,即使 它不包含任何注释,那么,必要的时候,该代码无论是对你还是对于其他人来说都是易于改变的。你学习这一好习惯的目标应该是适当命名以使您的代码读起来就像 一本书。
坏习惯:模棱两可或晦涩的命名
例一显示的代码,其中包括过短的变量名,缩写是很难理解的,而且方法的名称并没有清楚地说明。方法的名称意味着方法正做一件事。如果他们还在做些别的事情,那就会出问题,因为他们被误导了。
例一:
function getNBDay($d)
{
switch($d) {
case 5:
case 6:
case 7:
return 1;
default:
return ($d + 1);
}
}
$day = 5;
$nextDay = getNBDay($day);
echo ("Next day is: " . $nextDay . "\n");
?>
好习惯:考虑周详并且简明的命名
例二显示的代码,利用良好的命名习惯。方法被重新命名从而更好地反映了它们做了什么以及为什么。变量更名后更具描述性,并且仅剩一个短的循环变量$i,。尽管许多人可能有异义,但短的循环变量是可以接受的,甚至还更好,因为这可以明确指示功能。
例二:
define (‘MONDAY’, 1);
define (‘TUESDAY’, 2);
define (‘WEDNESDAY’, 3);
define (‘THURSDAY’, 4);
define (‘FRIDAY’, 5);
define (‘SATURDAY’, 6);
define (‘SUNDAY’, 7);
/*
*
* @param $dayOfWeek
* @return int Day of week, with 1 being Monday and so on.
*/
function findNextBusinessDay($dayOfWeek)
{
$nextBusinessDay = $dayOfWeek;
switch($dayOfWeek) {
case FRIDAY:
case SATURDAY:
case SUNDAY:
$nextBusinessDay = MONDAY;
break;
default:
$nextBusinessDay += 1;
break;
}
return $nextBusinessDay;
}
$day = FRIDAY;
$nextBusDay = findNextBusinessDay($day);
echo ("Next day is:" . $nextBusDay . "\n");
?>
我们鼓励您分解大的条件,然后用条件来命名方法。这一技巧使代码更易于阅读且使条件更具体,因而可以被抽取,甚至被重复使用。如果该条件语句有变化,就更易于更新。由于该方法有一个有意义的名称,代码不会失去其意义或变得难以阅读。
细分代码
人们很容易专注于解决问题,然后马上开始编码。在你解决紧迫问题时,您只顾敲键盘而不去注意函数越来越长。只要你检查并把代码分得更细,那从长远来看,这不是一个问题。
重构是一个伟大的想法,但你应养成编短码的习惯。较短的方法可在一个窗口中显示,所以易于理解。当一个方法太长了,就增加了理解的难度,因为你不能迅速跟进整个工作流程。
当写方法时,你还应该养成构建的习惯。有几个理由让你接受这样辛劳的编写。第一,当方法只做一件事并且做得很好时,它更容易被重复使用。其次,这种方法有易于测试。第三,这种方法更容易理解和变动。
坏习惯:过长的函数
例三显示了一组很长的函数。这会带来其他一些问题。它做了很多事,意图不明确。这将是难以理解的,而且也很难进行调试和测试。它遍布整个文件,并建立一个条目列表,它给对象分配了值,还进行了计等等。
例三:
function writeRssFeed($user)
{
// Get the DB connection information
// look up the user’s preferences…
$link = mysql_connect(‘mysql_host’, ‘mysql_user’, ‘mysql_password’)
OR die(mysql_error());
// Query
$perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= ‘%s’",
mysql_real_escape_string($user));
$result = mysql_query($query, $link);
$max_stories = 25; // default it to 25;
if ($row = mysql_fetch_assoc($result)) {
$max_stories = $row[‘max_stories’];
}
// go get my data
$perfsQuery = sprintf("SELECT * FROM stories WHERE post_date = ‘%s’",
mysql_real_escape_string());
$result = mysql_query($query, $link);
$feed = "" .
"" .
"" .
"http://www.example.com/feed.xml" .
"The best feed in the world" .
"en-us" .
"Tue, 20 Oct 2008 10:00:00 GMT" .
"Tue, 20 Oct 2008 10:00:00 GMT" .
"http://www.example.com/rss" .
"MyFeed Generator" .
"editor@example.com" .
"webmaster@example.com" .
"5";
// build the feed…
while ($row = mysql_fetch_assoc($result)) {
$title = $row[‘title’];
$link = $row[‘link’];
$description = $row[‘description’];
$date = $row[‘date’];
$guid = $row[‘guid’];
$feed .= "";
$feed .= "";
$feed .= "" . $link . "";
$feed .= " " . $description . "";
$feed .= "" . $date . "";
$feed .= "" . $guid . "";
$feed .= "";
}
$feed .= "
// write the feed out to the server…
echo($feed);
}
?>
坏习惯:可操控 有侧重
例四给出了更简洁,更具可读性的方法。在这个例子中,长的方法被分解后,每次只做一件事,并且做得很好。这样的代码肯定会被重复使用,并且更加容易测试。
例四:
function createRssHeader()
{
return "" .
"" .
"" .
"http://www.example.com/feed.xml" .
"The best feed in the world" .
"en-us" .
"Tue, 20 Oct 2008 10:00:00 GMT" .
"Tue, 20 Oct 2008 10:00:00 GMT" .
"http://www.example.com/rss" .
"MyFeed Generator" .
"editor@example.com" .
"webmaster@example.com" .
"5";
}
function createRssFooter()
{
return "";
}
function createRssItem($title, $link, $desc, $date, $guid)
{
$item .= "";
$item .= "";
$item .= "" . $link . "";
$item .= " " . $description . "";
$item .= "" . $date . "";
$item .= "" . $guid . "";
$item .= "";
return $item;
}
function getUserMaxStories($db_link, $default)
{
$perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= ‘%s’",
mysql_real_escape_string($user));
$result = mysql_query($perfsQuery, $db_link);
$max_stories = $default;
if ($row = mysql_fetch_assoc($result)) {
$max_stories = $row[‘max_stories’];
}
return $max_stories;
}
function writeRssFeed($user)
{
// Get the DB connection information
$settings = parse_ini_file("rss_server.ini");
// look up the user’s preferences…
$link = mysql_connect($settings[‘db_host’], $settings[‘user’],
$settings[‘password‘]) OR die(mysql_error());
$max_stories = getUserMaxStories($link, 25);
// go get my data
$newsQuery = sprintf("SELECT * FROM stories WHERE post_date = ‘%s’",
mysql_real_escape_string(time()));
$result = mysql_query($newsQuery, $link);
$feed = createRssHeader();
$i = 0;
// build the feed…
while ($row = mysql_fetch_assoc($result)) {
if ($i < $max_stories) {
$title = $row[‘title’];
$link = $row[‘link’];
$description = $row[‘description’];
$date = $row[‘date’];
$guid = $row[‘guid’];
$feed .= createRssItem($title, $link, $description, $date, $guid);
$i++;
} else {
break;
}
}
mysql_close($link);
$feed .= createRssFooter();
// write the feed out to the server…
echo($feed);
}
?>
分解长的方法可能造成递减报告,因此要小心,不要画蛇添足。有可能由于分解了太多代码而导致再次难以阅读。
记录你的代码
记录您的代码有时似乎就像编写代码一样困难。了解要记录什么是有技巧的,因为很多人会考虑去记录代码所执行的事情。其实,记录代码的意向才是更好的主意。函数的标头块可能并没有明显告诉程序员方法的预期输入和输出以及初衷。
记录代码正在做的事情是常见的,但却是没有必要的。如果代码非常混乱以至于你需要记录它的执行过程,那或许这也是你需要重写代码的一个提示了。养成良好的命名习惯,选用更短的方法,使您的代码更具可读性,而不必费时间为其注释。
坏习惯:丢失和冗长的函数记录
例五中的注释只是告诉程序员代码的过程,并且它被循环使用。但却缺少了对代码为什么这样做的记录。难么无疑为维护这一代码增加了难度。
例五:
class
ResultMessage
{
private $severity;
private $message;
public function __construct($sev, $msg)
{
$this->severity = $sev;
$this->message = $msg;
}
public function getSeverity()
{
return $this->severity;
}
public function setSeverity($severity)
{
$this->severity = $severity;
}
public function getMessage()
{
return $this->message;
}
public function setMessage($msg)
{
$this->message = $msg;
}
}
function cntMsgs($messages)
{
$n = 0;
/* iterate through the messages… */
foreach($messages as $m) {
if ($m->getSeverity() == ‘Error’) {
$n++; // add one to the result;
}
}
return $n;
}
$messages = array(new ResultMessage("Error", "This is an error!"),
new ResultMessage("Warning", "This is a warning!"),
new ResultMessage("Error", "This is another error!"));
$errs = cntMsgs($messages);
echo("There are " . $errs . " errors in the result.\n");
?>