第十二节–类的自动加载==第十三节–对象串行化(php5)

当你尝试使用一个未定义的类时,PHP会报告一个致命错误. 解决方法就是添加一个类,可以用include包含一个文件. 毕竟你知道要用到哪个类. 但是,PHP提供了类的自动加载功能, 这可以节省编程的时间. 当你尝试使用一个PHP没有组织到的类, 它会寻找一个__autoload的全局函数. 如果存在这个函数,PHP会用一个参数来调用它,参数即类的名称.
例子6.15说明了__autoload是如何使用的. 它假设当前目录下每个文件对应一个类. 当脚本尝试来产生一个类User的实例,PHP会执行__autoload. 脚本假设class_User.php中定义有User类.. 不管调用时是大写还是小写,PHP将返回名称的小写.
Listing 6.15 Class autoloading

第十三节–对象串行化

串行化可以把变量包括对象,转化成连续bytes数据. 你可以将串行化后的变量存在一个文件里或在网络上传输. 然后再反串行化还原为原来的数据. 你在反串行化类的对象之前定义的类,PHP可以成功地存储其对象的属性和方法.[……]

Read more

第十一节–重载(php5)

PHP4中已经有了重载的语法来建立对于外部对象模型的映射,就像Java和COM那样. PHP5带来了强大的面向对象重载,允许程序员建立自定义的行为来访问属性和调用方法.
重载可以通过__get, __set, and __call几个特殊方法来进行. 当Zend引擎试图访问一个成员并没有找到时,PHP将会调用这些方法.
在例6.14中,__get和__set代替所有对属性变量数组的访问. 如果必要,你可以实现任何类型你想要的过滤. 例如,脚本可以禁止设置属性值, 在开始时用一定的前缀或包含一定类型的值.
__call方法说明了你如何调用未经定义的方法. 你调用未定义方法时,方法名和方法接收的参数将会传给__call方法, PHP传递__call的值返回给未定义的方法.

Listing 6.14 User-level overloading

 

 

第十节–抽象方法和抽象类(php5)

面向对象程序通过类的分层结构构建起来. 在单重继承语言如PHP中, 类的继承是树状的. 一个根类有一个或更多的子类,再从每个子类继承出一个或更多下一级子类. 当然,可能存在多个根类,用来实现不同的功能. 在一个良好设计的体系中,每个根类都应该有一个有用的接口, 可以被应用代码所使用. 如果我们的应用代码被设计成与根类一起工作,那么它也可以和任何一个从根类继承出来的子类合作.
抽象方法是就像子类中一般的方法的占位符(占个地方但不起作用),它与一般方法不同—没有任何代码. 如果类中存在一个或更多抽象方法, 那么这个类就成了抽象类. 你不能实例化抽象类. 你必须继承它们,然后实例化子类. 你也可以把抽象类看成是子类的一个模板.
如果你覆写所有的抽象方法, 子类就变成一个普通的类. 如果没有覆写所有方法, 子类仍是抽象的. 如果一个类中中包含有抽象方法(哪怕只有一个), 你必须声明这个类是抽象的, 在class关键字前加上abstract.
声明抽象方法的语法与声明一般方法不同. 抽象方法的没有像一般方法那样包含在大括号{}中的主体部份,并用分号;来结束.
在例子6.13中, 我们定义了一个含有get[……]

Read more

第九节–绑定(php5)

除了限制访问,访问方式也决定哪个方法将被子类调用或哪个属性将被子类访问. 函数调用与函数本身的关联,以及成员访问与变量内存地址间的关系,称为绑定. 
在计算机语言中有两种主要的绑定方式—静态绑定和动态绑定. 静态绑定发生于数据结构和数据结构间,程序执行之前. 静态绑定发生于编译期, 因此不能利用任何运行期的信息. 它针对函数调用与函数的主体,或变量与内存中的区块. 因为PHP是一种动态语言,它不使用静态绑定. 但是可以模拟静态绑定.
动态绑定则针对运行期产生的访问请求,只用到运行期的可用信息. 在面向对象的代码中,动态绑定意味着决定哪个方法被调用或哪个属性被访问,将基于这个类本身而不基于访问范围.
Public和protected成员的动作类似于PHP的前几个版本中函数的动作,使用动态绑定. 这意味着如果一个方法访问一个在子类中被覆写的类成员,并是一个子类的实例,子类的成员将被访问(而不是访问父类中的成员).
看例子6.10. 这段代码输出” Hey! I am Son.” 因为当PHP调用getSalutation, 是一个Son的实例,是将Father中的salutation覆写而来. 如[……]

