|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
《PHP+MYSQL WEB开发(第三版)》号称圣经级,(也许是个不错的选择(声明:作者没给我啥好处费,我也不是书托,隔着大老远,我连他老兄的面都没见过的说-_-)变量 “用 PHP 开辟强健的代码”是关于处理大中型使用法式中的实践成绩的系列文章。在本文中,PHP 内行 Amol Hatwar 会商了若何无效地利用变量。他还演示了若何经由过程利用 PHP 中可变的变量名来机关设置装备摆设文件解析器,以便简化剧本设置装备摆设。
在我的前一篇文章中,我研讨了在计划、设计乃至编写代码时代必需思索的一些要素。在本文中,您将真正接触到实践代码,并可以看到实践运转中的一些器材。假如您还没有看过前一篇文章,那末最好如今就看一看。
准确处置变量
变量与函数是任何盘算机言语必不成少的要素。有了变量,您可以将数据笼统化;有了函数,您可以将几行代码笼统化。正如 Bruce Eckel 在他的书本《C++ 编程思惟》中所说的那样,一切编程言语都供应笼统。汇编言语是对底层机械的小笼统。随后的很多所谓的号令式言语(如 Fortran、BASIC 和 C)是对汇编言语的笼统。
编程言语供应的笼统的品种和质量直接关系到您所能处理的成绩的庞杂水平。了解 PHP 若何处置变量和函数,将有助于您无效地利用它们。
称号里有甚么?
就象我在前一篇文章中提到的那样,定名商定和编码商定是主要的。不管您利用甚么定名商定,请记住要在项目中严厉恪守它。假如您利用使用得最普遍的定名商定,那末您的代码将被更多的人所承受。
对变量停止定名时,在包含剧本时要出格注重不要掩盖正在利用的变量。在大型使用法式中,当增添新的功效时,这是罕见的毛病本源。避免这一成绩的最好举措就是利用前缀。把变量地点模块的称号缩写作为前缀来利用。例如,假如一个处置投票的模块中有一个保留用户标识的变量,那末您可以将该变量定名为 $poll_userID 或 $pollUserID。
了解 PHP 变量
PHP 是注释型言语。这有很多优点,很快您将进修使用个中的一些。第一个很分明的优点是:它使您免却了设计-编码-编译-测试周期 ― 您在编纂器中编写的任何代码都当即可以使用。但是,最主要的优点是您不必忧虑变量的类型和若何在内存中办理这些变量。一切分派给剧本的内存在履行完剧本后都由 PHP 主动发出。另外,可以对变量履行很多操作而不用晓得变量的类型。清单 1 中的代码在 PHP 中任务非常正常,但在 C 和 Java 言语中会抛出一大堆毛病动静:
清单 1. 带变量的样本 PHP 代码
<?php
$myStr = 789696; // An integer.
$myVar = 2; // Another integer.
$myStr = "This is my favorite band: "; // Strings are more fun.
$myStr = $myStr . "U" . $myVar; // Doing this is OK, too.
echo "$myVar\n";
?>
装置完 PHP 后,如要运转运转代码,可起首将该代码保留为一个 .php 文件,再将该文件放置在 Web 办事器上,然后将阅读器指向该文件。更好的举措是装置 PHP 的 CGI 版本。然后,经由过程在 shell 或号令提醒符下输出以下号令,并用包括您的剧本的文件名替换 script-name,如许就能够运转该剧本了。
path-to-php/php script-name
该代码可以正常任务,由于 PHP 是类型宽松的言语。用浅显易懂的英语,可以不思索变量类型,可以把字符串赋值给整数,和绝不吃力地用较大的字符串替换较小的字符串。这在象 C 如许的言语中是不成能的工作。在外部,PHP 将变量所具有的数据与类型分隔存储。类型存储在独自的表中。每当呈现包括分歧类型的表达式时,PHP 主动肯定法式员想要做甚么,接着更改表中的类型,然后主动对表达式求值。
引见一个罕见的小成绩
不必忧虑类型当然很好,但有时那也会使您堕入真实的费事。怎样回事呢?这里有一个实践的示例:我经常必需把在基于 Windows 的 PC 上创立的内容移到 Linux 体系,以便能在 Web 上利用它们。基于 Windows 的文件体系在处置文件名时是不辨别巨细写的。文件名 DefParser.php 和 defparser.php 指向 Windows 上的统一文件。在 Linux 操作体系上,它们指向分歧的文件。您能够倡始文件名要末全用大写,要末全用小写,但最好的做法应当是使巨细写坚持不变。
处理这个小成绩
假定您想要一个函数,它能在不思索巨细写的情形下反省给定文件是不是存在于某个目次中。起首,将这个义务分化成一些复杂的步调。分化代码能够听起来有些好笑,但它的确有助于您在编写代码时将次要精神放在这段代码上。别的,在纸上重写步调一直比重写代码轻易很多:
获得源目次中的一切文件名
过滤失落 . 和 .. 目次
反省方针文件是不是存在于该目次中
假如文件存在,则获得具有准确巨细写的文件名
假如称号不婚配,则前往 false
要读取目次的内容,需求利用 readdir() 函数。可以在 PHP 手册(请参阅参考材料)中获得有关该函数的更多细节。至于如今,只需晓得:readdir() 在每次挪用时会逐一前往给定目次中一切文件的称号。在列出了一切的文件名后,它前往 false。您将利用一个轮回,该轮回在 readdir() 前往 false 时终止。
但如许就够了吗?请记住,PHP 是类型宽松的言语,这意味着会将整型值 0 与 false 视为不异(乃至 C 也把 0 和布尔值 false 视为等价)。成绩不是该代码是不是能正常任务;想象一下,假如文件的称号是 0 会若何!该剧本会过早终止。可使用以下剧本(清单 2)来肯定 0 与布尔值 false 的等价性:
清单 2. 肯定 0 与布尔值 false 是不是等价的剧本
<?php
$file_name = 0;
if (0 == $file_name ) {
echo "The code is in trouble ...\n"; // This text prints on the screen.
}
else {
echo "Phew ... The code is safe"; // This text never prints.
}
?>
那末您可以做甚么呢?您晓得 PHP 会在外部存储类型,而假如可以会见这些类型的话,成绩就处理了。布尔值 false 和整型值 0 分明是分歧的。
PHP 有一个 gettype() 函数,但让咱们在这里选择更复杂的办法。您可使用 === 运算符(是的,有三个等号)。分歧的地方在于该运算符同时对照数据的值和类型。假如您对此感觉有些困惑,PHP 还有 !== 运算符。只要 PHP 4 中才有这些新型运算符和 gettype() 函数。清单 3 显示懂得决该成绩的完全代码:
清单 3. 完全代码
<?php
/* This is the function where the action takes place */
function chk_file_name( $name, $path="." ) {
$fileList = get_file_list($path);
foreach ($fileList as $file) {
if (eregi($name, $file)) {
return $file;
}
}
return false;
}
/* Return the list of files in a given directory in an array.
Uses the current directory as default. */
function get_file_list($dirName=".") {
$list = array();
$handle = opendir($dirName);
while (false !== ($file = readdir($handle))) {
/* Omit the '.' and the '..' directories. */
if ((".."== $file) || ("."== $file)) continue;
array_push($list, $file);
}
closedir($handle);
return $list;
}
?>
察看中失掉的经历
我不盘算对清单 3 中各个函数的功效加以申明,相反,我勉励您查阅 PHP 手册(请参阅参考材料)。当您利用不熟习的函数时,假定的参数与前往值的类型会是另外一个毛病本源。我没有对 PHP 中的内置函数加以申明,而是盘算申明一些不太了如指掌的工作。
当终止前提中触及分歧的变量类型时,经由过程利用 === 和 !== 运算符停止强类型反省是很主要的。
由各局部构成的代码
我原本可以将全部剧本编写为一个函数,但这里我却把代码朋分成两个函数。还记得前一篇文章中的“分而治之”划定规矩吗?我这么做恰是由于每一个函数所起的感化分歧。假如您用其它剧本获得某个目次的内容,那末如今就能够利用便利的完成。我但愿您思索一些工作:想象一下将全部剧本作为一个函数来完成,然后想象调试、测试和重用代码所需的任务。
准确利用轮回
如今看看 foreach 轮回,想一想为何不必 for 轮回?利用 for 轮回请求您晓得数组中项的数量 ― 需求一个额定的步调。另外,在处置 PHP 数组时,有能够超越数组界限。也就是说,在数组只要 10 个元素时,试图会见它的第 15 个元素。PHP 切实其实会给出一个小正告,但据我所知,在一些情形下,当重复运转某个剧本时,CPU 举动率会俄然上升到 100% 而办事器功能则一连下落。我建议您尽量地防止利用 for 轮回。
断言性的 if
最初,我但愿您研讨一下谁人在 get_file_list() 函数顶用于疏忽 . 和 .. 目次的较大的 if 前提。明显,我可以采取传统的办法,依据常数来反省变量。但在我本人的很多编码昏招中,我常常会漏掉等号而且在今后找不到哪里出了成绩。固然,PHP 不会报错,由于它以为我想停止赋值而不是对照。当您依据变量来对照常数而且又漏掉了一个等号时,PHP 会抛失足误动静。
可变的变量名
如今来会商一些奇奥的工作。作为老手的开辟人员以为,利用可变变量来完成义务是一种使人隐晦的办法,所以经常躲避它。实践上,很轻易了解和利用可变变量。它们已不止一次地帮我脱节窘境,并且它们是一种主要的言语元素。现实上,在有些情形下,利用可变变量在所不免。很快我将研讨一种此类实际情形,但起首让咱们看看可变变量究竟是甚么。让咱们先测验考试一下清单 4 中的代码:
清单 4. 具有可变变量的代码
<?php
$myStr = "I";
$$myStr = "am";
$$$myStr = "great.";
// These are new variables.
echo "$myStr ";
echo "$I ";
echo "$am\n";
// Now for the moment of truth ...";
$am = "exaggerating.";
// Does it work the other way?
echo "$myStr ";
echo "${$myStr} ";
echo "${${$myStr}}\n ";
?>
起首,清单 4 中的代码声了然名为 $myStr 的变量,并将字符串 I 赋给它。接上去的语句界说了另外一个变量。但此次,变量的称号是 $myStr 中的数据。$$myStr 是一种告知 PHP 发生另外一个变量的办法,其意思是“我想要一个变量,可以在变量 $myStr 中找到这个变量的称号”。固然,为做到这一点,必需界说 $myStr。所以,如今您有一个名为 I 的变量,并用字符串 am 给它赋值。接上去的语句做了一样的工作,并将字符串 great 赋给名为 am 的变量。而 am 只是变量 I 中的数据。
那廓清了一些事,但 echo 语句中那些奇异的花括号是怎样回事呢?那就是您打印可变变量的办法。假如您省略花括号,那末 PHP 在打印时会将美元符号($)附加到变量的内容上。这些花括号告知 PHP 起首对它们外面的变量求值。
试着如许思索:变量可以做甚么?复杂地说,它们笼统或暗示数据,这些数据可以变更,而它们的称号坚持不变。可变变量做的是一样的工作;它们笼统数据。但在本例中,它们包括的数据实践上是另外一个变量的称号。
我在清单 4 中所给的例子是为了让您熟习可变变量。可变变量名的实践功效来自如许的现实:您可以在运转时静态地生成可变的变量名。您将在机关一个设置装备摆设文件解析器时用到这一特征。
设置装备摆设文件解析器
依照我的经历,在设置装备摆设使用法式以使其运转时代,用 PHP 编纂设置装备摆设文件时,用户常有所埋怨。设置装备摆设只不外是全局变量的一个列表,使用法式中的其它剧本依托它来查找文件、URL 和其它掌握使用法式行动的设置。一个漏掉的美元符号、分号或一段未关闭的正文经常会损坏全部代码。有甚么能匡助用户呢?
假定您给用户一个文件,让用户利用由等号分隔的复杂的称号-值对来编纂该文件。设置装备摆设文件相似于清单 5。以 # 开首的行的文本被作为正文处置。
清单 5. 样本设置装备摆设文件
# This is sample a configuration file.
admin_fname = Amol
admin_lname = Hatwar
admin_email = amolhatwar@consultant.com
admin_login = admin
admin_pass = secretstring
# File Ends
意思清晰吗?是的,切实其实如斯……既然可以用 PHP 解析文件,为何让用户编纂设置装备摆设文件呢?现实上,这是人们十分希冀的。请记住,您的使用法式必需在对用户埋没一切庞杂性的同时,依然让他晓得他能掌握该使用法式。
您可以编写担任解析任务的函数,如许您可以在任何中央利用它而不必做任何修正。让咱们将该义务分为一些更复杂的步调:
逐行地读取文件
抛弃一行中 # 号字符后的一切内容
以等号为界,将一行分为两个字符串,并抛弃等号
除去字符串中的额定空格
响应声明变量
要编写最初一步,只要利用可变变量才行。清单 6 显示了代码:
清单 6. 解析函数
<?php
/* conf_parser.php */
/* Give the filename with path info whenever possible. */
function conf_parse($file_name) {
// @ in front makes the function quiet. Error messages are not printed.
$fp = @fopen($file_name, "r") or die("Cannot open $file_name");
while ($conf_line = @fgets($fp, 1024)) {
$line = ereg_replace("#.*$", "", $line); // Do stripping after hashes.
if ($line == "") continue; // Drop blank lines resulting from the previous step.
list($name, $value) = explode ('=', $line); // Drop '=' and split.
$name = trim($name); // Strip spaces.
$$name= trim($value); // Define the said variable.
}
fclose($fp) or die("Can't close file $file_name");
}
?>
用正则表达式除去 # 号。虽然这里的表达式很复杂,但要晓得庞杂的正则表达式会损耗大批的 CPU 工夫。另外,为每页重复地解析设置装备摆设文件不是一个好的决议计划。更好的选择是:利用变量或界说语句将已解析的输入存储为 PHP 剧本。我偏向于利用 define() 函数停止界说,由于一旦设置了值就不克不及在运转时更改它。可以在参考材料中找到一个可以依据您的需求加以修正的完成。
停止语
既然晓得了若何无效地利用变量,那末您可以着手编写一些较大的法式了。在本系列的下一篇文章中,我将研讨函数和 API 设计。鄙人次会晤之前,但愿您编程兴奋!
参考材料
下载 def_parser.zip 文件,个中包括设置装备摆设文件解析器的完成,您可以将该解析器写的文件包含在您的剧本中。
请会见 PHPBuilder.com 和 Developer Shed,以获得更多有关在 PHP 中利用可变变量称号的示例。
请浏览懂得 Free Energy,这是一个对 Web 使用法式停止编码的复杂办法。
下载或在线查阅 PHP 手册。
列入“Writing efficient PHP”教程,进修若何编写无效的 PHP 代码(developerWorks,2002 年 7 月)。
请浏览本系列文章中的第一篇“奠基基本”,懂得有关设计和计划 Web 使用法式的要点(developerWorks,2002 年 8 月)。
关于作者
Amol Hatwar 从能记事起就入手下手接触盘算机。作为 GNU/Linux 的相对反对者,他为曩昔在 Microsoft 平台上编程感应忸怩。他如今作为自力参谋匡助浩瀚公司迁徙到 GNU/Linux。作为开辟 Web 使用法式范畴的专家,他把所剩无几的空余工夫花在研讨没人传闻过的手艺上。他如今的乐趣包含开放源码软件、Web 办事、对等盘算和高可用性群集。您可以经由过程 amolhatwar@consultant.com 与 Amol 接洽。
理解动态语言的概念,运做机制,熟悉PHP语法 |
|