《PHP精粹:编写高效PHP代码》——1.2节OOP简介

简介:

本节书摘来自华章社区《PHP精粹:编写高效PHP代码》一书中的第1章,第1.2节OOP简介,作者:(美)  Davey Shafik,更多章节内容可以访问云栖社区“华章社区”公众号查看

1.2 OOP简介
开始冒险吧!在理论知识方面,我们会结合代码示例来讲解,这让你更容易看懂代码的实际意义。

1.2.1 声明类
类相当于蓝图,是表明如何创建对象的一组指令。它还不是一个对象,而仅仅是对象的一个描述。在Web应用程序中,用类来表示各种实体。下面是一个可能用于电子商务应用程序中的Courier类:


91595af0dff53f144ce040c58b0aa085698f6722

以上代码表明了如何声明类,可以将Courier类保存在一个名为courier.php的文件中。这个文件的命名方法是需要牢记的一个要点,其重要性在1.3节中会详细阐述,我们会讲解当需要时如何访问对象。
上面的例子表明Courier类有两个属性:$name和$home_country,以及两种方法:__construct()和ship(),在类中声明方法的方式和我们所熟悉的声明函数的方式完全一样,因此一定要牢记这个语法。当写一个函数的时候,可以用同一种方式向方法中传入参数以及返回值。
你可能已经注意到示例代码中还有一个名为$this的变量,这是一个特别的变量,在对象的范围内它一直是可用的,用于指代当前对象。在本章的示例代码中,会用它从对象内部直接访问变量和调用方法,因此,在阅读本章时要留心这一点。

1.2.2 类的构造
__construct()函数名字前面有两条相连的下划线。在PHP中,两条下划线表示一个神奇的方法,表示这是一个具有特殊意义或功能的方法。在本章我们将看到很多这样的方法。__construct()方法是一种特殊的函数,在实例化一个对象时会调用它,称其为构造函数(constructor)。
PHP 4构造函数
PHP 4中没有什么神奇的方法。对象都有构造函数,并且在类声明中,构造函数的名字与类名相同。虽然在最新版本的PHP中已不再使用这种规范,但在遗留的代码或者与PHP 4兼容的代码中还可以看到这种规范,不过在PHP 5中已不再使用这种规范。

当实例化一个对象时通常会调用构造函数,当释放构造函数进而在代码中使用之前会用它创建和配置对象。构造函数还有一个和它相匹配的神奇方法,称为析构函数(destructor),它是一个名为__destruct()不带参数的方法。当销毁对象时,会调用析构函数,并且运行对象所需的停止或者清除任务。注意,虽然我们不能保证析构函数何时会运行,但当对象因销毁或超出作用域,或者PHP垃圾收集器开始运行等原因而不再使用时,析构函数才会运行。
当我们阅读本章的示例时,将会发现很多这样的示例或者神奇的方法。现在,让我们实例化一个对象,这将极好地解释构造函数是如何运行的。

1.2.3 对象实例化
要实例化或创建一个对象,要使用新的关键字,如同给一个对象取名,需要声明一个类;然后将预期使用的参数传入构造函数中。要实例化一个courier,应该这样做:


5ad7729bba34a236abec93c39c839663f6889daf

var_dump()的输出告诉我们:
这是一个属于Courier类的对象;
它有两种属性;
每个属性的名称和值。
当实例化对象时可以将参数值传入构造函数。在示例中,构造Courier对象时通过构造函数传入参数给$name属性赋值。

1.2.4 自动加载
到目前为止,上述示例表明了如何声明一个类,然后在需要的地方引用那个文件。在一个大型应用程序里,不同的文件需要包含在不同的脚本里,这一切很快会变得复杂而混乱,令人高兴的是,PHP有一种特性可使这一切变得很容易,称为自动加载。当需要一个类声明而不知道在哪里寻能找到类文件时,PHP自动加载会指引我们。
为自动加载定义规则时,用到了另一个神奇的方法:__autoload()。在前面的示例中,引用了一个文件,但作为一种选择,可以用自动加载方法来替代这种方法:


c226febcb4283a34372cc3b41d5bb8d33876712a

只有当你用显而易见的方法命名而且保存包含类定义的文件时,自动加载才会发挥作用。到目前为止,示例都是很简单的内容;类文件都具有相同的名字,都带有.php扩展的小写文件名,因此自动加载函数处理的都是这种简单的示例。
如果需要,也可以创建一个复杂的自动加载函数。例如,许多现代应用程序都是以MVC(Model-View-Controller,第4章会深入解释)模式构建的,在为类定义时,模型、视图和控制器往往会存放在不同的目录,为了解决这个问题,通常会用类的类型来为类命名,比如UserController,而自动加载功能会用字符串匹配或正规表达式来解释要寻找的类的特征,以及在哪里可以找到这些类。