Read more

第八节–访问方式(php5)

PHP5的访问方式允许限制对类成员的访问. 这是在PHP5中新增的功能,但在许多面向对象语言中都早已存在. 有了访问方式,才能开发一个可靠的面向对象应用程序,并且构建可重用的面向对象类库.
像C++和Java一样,PHP有三种访问方式:public,private和protected. 对于一个类成员的访问方式,可以是其中之一. 如果你没有指明访问方式,默认地访问方式为public. 你也可以为静态成员指明一种访问方式,将访问方式放在static关键字之前(如public static).
Public成员可以被毫无限制地访问.类外部的任何代码都可以读写public属性. 你可以从脚本的任何地方调用一个public方法. 在PHP的前几个版本中,所有方法和属性都是public, 这让人觉得对象就像是结构精巧的数组.
Private(私有)成员只在类的内部可见. 你不能在一个private属性所在的类方法之外改变或读取它的值. 同样地,只有在同一个类中的方法可以调用一个private方法. 继承的子类也不能访问父类中的private 成员.
要注意,类中的任何成员和类的实例都可以访问privat[……]

Read more

第七节–类的静态成员(php5)

类的静态成员与一般的类成员不同: 静态成员与对象的实例无关,只与类本身有关. 他们用来实现类要封装的功能和数据,但不包括特定对象的功能和数据. 静态成员包括静态方法和静态属性.
静态属性包含在类中要封装的数据,可以由所有类的实例共享. 实际上,除了属于一个固定的类并限制访问方式外,类的静态属性非常类似于函数的全局变量
我们在下例中使用了一个静态属性Counter::$count. 它属于Counter类,而不属于任何Counter的实例.你不能用this来引用它,但可以用self或其它有效的命名表达. 在例子中,getCount方法返回self::$count,而不是Counter::$count.
静态方法则实现类需要封装的功能,与特定的对象无关. 静态方法非常类似于全局函数. 静态方法可以完全访问类的属性,也可以由对象的实例来访问,不论访问的限定语是否是什么.
在6.3例中,getCount是一个普通的方法,用->来调用. PHP建立一个this变量,尽管方法没有使用到.但是,getCount不属于任何对象.在有些情况下,我们甚至希望在不存在有效的对象时调用它,那么就应该使用静态方法[……]

Read more

第六节–访问属性和方法(php5)

一个对象实例的属性是变量,就像PHP的其他变量一样. 但是你必须使用->运算符来引用它们. 不需要在属性前使用美元符$. 例如, 6.1中打印User对象的name属性那一行. 
可以联用->,如果一个对象的属性包含了一个对象,你可以使用两个->运算符来得到内部对象的属性. 你甚至可以用双重引用的字符串来放置这些表达式. 看6.5中的例子,对象House中的属性room包含了一组Room对象.
访问方法和访问属性类似. ->运算符用来指向实例的方法. 在例子6.1中调用getLastLogin就是. 方法执行起来和类外的函数几乎相同.
如果一个类从另一类中继承而来,父类中的属性和方法将在子类中都有效,即使在子类中没有声明. 像以前提到过的,继承是非常强大的. 如果你想访问一个继承的属性,你只需要像访问基类自己的属性那样引用即可,使用::运算符.

PHP有两个特殊的命名空间:parent命名空间指向父类,self命名空间指向当前的类. 例子6.6中显示了如何用parent命名空间来调用父类中的构造函数[……]

Read more

第五节–克隆(php5)

PHP5中的对象模型通过引用来调用对象, 但有时你可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本 . 为了这样的目的,PHP定义了一个特殊的方法,称为__clone. 像__construct和__destruct一样,前面有两个下划线.
默认地,用__clone方法将建立一个与原对象拥有相同属性和方法的对象. 如果你想在克隆时改变默认的内容,你要在__clone中覆写(属性或方法).
克隆的方法可以没有参数,但它同时包含this和that指针(that指向被复制的对象). 如果你选择克隆自己,你要小心复制任何你要你的对象包含的信息,从that到this. 如果你用__clone来复制. PHP不会执行任何隐性的复制, 
下面显示了一个用系列序数来自动化对象的例子:

