从零开始攻略PHP(6)——代码重用与函数编写的一些注意事项

  一个新的项目是这样创建的:它将已有的可重新利用的组件进行组合,并将新的开发难度降低到最小。

  代码重用的好处:降低成本、提升可靠性和一致性。

1.使用require()和include()函数

  使用一条require()或include()语句,可以将一个文件载入到PHP脚本中。

  require()和include()几乎相同。区别是函数失败后,require()函数将给出一个报错。Include()给的则是警告。

  变体函数分别是require_once()和include_once()。作用是确保一个包含(inlcuded)的文件只能被引入一次。当使用require()和include()来引入函数库时,使用这两个函数可以防止错误的引入同样的函数库两次。

  1.1 文件扩展名和require()函数

  当使用require()语句时,必须注意处理文件扩展名和PHP标记的不同方式。将被包含文件保存在文档树之外,或使用标准的文件扩展名是非常重要的。

  将文件中的PHP代码放到PHP标记之间,能够被当成PHP代码进行处理。如果不使用PHP标记,将会被视为文本或者HTML脚本,因此也就不会被执行。

  1.2 使用require()制作Web站点的模板

  一个虚构的TLA咨询公司:

从零开始攻略PHP(6)——代码重用与函数编写的一些注意事项

  原脚本home.html:

<html>
<head>
<title>TLA Consulting Pty Ltd</title>
<style type="text/css">
h1 {color:white; font-size:24pt; text-align:center;
font-family:arial,sans-serif}
.menu {color:white; font-size:12pt; text-align:center;
font-family:arial,sans-serif; font-weight:bold}
td {background:black}
p {color:black; font-size:12pt; text-align:justify;
font-family:arial,sans-serif}
p.foot {color:white; font-size:9pt; text-align:center;
font-family:arial,sans-serif; font-weight:bold}
a:link,a:visited,a:active {color:white}
</style>
</head>
<body> <!-- page header -->
<table width="100%" cellpadding="12" cellspacing="0" border="0">
<tr bgcolor="black">
<td align="left"><img src="logo.gif" alt="TLA logo" height="70" width="70" /></td>
<td>
<h1>TLA Consulting</h1>
</td>
<td align="right"><img src="logo.gif" alt="TLA logo" height="70" width="70" /></td>
</tr>
</table> <!-- menu -->
<table width="100%" bgcolor="white" cellpadding="4" cellspacing="4">
<tr >
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Home</span></td>
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Contact</span></td>
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Services</span></td>
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Site Map</span></td>
</tr>
</table> <!-- page content -->
<p>Welcome to the home of TLA Consulting.
Please take some time to get to know us.</p>
<p>We specialize in serving your business needs
and hope to hear from you soon.</p> <!-- page footer -->
<table width="100%" bgcolor="black" cellpadding="12" border="0">
<tr>
<td>
<p class="foot">&copy; TLA Consulting Pty Ltd.</p>
<p class="foot">Please see our
<a href="legal.php">legal information page</a></p>
</td>
</tr>
</table>
</body>
</html>

  可以将这个文件分割,然后给这些部分分别命名为header.php、home.php和footer.php。文件header.php和footer.php都包含有在其他页面中可以重用的代码。

  文件home.php代替home.html,它包含页面内容和两个require()语句:

<?php
require('header.php');
?>
<!-- page content -->
<p>Welcome to the home of TLA Consulting.
Please take some time to get to know us.</p>
<p>We specialize in serving your business needs
and hope to hear from you soon.</p>
<?php
require('footer.php');
?>

  可以将.inc(此处inc代表include)文件保存在一个目录中,而这个目录可以被脚本访问,但是被引入的文件不会被Web服务器载入。这种设置可以防止下面两种情况发生:a)如果文件扩展名是.php,但只包含部分页面或脚本,此时可能会引起错误。b)如果已经使用了其他扩展名,别人就可以读取源码。

  所有TLA网站页面可重复使用的页眉header.php:

