PHP5基础教程

  • 格式:doc
  • 大小:153.00 KB
  • 文档页数:32

*/

php5学习笔记

第一节--面向对象编程

面向对象编程被设计来为大型软件项目提供解决方案,尤其是多人合作的项目. 当源代码增长到一万行甚至更多的时候,每一个更动都可能导致不希望的副作用. 这种情况发生于模块间结成秘密联盟的时候,就像第一次世界大战前的欧洲.

//haohappy注:喻指模块间的关联度过高,相互依赖性太强.更动一个模块导致其它模块也必须跟着更动.

想像一下,如果有一个用来处理登录的模块允许一个信用卡处理模块来分享它的数据库连接.

当然出发点是好的,节省了进行另一个数据库连接的支出.然而有时,登录处理模块改变了其中一个变量的名字,就可能割断了两者间的协议.导致信用卡模块的处理出错,进而导致处理发票的模块出错. 很快地,体系中所有无关的模块都可能由此出错.

因此,我觉得有点戏剧性地,绝大多数程序员都对耦合和封装心存感激. 耦合是两个模块间依赖程度的量度. 耦合越少越好.我们希望能够从已有的项目中抽走一个模块并在另一个新项目中使用.

我们也希望在某个模块内部大规模的更动而不用担心对其他模块的影响. 封装的原则可以提供这个解决方案.模块被看待成相对独立,并且模块间的数据通信通过接口来进行. 模块不通过彼此的变量名来窥探另一个模块,它们通过函数来礼貌地发送请求.

封装是你可以在任何编程语言中使用的一个原则. 在php和许多面向过程的语言中,可以偷懒是很有诱惑的.没有什么可以阻止你通过模块来构建一个假想的web. 面向对象编程是使程序员不会违背封装原则的一种方法.

在面向对象编程中,模块被组织成一个个对象. 这些对象拥有方法和属性. 从抽象的角度来看,方法是一个对象的所做的动作,而属性是对象的特性.从编程角度来看,方法就是函数而属性是变量. 在一个理想化的面向对象体系中,每个部份都是一个对象. 体系由对象及对象间通过方法来形成的联系构成.

一个类定义了对象的属性. 如果你在烘烤一组甜饼对象,那么类将会是甜饼机. 类的属性和方法是被调用的成员. 人们可以通过说出数据成员或者方法成员来表达.

每种语言提供了不同的途径来访问对象. php从c++中借用概念,提供一个数据类型用来在一个标识符下包含函数和变量。最初设计php的时候,甚至php3被开发出时,php并不打算提供开发超过10万行代码的大型项目的能力。随着php和zend引擎的发展,开发大型项目变得有可能,但无论你的项目规模多大,用类来书写你的脚本将可以让代码实现重用。这是一个好主意,特别当你愿意与别人分享你的代码的时候。

有关对象的想法是计算机科学上最令人兴奋的概念之一。开始很难掌握它,但我可以保证,一旦你掌握了它,用它的思维来思考将会非常自然。

第二节--php5 的对象模型

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

//haohappy注:php4中没有private,只有public.private对于更好地实现封装很有好处.

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

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

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

//haohappy注:基于句柄,就是说两个对象可以指向同一块内存,既减少了复制动作,又减少对内存的占用.

zand引擎2具有更大的灵活性. 一个令人高兴的发展是允许析构--在对象销毁之前执行一个类方法. 这对于利用内存也很有好处,让php清楚地知道什么时候没有对象的引用,把空出的内存分配到其它用途.

第三节--定义一个类

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

3.1.1

class name extends another class

{

access variable declaration

access function declaration

}

//定义一个跟踪用户的类

class user

{

//属性

public $name;

private $password, $lastlogin;

//方法

public function __construct($name, $password)

{

$this->name = $name;

$this->password = $password;

$this->lastlogin = time();

$this->accesses++;

}

// 获取最后访问的时间

function getlastlogin()

{

return(date("m d y", $this->lastlogin));

}

}

//创建一个对象的实例

$user = new user("leon", "sdf123");

//获取最后访问的时间

print($user->getlastlogin() ."\n");

//打印用户名

print("$user->name\n");

?>

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

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

类方法可能包含php中所谓的type hint. type hint 是另一个传递参数给方法的类的名字. 如果你的脚本调用方法并传递一个不是类的实例的变量,php将产生一个”致命(fatal)错误” .

你可能没有给其它类型给出type hint,就像整型,字符串,或者布尔值. 在书写的时候, type hint是否应当包含数组类型仍存在争议.

type hint是测试函数参数或者运算符的实例的数据类型的捷径. 你可能总是返回这个方法.

确认你强制让一个参数必须是哪种数据类型,如整型. 3.2.1 确保编译类只产生widget的实例.

3.2.1

php代码:

//组件

class widget

{

public $name=none;

public $created=false;

}

//装配器

class assembler

{

public function make(widget $w)

{

print("making $w->name\n");

$w->created=true;

} }

//建立一个组件对象

$thing = new widget;

$thing->name = gadget;

//装配组件

assembler::make($thing);

?>

除了传递参数的变量外,方法含有一个特殊的变量. 它代表类的个别实例. 你应当用这个来指向对象的属性和其它方法.一些面向对象的语言假设一个不合格的变量提交给本地属性,但在php中方法的任何变量只是在方法的一定范围内. 注意在user类的构造函数中这个变量的使用(3.1.2).

php在属性和方法声明前定义一个访问限定语,如public,private和protected. 另外,你可以用”static”来标记一个成员. 你也可以在类中声明常量. 本章稍后会有不同访问方式的相关讨论.

你可以在一行中列出相同访问方式的几个属性,用逗号来分隔它们. 在3.1.2中,user类有两个private属性--$password和$lastlogin.

第四节--构造函数和析构函数

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

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

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

你可能想知道构造函数是如何被继承的. 当它们和其它方法一起被继承时,他们不会在创建对象时被执行.

如果你需要这个功能,你需要用第二章提到的::运算符. 它允许你指向一块命名空间. parent指向父类命名空间,你可以用parent::__construct来调用父类的构造函数.

一些面向对象语言在类之后命名构造函数. php的前几个版本也是如此,到现在这种方法仍然有效.也就是:如果你把一个类命名为animal并且在其中建立一个命名也是animal的方法,则这个方法就是构造函数.如果一个类的同时拥有__construt构造函数和与类名相同的函数,php将把__construct看作构造函数.这使得用以前的php版本所写的类仍然可以使用. 但新的脚本(php5)应当使用__construct.