第四节–构造函数和析构函数(php5)

如果你在一个类中声明一个函数,命名为__construct,这个函数将被当成是一个构造函数并在建立一个对象实例时被执行. 清楚地说,__是两个下划线. 就像其它任何函数一样,构造函数可能有参数或者默认值. 你可以定义一个类来建立一个对象并将其属性全放在一个语句(statement)中. 

你也可以定义一个名为__destruct的函数,PHP将在对象被销毁前调用这个函数. 它称为析构函数.

继承是类的一个强大功能. 一个类(子类/派生类)可以继承另一类(父类/基类)的功能. 派生类将包含有基类的所有属性和方法,并可以在派生类中加上其他属性和方法. 你也可以覆写基类的方法和属性. 就像3.1.2中显示的,你可以用extends关键字来继承一个类.

你可能想知道构造函数是如何被继承的. 当它们和其它方法一起被继承时,他们不会在创建对象时被执行.
如果你需要这个功能,你需要用第二章提到的::运算符. 它允许你指向一块命名空间. parent指向父类命名空间,你可以用parent::__construct来调用父类的构造函数.

一些面向对象语言在类之后命名构造函数. PHP的前几个版本也是如此,到现在这[……]

Read more

第三节–定义一个类(php5)

当你声明一个类,你需要列出对象应有的所有变量和所有函数—被称为属性和方法. 3.1.1中显示了一个类的构成. 注意在大括号({})内你只能声明变量或者函数. 3.1.2中显示了如何在一个类中定义三个属性和两个方法.
3.1.1
class Name extends Another Class 

Access Variable Declaration 
Access Function Declaration 

3.1.2

当你声明属性,你不需要指明数据类型. 变量可能是整型,字符串或者是另一个对象,这取决于实际情况.在声明属性时增加注释是一个好主意,标记上属性的含义和数据类型.

当你声明一个方法,你所做的和在类外部定义一个函数是一样的. 方法和属性都有各自的命名空间. 这意味着你可以安全地建立一个与类外部函数同名的方法,两者不会冲突. 例如,一个类中可以定义一个名为date()的方法. 但是你不能将一个方法命名为PHP的关键字,如for或者while.

类方法可能包含PHP中所谓的type hint. Type hint 是[……]

Read more

第二节–对象模型(php5)

PHP5 的对象模型

PHP5有一个单重继承的,限制访问的,可以重载的对象模型. 本章稍后会详细讨论的”继承”,包含类间的父-子关系. 另外,PHP支持对属性和方法的限制性访问. 你可以声明成员为private,不允许外部类访问. 最后,PHP允许一个子类从它的父类中重载成员.

PHP5的对象模型把对象看成与任何其它数据类型不同,通过引用来传递. PHP不要求你通过引用(reference)显性传递和返回对象. 在本章的最后将会详细阐述基于引用的对象模型. 它是PHP5中最重要的新特性.

有了更直接的对象模型,就拥有了附加的优势: 效率提高, 占用内存少,并且具有更大的灵活性.

在PHP的前几个版本中,脚本默认复制对象.现在PHP5只移动句柄,需要更少的时间. 脚本执行效率的提升是由于避免了不必要的复制. 在对象体系带来复杂性的同时,也带来了执行效率上的收益. 同时,减少复制意味着占用更少的内存,可以留出更多内存给其它操作,这也使效率提高.

Zand引擎2具有更大的灵活性. 一个令人高兴的发展是允许析构–在对象销毁之前执行一个类方法. 这对于利用内存也很有好处,让PHP清楚地知道什么时候没有对[……]

Read more

第一节–面向对象编程(php5)