1.2.5 使用对象
到目前为止,我们已经知道如何声明类,实例化对象,并且谈到了自动加载,但我们还没有进行更多的面向对象编程。接下来我们将使用所创建对象的属性和方法来工作,让我们用一些示例代码来看看究竟应该怎么做:


8a5e8f6a85a0e0aaa49fd00bfb47aa18ab2c704b

在这里,使用了对象运算符,这是用一个连字符和大于号组成的符号:->。它将对象与属性、方法或者你想访问的内容连接起来。连接符后的方法带有圆括号,而属性不带圆括号。

1.2.6 使用静态属性和方法
在举例说明了如何使用类,并解释了如何实例化对象之后,接下来要介绍的内容在概念上发生了转变。和初始化对象一样,将类的属性和方法定义为静态的(static)。静态属性或方法在使用时无需事先实例化对象。在任何一种情况下,可以标记一个元素为静态,将静态的关键字放在public之后(或其他可视性修饰符—本章后面会讲到很多这样的情况)。通过双冒号操作符::就可以访问它们。
范围解析操作符
在PHP中,使用双冒号操作符访问静态属性或方法,双冒号操作符在技术上称为范围解析操作符(scope resolution operator)。如果包含::操作符的代码发生问题,你常常会看到一个包含有T_PAAMAYIM_NEKUDOTAYIM内容的错误提示。虽然一眼看上去颇令人恐惧,但这只是一个简单的::引用。“Paamayim Nekudotayim”在希伯来语中的意思是“二点,二次”的意思。

静态属性是仅属于类的变量,而不属于对象。它完全孤立于任何属性,甚至于在类的对象中具有相同名字的属性。
静态方法是不需要访问类的其他部分的方法。因为没有创建用于引用的对象,所以在静态方法里不能引用$this关键字。你经常在库中看到的静态属性,其功能独立于任何对象的属性。它常常用来作为一种命名空间(直到5.3版本PHP才有命名空间;相关内容在下一节中介绍),并且静态属性对于检索对象集合的函数也是非常有用的,可以像这样在Courier类中增加函数:


60c9b94e44ef2c5b8fca790cc63b3eea145ea2a2

如果你想用这种方式调用方法,那么必须将该方法标记为静态方法;否则,你将会看到一个错误提示。这是因为设计一个用于调用的方法时,不论使用静态或是动态的方法,都应该像这样先声明。如果没有必要访问$this,并且这个方法是静态的,那么像示例一样声明和调用它。如果不是这样,那么应该首先实例化对象,这是因为这个方法不是静态的方法。
何时使用静态方法是学习重点。一些类库和框架频繁地使用它们;但在没有严格要求使用的地方,其他类库和框架通常会使用动态函数。

1.2.7 对象和命名空间
从PHP 5.3开始,PHP开始提供对命名空间(namespace)的支持。这一新功能有两个主要目的,第一个目的是为了避免给类取像这样的名字:Zend_InfoCard_Xml_Security_Transform_Exception,这样长达47个字符的名字在代码中使用非常不方便(这里没有任何对Zend Framework的不敬,我们只是随机抽取一个具有描述性的名字);第二个目的是提供简单的方法将类和函数从各种类库中分离出来。每个框架都有不同的优势,可以仔细挑选几个最好的框架在应用程序中使用。然而,当两个类在不同的框架中具有相同的名字时,问题就出现了;在声明两个类时不能取相同的名字。
幸运的是,使用命名空间能解决这个问题,可以用很短的名字为类取名,但要加上前缀。命名空间在文件的顶部声明,并适用于所有在该文件中声明的类、方法和常数。我们将重点关注命名空间对类的影响,但我们要牢记的是,这些原则也可用于其他项目。例如,将代码放入一个名为shipping的命名空间里:


bb0fba1a4477a0456568389be4b777d406286002

因为Courier类嵌套了两个层次的深度,所以用命名空间声明顶部的shop/shipping并将其类定义放进一个文件中。加上这些适当的前缀,你可能想知道这将如何帮助解决长类名的问题;到目前为止,我们似乎只能使用通过命名空间运算符替代下划线的方法!事实上,可以用简写来指代命名空间,甚至包括在一个文件中使用多个命名空间的情况。
下面的示例使用了我们刚才所见列表结构中的一系列类:


3ce94ade675ec4c60aa11715c87efa9cf254f2e8