<html>
<head>
<title>TLA Consulting Pty Ltd</title>
<style type="text/css">
h1 {color:white; font-size:24pt; text-align:center;
font-family:arial,sans-serif}
.menu {color:white; font-size:12pt; text-align:center;
font-family:arial,sans-serif; font-weight:bold}
td {background:black}
p {color:black; font-size:12pt; text-align:justify;
font-family:arial,sans-serif}
p.foot {color:white; font-size:9pt; text-align:center;
font-family:arial,sans-serif; font-weight:bold}
a:link,a:visited,a:active {color:white}
</style>
</head>
<body> <!-- page header -->
<table width="100%" cellpadding="12" cellspacing="0" border="0">
<tr bgcolor="black">
<td align="left"><img src="logo.gif" alt="TLA logo" height="70" width="70"></td>
<td>
<h1>TLA Consulting</h1>
</td>
<td align="right"><img src="logo.gif" alt="TLA logo" height="70" width="70" /></td>
</tr>
</table> <!-- menu -->
<table width="100%" bgcolor="white" cellpadding="4" cellspacing="4">
<tr >
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Home</span></td>
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Contact</span></td>
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Services</span></td>
<td width="25%">
<img src="s-logo.gif" alt="" height="20" width="20" />
<span class="menu">Site Map</span></td>
</tr>
</table>

  文件footer.inc包含了在每个页面底部脚注处显示的表格:

<!-- page footer -->
<table width="100%" bgcolor="black" cellpadding="12" border="0">
<tr>
<td>
<p class="foot">&copy; TLA Consulting Pty Ltd.</p>
<p class="foot">Please see our <a href="legal.php">
legal information page</a></p>
</td>
</tr>
</table>
</body>
</html>

  如果希望保证一个文件将被当作纯文本或HTML,并且不会执行任何PHP,可以使用readfile()作为替代方法。这个函数将回显文件内容,不会对其进行解析。如果使用的是用户提供的文本,这可能就是一个重要的安全问题。

  1.3 使用auto_prepend_file和auto_append_file

  如果希望使用require()将页眉和脚注加入到每个页面中,还可以设置php.ini中的auto_prepend_file和auto_append_file。使用这些指令包含的文件可以像使用include()语句包含的文件一样;如果文件不存在,将产生一个警告。

  Windows的设置如下:

auto_prepend_file = “c:/Program Files/Apache Software/Froundation/Apache2.2//include/header.php”

auto_append_file = “c:/Program Files/Apache Group/Apache2/Include/footer.php”

  使用了这些指令,就不需要再输入include()语句,但页眉和脚注在页面中不再是页面的可选内容。

  如果使用的是Apache Web服务器,可以对单个目录进行不同配置选项的修改。这样做的前提是服务器允许重设其主配置文件。要给目录设定自动前加入和自动追加,需要在该目录中创建一个名为.htaccess的文件。这个文件需要包含如下代码:

php_value auto_prepend_file “/home/username/include/header.php”

php_value auto_append_file “/home/username/include/footer.php”

  注意,其语法与配置文件php.ini中的相应选项有所不同,和行开始处的php_value一样:没有等号。许多php.ini中的配置设定也可以按这种方法进行修改。

  在.htaccess中设置选项,而不是php.ini中或是在Web服务器的配置文件中进行配置,将带来极大的灵活性。可以在一台只影响你的目录的共享机器上进行。不需要重新启动服务器而且不需要管理员权限。使用.htaccess方法的一个缺点就是目录中每个被读取和被解析的文件每次都要进行处理,而不是只在启动时处理一次,所以性能会有所降低。

2.函数编写的一些注意事项

  · 函数调用将不区分大小写,变量名是区分大小写的,所以$Name和$name是两个不同的变量,但Name()和name()则是同一个函数。

  · 如果希望在一个函数中退出PHP并输入HTML脚本,可以像在脚本其他地方做的那样——使用一个封闭的PHP标记,然后再编写HTML。

  · 许多语言允许重复使用函数名称。这个特性叫做函数的重载。但是PHP不支持函数重载,所以自定义函数不能和内置函数或是用户已定义的函数重名。请注意,虽然每个PHP脚本知道所有内置函数,但对于用户定义的函数,PHP只能识别哪些存在于脚本之中的。这就意味着,虽然可以在不同的文件中重复使用一个函数名,但这会引起混乱,所以应该避免。

  · 通过3个帮助器函数:func_num_args()、func_get_arg()和func_get_args(),可以确定已经传递了多少个参数以及这些参数的值:

function var_args(){

  echo "Number of parameters:";

  echo func_num_args();

  echo "<br />";

  $args = func_get_args();

  foreach($args as $arg){

    echo $arg."<br />";

  }

}