第一节–面向对象编程
面向对象编程被设计来为大型软件项目提供解决方案,尤其是多人合作的项目. 当源代码增长到一万行甚至更多的时候,每一个更动都可能导致不希望的副作用. 这种情况发生于模块间结成秘密联盟的时候,就像第一次世界大战前的欧洲.
//haohappy注:喻指模块间的关联度过高,相互依赖性太强.更动一个模块导致其它模块也必须跟着更动.
想像一下,如果有一个用来处理登录的模块允许一个信用卡处理模块来分享它的数据库连接. 当然出发点是好的,节省了进行另一个数据库连接的支出.然而有时,登录处理模块改变了其中一个变量的名字,就可能割断了两者间的协议.导致信用卡模块的处理出错,进而导致处理发票的模块出错. 很快地,体系中所有无关的模块都可能由此出错.
因此,我觉得有点戏剧性地,绝大多数程序员都对耦合和封装心存感激. 耦合是两个模块间依赖程度的量度. 耦合越少越好.我们希望能够从已有的项目中抽走一个模块并在另一个新项目中使用. 
我们也希望在某个模块内部大规模的更动而不用担心对其他模块的影响. 封装的原则可以提供这个解决方案.模块被看待成相对独立,并且模块间的数据通信通过接口来进行. 模块不通过彼此[……]

Read more

PHP时间戳函数总结一览

一,PHP时间戳函数获取指定日期的unix时间戳 strtotime(”2009-1-22″) 示例如下:

echo strtotime(”2009-1-22″) 结果:1232553600

说明:返回2009年1月22日0点0分0秒时间戳

二,PHP时间戳函数获取英文文本日期时间 示例如下:

便于比较,使用date将当时间戳与指定时间戳转换成系统时间

(1)打印明天此时的时间戳strtotime(”+1 day”)

当前时间:echo date(”Y-m-d H:i:s”,time()) 结果:2009-01-22 09:40:25

指定时间:echo date(”Y-m-d H:i:s”,strtotime(”+1 day”)) 结果:2009-01-23 09:40:25

(2)打印昨天此时的时间戳strtotime(”-1 day”)

当前时间:echo date(”Y-m-d H:i:s”,time()) 结果:2009-01-22 09:40:25

指定时间:echo date(”Y-m-d H:i:s”,strtotime(”-1 day”)) 结果:2009-01-21 09:40:25

([……]

Read more

附录c:加密-php安全基础

作为一本相关安全方面的书,通常加密是需要提及的话题。我之所以在本书的主体部分忽略了加密问题,是因为它的用途是狭窄的,而开发者应从大处着眼来考虑安全问题。过分依赖于加密常常会混淆问题的根源。尽管加密本身是有效的,但是进行加密并不会神奇地提高一个应用的安全性。
  一个PHP开发人员应主要熟悉以下的加密方式:
l        对称加密
l        非对称加密(公钥)
l        Hash函数(信息摘要)
l        信息验证码
  本附录主要关注于使用mcrypt扩展的对称加密算法。你需要参考的资料如下:
  实用加密技术(Applied Cryptography), by Bruce Schneier (Wiley)
http://www.schneier.com/blog/
http://wikipedia.org/wiki/Cryptography
http://phpsec.org/articles/2005/password-hashing.html
http://pear.php.net/package/Crypt_HMAC
http://pear.php.net/package/[……]

Read more

附录B:函数-php安全基础

在我写作本书的时候,http://php.net/quickref.php列出了共3917个函数,其中包括一些类似函数的语法结构,在此我不准备把它们从函数中区分开来,而是把它作为函数看待。
  由于函数数量很大,一一说明它们的正确及安全用法是不太可能的。在此我选出了我认为最需要注意的函数。选择的标准包括使用的频繁度、使用时的危险(安全)度及我本人的经验。
  对于每一个列出的函数,我都会提供推荐的使用方法。在提出这些方法时,我会把安全作为重点考虑。请在实际使用时根据你的需求进行相应调整。
  当一个函数与另一个有相同的风险时,我会给出参见另一个函数的信息,而不是多余地再次描述一遍。
B.1. eval( )
  eval( )函数用于对一个字符串以PHP语句方式解析运行。如:

  上例中会把$string作为PHP语句来运行,因此等价于:

  虽然eval( )非常有用,但是当使用了被污染数据时会非常危险。例如,在下例中,如果$name是被污染的,攻击者可以[……]

Read more

return top