序言
闲来无事,下载了一些电子书,然后看书名不错《PHP高级程序设计_模式、框架与测试》,翻了一下虽然书有点老了但是讲的内容经常会碰到!给大家推荐一下,然后这里放上我的读书笔记,每日更新。
【作 者】(加)Kevin McArthur [同作者作品] [作译者介绍]
【译 者】 汪泳[同译者作品]
【丛 书 名】 图灵程序设计丛书
【出 版 社】 人民邮电出版社 【书 号】 9787115193179
【上架时间】 2009-5-31
【出版日期】 2009 年7月 【开 本】 16开 【页 码】 1 【版 次】1-1
翻译很到位,给翻译官加鸡腿!PHP进阶篇。
另外《PHP核心技术与最佳实践》也可以去翻翻,哇学无止境啊!
索要此书电子版可在下方留言你的邮箱!
章节
- 第一章 抽象类、接口和契约式编程
- 第二章 静态变量、成员和方法
- 第三章 单例模式和工程模式
- 第四章 异常
- 第五章 PHP 6中的新特性
- 第六章 文档编写和编码规范
- 第七章 反射API
- 第八章 测试、部署和持续集成
- 第九章 SPL简介
- 第十章 SPL迭代器
- 第十一章 SPL文件和目录处理
- 第十二章 SPL数组重载
- 第十三章 SPL异常
- 第十四章 MVC架构
- 第十五章 Zend框架简介
- 第十六章 Zend框架高级功能
- 第十七章 应用Zend框架
- 第十八章 Ajax和JSON
- 第十九章 Web服务和SOAP协议介绍
- 第二十章 高级Web服务
- 第二十一章 证书验证
读书笔记
第一章 抽象类、接口和契约式编程
抽象类
抽象类是使用abstract关键字声明的类。通过将某个类标记成抽象类,我们可以推迟实现所声明的方法。要将某个方法声明成抽象方法,只需要省略掉包含所有大括号的方法实现体,将方法声明的代码行用分号结束即可。
抽象类不能直接实例化,他们必须被继承。如果某个类从抽象类继承,当它没有实现基类中所声明的所有抽象方法时,它就必须也被声明成抽象的。
接口
在接口中,我们也可以声明没有方法体的方法原型,这点与抽象类很类似。它们之间的区别在于,接口不能声明任何具有方法体的方法;并且它们使用的语法也不一样。为了将接口规则强制加到某个类上,我们必须使用implements关键字,而不是使用extends关键字。
instanceof
在某些情况下,我们希望确定某个类是否是特定的类型,或者是否实现了特定的接口。instanceof操作符非常适合这个任务。instanceof操作符检查三件事情:实例是否是某个特定的类型,实例是否从某个特定的类型继承,实例或者他的任何祖先类是否实现了特定的接口。
某些语言具有从多个基类继承的功能,这成为多重继承。PHP不支持多重继承。相反,它提供了为一个类声明多个接口的功能。
接口在生命类必须遵循的规则时非常有用。契约式编程技术使用这一功能来增强封装性,优化工作流。
第二章 静态变量、成员和方法
静态变量
静态变量是经过修饰的函数变量,在某个函数执行完成之后,它的值r仍然不会丢失。使用static关键字可以创建静态变量,同时还可以提供一个默认的初始值。不过,这个初始化值不能是一个表达式。当使用全局变量来模拟静态变量时,有可能发生变量名称冲突的现象,静态变量在消除这一冲突方面是非常有用的。
静态成员和方法
static关键字还可以用在类中修饰属性和方法。用在属性上时,它使属性不再为每个实例保存一个值,,而是只为整个类自身保存一个值。这个值也可以被用做事类的所有实例之间共享的值。
要访问静态方法,可以使用双冒号操作符(::),它也被称为作用域限定操作符。这个操作符的左边是一个类名称或者某个预定义作用域,预定义作用域包括self、parent或者PHP6中的static。操作符的右边是一个静态方法、变量和常量。在类中使用self预定义作用域时,它代表的是类自身。而parent预定难以作用域代表的是父类,当我们需要访问可能已经被重写的基类中的方法时,parent作用域非常有用。
静态类会对特定类型的测试产生影响。当在PHP中使用静态类时,IoC(控制反转)设计原型会受到限制。这是因为静态特性的使用会导致类之间通过名称绑定在一起,这使得单独地测试某个组件变得更加困难。不过,大多数PHP应用程序最终都没有采用IoC设计原型,并且静态特性的使用通常会被优先考虑。
第三章 单例模式和工程模式
单例模式为我们提供了定义系统职责中心点的功能。单例类在一个静态变量中保存了自身的一个实例,并且提供了一个getInstance()静态方法对这个实例进行访问。这个方法会返回对这个变量的引用,并且如果这个变量之前还没有执行初始的实例化工作,这个方法便会执行。这种延时实例化的行被称为延时加载。单例类还应该将他的构造函数标记为private,从而防止其他类直接实例化这个类。为了清除其他可以创建这个单实例的副本的漏洞,还可以定义__clone()魔术方法,并且将它标记成private。(看到这是不是想起了TP框架)
工厂模式的作用在于,可以根据输入参数或者应用程序配置的不同来创建一种专门用于实例化并返回其他类的实例的类。工程模式包含一个名为factory()的方法,这个方法必须返回一个对象.
第四章 异常
try关键字定义了要执行的代码块,并且需要检测抛出的异常。你可以为不同类型的异常定义多个catch语句块。
你能够使用变量和内部调用来抛出内置的Exception类。当一个异常发生时,可以检测异常具有的一些属性,其中包括错误信息、错误代码和跟踪信息。
Exception 类方法:
getMessage() 返回异常信息,此信息是描述错误状态的字符串
getCode() 返回错误代码
getFile() 返回发送的错误所在的源文件。
getLine() 返回异常抛出伪造在源文件的行号
getTrace() 赶回包含场景回溯的一个数组。
getTraceAsString() 与getTrace()相同,不过这个函数返回的是字符串而不是数组。
__toString() 返回用字符串表达的整个异常信息
可以通过扩展内置的Exception类为应用程序创建自定义异常。
还可以通过定义set_exception_handler()回调函数来重写内置的异常处理程序,并且将所有未捕捉的异常信息记录到日志文件中。
然而,使用异常也会带来一定的开销。应该避免过度使用异常来控制程序流。
通过使用错误代码类,可以将错误信息集中起来。随着系统规模的不断扩大,这种做法可以创建更加可控的应用程序。
将类型提示机制应用在异常上,可以用不同的异常类型实现多个catch语句块。
最后,我们可以捕捉、检测某个异常,然后再将这个异常重新抛给未捕捉异常的异常处理程序。
第五章 PHP 6中的新特性
这一章跳过......
第六章 文档编写和编码规范
PHP注释:
//单行注释
/*
多行注释
*/
/**
文档注释(文档块)
*/
文法解析:PHP代码在被实际执行之前会转换成二进制格式。这种从编程语言到可执行代码的转换过程被称为文法解析。
元数据:描述数据的数据。在编程中,这意味着元数据是关于程序的信息。
可以再代码中使用单行注释、多行注释和文档注释。在文法解析之后,只有文档注释会被保存,这对 通过编程访问这些信息非常有用。
PHPDoc是在应用程序中嵌入元数据的一种方法。PHPDoc格式是PHP文档的一种标准。而大量可用的PHPDoc标签,你还可以创建自己所需标签。
/**
这里是PHPDoc注释
@param bool $foo foo 给函数传递了一些信息
*/
function bar ($foo){}
PHPDoc标签列表请参加:http://manual.phpdoc.org/
DocBook标准是一种综合性的基于XML的文档类型,它定义了程序手册的数据标记。它的设计目的更加关注于创建实际的书籍,而不是关注程序中的注释代码。
第七章 反射API
一个关于反射API的实例
<?php interface Iplugin{
public static function getName();
public static function getMenuItems();
public static function getArticles();
public static function getSideBars();
} class MyCoolIplugin implements Iplugin{
public static function getName(){
return "MyCoolIplugin";
}
public static function getMenuItems(){
return array(array(
'description'=>"MyCoolIplugin",
'link'=>"/MyCoolIplugin"
));
}
public static function getArticles(){
return array(array(
'path'=>"11111111",
'desc'=>'aaaaaaaaa'
));
}
public static function getSideBars(){
return array(array(
'description'=>'SideBars',
'test'=>'qqqqqqqqq'
));
}
} function findIplugin(){
$plugins=array();
foreach(get_declared_classes() as $class){
$reflectionClass= new ReflectionClass($class);
if($reflectionClass->implementsInterface('Iplugin')){
$plugins[]=$reflectionClass;
}
}
return $plugins;
}
function computerMenu(){
$menu=array();
foreach (findIplugin() as $plugin){
if($plugin->hasMethod('getMenuItems')){
$reflectionMethod=$plugin->getMethod('getMenuItems');
if($reflectionMethod->isStatic()){
$items=$reflectionMethod->invoke(null);
}else{
$items=$reflectionMethod->invoke($plugin->newInstance());
}
}
}
$menu=array_merge($menu,$items);
return $menu;
}
function computerArticles(){
$articles=array();
foreach(findIplugin() as $plugin){
if($plugin->hasMethod('getArticles')){
$reflectionMethod=$plugin->getMethod('getArticles');
if($reflectionMethod->isStatic()){
$items=$reflectionMethod->invoke(null);
}else{
$items=$reflectionMethod->invoke($plugin->newInstance());
}
}
}
$articles=array_merge($articles,$items);
return $articles;
}
function computerSideBars(){
$sideBars=array();
foreach (findIplugin() as $plugin){
if($plugin->hasMethod('getSideBars')){
$reflectionMethod=$plugin->getMethod('getSideBars');
if($reflectionMethod->isStatic()){
$items=$reflectionMethod->invoke(null);
}else{
$items=$reflectionMethod->invoke($plugin->newiInstance());
}
}
}
$sideBars=array_merge($sideBars,$items);
return $sideBars;
} print_r(computerMenu());
print_r(computerArticles());
print_r(computerSideBars());