因为有shipping,所以可以在嵌套命名空间中的最低一层使用缩写,并且因为有user,所以可以创建昵称或缩写来使用这个类。这对于我们逐步解决多数特定元素的同名问题大有裨益。你可以为这些同名元素各取一个有特色的名字以便区分。
命名空间越来越多地应用于自动加载功能,你很容易想象目录分隔符和命名空间分隔符如何相互代表。相对于PHP而言,命名空间是一个新增加的内容,你一定要在类库和框架中理解它们。现在你知道该如何有效使用命名空间了。

相关文章
|
2月前
|
IDE PHP 开发工具
PHP中的类型提示与严格模式:提高代码可维护性
随着PHP语言的发展,开发者对代码的可读性、可维护性和可靠性有了更高的要求。PHP中的类型提示(Type Hinting)和严格模式(Strict Mode)为开发者提供了更强的类型检查机制,有助于提升代码质量和减少潜在的错误,尤其是在大型项目中。
|
3月前
|
安全 程序员 PHP
PHP中的异常处理:提升代码的健壮性
【10月更文挑战第8天】在编程的世界中,错误和异常是不可避免的。它们就像路上的坑洼,可能会让我们的程序“跌倒”。但是,如果我们能够正确地处理这些异常,就可以让我们的程序更加稳健,就像我们学会了如何在坑洼的路上稳稳地行走一样。本文将介绍PHP中的异常处理机制,以及如何使用它来提升我们的代码质量。
|
4月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
4月前
|
存储 Java 数据库连接
php学习笔记-代码基本语法-day01
本文是关于PHP编程语言的基础语法学习笔记,内容包括PHP的介绍、注释风格、数据类型、命名规范、常量和变量的使用,以及变量和常量相关的常用函数。文中详细解释了PHP的基本语法元素和一些易混淆的概念,如传值赋值与传址赋值、可变变量,以及如何检查变量是否已定义或为空。
php学习笔记-代码基本语法-day01
|
1月前
|
PHP 开发者 容器
PHP命名空间深度解析:避免命名冲突与提升代码组织####
本文深入探讨了PHP中命名空间的概念、用途及最佳实践,揭示其在解决全局命名冲突、提高代码可维护性方面的重要性。通过生动实例和详尽分析,本文将帮助开发者有效利用命名空间来优化大型项目结构,确保代码的清晰与高效。 ####
32 1
|
2月前
|
供应链 安全 NoSQL
PHP 互斥锁:如何确保代码的线程安全?
在多线程和高并发环境中,确保代码段互斥执行至关重要。本文介绍了 PHP 互斥锁库 `wise-locksmith`,它提供多种锁机制(如文件锁、分布式锁等),有效解决线程安全问题,特别适用于电商平台库存管理等场景。通过 Composer 安装后,开发者可以利用该库确保在高并发下数据的一致性和安全性。
45 6
|
2月前
|
PHP 开发者 UED
探索PHP中的异常处理:提升代码的健壮性
在PHP开发中,优雅地处理错误和异常是确保应用稳定性和用户体验的关键。本文将通过深入浅出的方式,介绍如何在PHP中实现有效的异常处理机制,包括异常的基本概念、如何抛出和捕获异常,以及最佳实践。准备好让你的代码变得更加健壮和可靠吧!
24 2
|
2月前
|
PHP 开发者
深入理解PHP中的面向对象编程(OOP)
本文旨在探讨PHP中面向对象编程的核心概念和实践,包括类与对象、继承、多态性以及接口和抽象类。通过实际示例,我们将展示如何有效地使用这些特性来提高代码的可维护性和可重用性。无论你是PHP初学者还是有经验的开发者,本文都将帮助你更好地理解和应用OOP原则。
43 6
|
2月前
|
PHP 开发者
PHP中的异常处理:提升代码的健壮性
【10月更文挑战第40天】在PHP编程中,异常处理是确保应用稳定性的关键。本文将引导你理解异常处理的重要性,掌握如何在PHP中捕获和处理异常,以及如何通过自定义异常类来增强代码的错误管理能力。我们将一起探索如何利用PHP的异常处理机制,打造一个更加健壮和可靠的应用程序。
|
3月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性和扩展性
【10月更文挑战第13天】 本文将探讨PHP中常见的设计模式及其在实际项目中的应用。通过对比传统编程方式,我们将展示设计模式如何有效地提高代码的可维护性和扩展性。无论是单例模式确保类的单一实例,还是观察者模式实现对象间的松耦合,每一种设计模式都为开发者提供了解决特定问题的最佳实践。阅读本文后,读者将能更好地理解和应用这些设计模式,从而提升PHP编程的效率和质量。