var_args(2,123,234,122,7);

从零开始攻略PHP(6)——代码重用与函数编写的一些注意事项

  其中func_num_args()函数将返回传入的参数个数。而func_get_args()函数将返回参数的数组。或者可以使用func_get_arg()函数一次获得一个参数,该函数需要以希望访问的参数个数作为参数(参数从0开始)。

3.关于作用域

  PHP变量的作用域具有相当简单的规则:

  · 在函数内部生命的变量作用域是从声明它们的那条语句开始到函数末尾。这些变量称为局部变量。

  · 在函数外部声明的变量作用域是从声明它们的那条语句开始到文件末尾。这叫做全局作用域。这些变量称为全局变量。

  · 特殊的超级全局变量在函数内部和外部都是可见的。

  · 使用require()和include()并不影响作用域。如果这两个语句用于函数内部,函数作用域适用。如果它不在函数内部,全局作用域适用。

  · 关键字“global”可以用来手动指定一个在函数中定义或使用的变量具有全局作用域。

  · 通过调用unset($variable_name)可以手动删除变量。如果变量被删除,它就不在参数所指定的作用域中了。

4.参数的引用传递和值传递

  通常,函数获取参数的方式是值传递。更好的办法是使用引用传递。这里,在参数被传递给函数的时候,函数不会再创建一个新的变量,而是函数获得一个原来变量的引用。这个引用有一个变量名称,它以美元符号开始,可以像另一个变量那样使用它。其区别在于它不是获得变量本身的值,而是指向原来的值。任何对该引用的修改都会影响到原始变量值

  可以通过在函数定义的参数名前加一个地址符(&)来指定参数的引用传递。在函数调用处不用修改。

function increment(&$value, $amount = 1){

  $value = $value + $amount;

}

$a = 10;

echo $a.'<br />';

increment ($a);

echo $a.'<br />';

从零开始攻略PHP(6)——代码重用与函数编写的一些注意事项

5.使用Return关键字

  关键字“return”将终止函数的执行。

  一个错误条件是在程序执行到函数末尾之前使用“return”语句中断函数执行的最常见原因。

  另一个重要作用是从函数返回一个值。

  如果不符合判断条件,可以返回“false”。(使用这种方法唯一需要注意的是编程人员调用这个函数必须使用“===”测试返回类型,确保“false”不会与0混淆。前一篇中有判断代码。)

6.关于递归

  PHP支持递归函数。递归函数就是函数调用自己本身。递归函数比循环慢而且要占用更多内存,所以应该尽可能多用些循环。

  两种方式颠倒字符串:

<?php

function reverse_r($str)
{
if (strlen($str)>0)
reverse_r(substr($str, 1));
echo substr($str, 0, 1);
return;
} function reverse_i($str)
{
for ($i=1; $i<=strlen($str); $i++)
{
echo substr($str, -$i, 1);
}
return;
} reverse_r('Hello');
echo '<br />';
reverse_i('Hello'); ?>

从零开始攻略PHP(6)——代码重用与函数编写的一些注意事项

  递归的缺陷:

  递归函数将在内存中创建几个自身的副本,并且将产生多次函数调用的开销。

  当递归方法的代码比循环方法的代码更简短、更美观的时候,我们可能会选择使用递归,但是在应用领域通常不会这样。

  另外,虽然递归看上去更美观,但如果忘记给出递归的终止条件,这意味着函数会一直重复下去直到服务器内存耗尽,或者达到了最大调用次数。

7.名称空间

  名称空间是一个抽象的容器,它可以包含一组标识符;在PHP中,名称空间可以包含你所定义的函数,常量以及类。优点如下:

  · 一个名称空间中的所有函数、类和常量都将自动冠以名称空间前缀。

  · 非全路径的类、函数和常量名称将在运行时解析,在查看全局空间之前,将首先查看名称空间。

整理自《PHP和MySQL Web开发》

上一篇:What exactly can you do with Python? Here are Python’s 3 main applications._你能用Python做什么?下面是Python的3个主要应用程序。


下一篇:五、jdk工具之jmap(java memory map)、 mat之四--结合mat对内存泄露的分析、jhat之二--结合jmap生成的dump结果在浏览器上展示