第五章 代码重用与函数编写
require()或include()可以将一个文件载入到php脚本中。
这两个函数几乎等价,唯一的区别是调用失败后require()给出一个致命错误,而include()只给出一个警告。
如果Web页面具有一致的外观,可以将相同的部分分离到单独的页面中,然后可以在php中使用require()语句将模板元素加入到页面中。
如果希望保证一个文件将被当作普通文本或html,而不执行任何php,可以使用readfile()作为替代方法。
require_once()和include_once()可以保证某个文件只被包含一次,在使用函数库的时候,这两个函数非常有用,可以防止意外地多次包含相同的函数库,从而导致函数的重复定义并产生错误。
也可以在php.ini配置文件中,使用auto_prepend_file和auto_append_file这两个选项来设置页眉和页脚,可以保证它们在每个页面的前后被载入。此时就可以不再用include()语句。
auto_prepend_file = "/home/***/header.inc"
如果使用的apache,则可以给每个目录单独设定,在目录中创建名为.htaccess的文件,并在文件中包含如下的代码:
php_value auto_prepend_file "/home/***/header.inc"
(php的很多其它选项也可以通过这种方法来设置)
函数声明方法:
function my_function()
{ echo 'myfunction'; }
函数调用不区分大小写。function_name()等价于FunCtion_NaMe()。
php中函数定义不能和已有的函数重名,即不支持函数的重载。但可以包含默认的参数。
php中也可以声明能够接收可变参数数量的函数,通过如下三个函数:
func_num_args()、func_get_arg()以及func_get_args()。
function var_args()
{
echo "Number of parameters:";
echo func_num_args();
$args = func_get_args();
foreach($args as $arg)
echo $arg.'<br />';
}
php具有超级全局变量,在任何地方可见。
使用require()和include()并不影响作用域,被包含的全局作用域变量仍然可用。
关键字"global"可以用来手动指定在一个函数中定义或使用的变量具有全局作用域。
unset($var)可以手动删除变量,在此之后就不能再使用了。
php函数参数也有“值传递”和“引用”传递。
function increment(&$value, $amount = 1){}
$value就是引用传递,$amount就是值传递。
return可以退出函数的执行。 也可以用return来从函数中返回一个值。
function larger($x, $y){
if ($x >= $y) return $x;
else return $y;
}
php支持递归函数。
第六章 面向对象的php
一个基本的php类:
class classname
{
function __construct($param) //构造函数
{
echo "Constructor called with parameter $param <br />";
}
function __destruct() //析构函数
{
echo "Destruct";
}
function operation($att){ //普通成员函数
$this->attribute = $att;
}
var $attribute; //普通成员变量
//取类属性的值,可以通过__get和__Set函数
function __get($name) //$name参数指定属性的名称,在这个类里面应该是$attribute
{
return $this->$name;
}
function __set($name, $value) //$value是被设置的值
{
this->$name = $value;
}
}
使用如下:
$a = new classname();
$a->$attribute = 5; //这句话,会间接的调用__set()函数
$a->$attribute; //会间接调用__get()函数
通过__get()、__set()是为了提供使其只有一个访问入口,这样就可以实现对要存取的数据进行检查,保证数据是有意义的。
在php5中也引用了访问修饰符,可以使用private和public及protected关键字控制访问。
默认的访问修饰符是public。
class classname
{
public $attribute;
public function __get($name){/**/}
}
实现继承:
class A{
var $attr1;
function oper1(){}
}
class B extends A{
var $attr2;
function oper2(){}
}
B的对象也可以访问$attr1和oper1();
在继承中,通过使用private和protected来控制可见性。
如果A的oper1()是private的,则在B中无法访问。protected和public都可以(与C++一样)
php中的"重载“其实就是C++中的覆盖,子类函数名与父类函数名相同,且将父类的同名函数隐藏掉。
php5中引入的final关键字可以禁止继承和重载。
class A{
final function opera(){}
}
则opera()函数在子类中不能被重载。
php不支持多重继承,不过支持接口。
interface Displayable
{
function display();
}
class WebPage implements Displayable
{
function display(){ /*实现代码*/ }
}
在业务繁忙的网站中,处理速度是很重要的,应该尽量使用静态html网页,或者尽可能缓存脚本输出,从而减少在服务器上的载入操作。
在php4中,对象是按值传递的,但在php5中是按引用传递的。
以前的php版本无法间接引用由函数返回的对象,如:select()->display();
php5中引用了Per-Class常量,可以在不需要初始化类的情况下使用。
class Math {
const pi = 3.14;
}
可以直接这样使用 Math::pi。
php5也引入了static关键字,它允许在未初始化类的情况下,就可以调用的类方法。(在静态方法中不能使用this关键字)
php5提供了instanceof关键字和类型提示的概念。
php5引入了clone关键字,允许复制一个已有的对象。 $c = clone $b;
在基类中创建__clone()方法,可以自定义克隆行为,而不使用默认的。
php5中也引入了“抽象类”和“抽象方法”。
包含抽象方法的任何类自身都必须是抽象的。
abstract class A {
abstract function operationX($param);
}
重载__call()方法,可以实现方法的重载。
public function __call($method, $p)
{
if ($method == 'display') {if (...) else if (...)}
}
可以实现在调用 display方法时,根据call的实现,调用不同的函数。
__autoload()方法,是一个单独的函数,它用来实例化一个还没有被声明的类时自动载入"类名.php"文件。
代器和迭代
可以使用foreach()方法通过循环方式取出一个对象的所有属性,就像数组方式一样。(引擎会默认生成)
但如果需要更复杂的功能的话,则只能通过实现一个迭代器的方式。
__toString()函数可以将类转换成字符串,echo类时,会显示相应的字符串。
反射API:
$varcls = new ReflectionClass('Page'); //Page是个类名
echo $varcls; //就可以打印出Page类的信息
第七章 异常处理
PHP中,异常必须手动抛出。
throw 异常类;
如可以抛出内置的Exception类:throw new Exception('message', code);
在外部用catch来捕获。
Exception类提供了很多内置方法:
getCode()--返回传递给构造函数的代码。
getMessage()--返回传递给构造函数的消息。
getFile()--返回产生异常的代码文件的完整路径。
getLine()、getTrace()、getTraceAsString()、_toString等等……
也可以抛出自定义的任何类对象,不过一般情况下都会使自定义的异常类从Exception中继承。