【学习笔记】《深入PHP - 面向对象、模式与实践》(第3版)——第5章 对象工具

来源:互联网 发布:mysql中添加外键约束 编辑:程序博客网 时间:2024/05/16 15:36

第5章 对象工具

5.1 PHP和包

  1. 包是一组相关类的集合,这些类以某种方式组合在一起。包可以把系统的一部分和其他部分分割开来。一些程序语言支持包并为它们提供不同的命名空间。PHP现在还没有包的概念,但是PHP5.3支持命名空间。

5.1.1 PHP包和命名空间

  1. 尽管PHP本身不支持包的概念,开发人员却一直在使用文件系统和命名模式将代码组织成类似于包的结构。

1.命名空间来救场

  1. 从本质上说,命名空间就是一个容器,你可以将类、函数和变量放在其中。在命名空间中,你可以无条件地访问这些项。在命名空间之外,必须导入或引用命名空间,才能访问它所包含的项。
  2. namespace关键字用于创建命名空间,命名空间声明必须是文件中的第一条语句。
  3. PHP支持声明嵌套的命名空间,只需使用反斜杠字符将每一层分开。


  4. namespace example\example;
    use example\example as ex;
  5. __NAMESPACE__常量可以输出当前的命名空间。
  6. namespace example\example{    class example{        //...    }}

2.使用文件系统模拟包

  1. 无论在哪种版本的PHP中,我们都可以使用提供了包结构的文件系统来组织类。
  2. 我们可以使用require_once()include_once()来包含类文件。
  3. require()require_once()都是语句而不是函数。
  4. 和使用require()相比,require_once()需要额外的开销。如果想尽可能地减少系统执行时间,应该考虑使用require()。在很多情况下,效率和便利之间是平衡关系。
  5. 就PHP而言,使用文件系统模拟包没有什么特别的地方,你只是将库脚本放在不同的目录中。他确实有助于形成清晰的组织结构,并且可以和命名空间或者命名约定同时使用。

3.PEAR风格的命名方式

  1. PEAR使用文件系统来定义包,每个类都根据包路径来命名,每个路径名以下划线来分隔。

4.包含路径

  1. 在包含文件时,如果文件系统中文件和目录存放的位置可能发生改变,那么无论是使用相对路径还是绝对路径都不是一种很好的方案。
  2. 可以在PHP的核心配置文件php.ini中设置include_path。
  3. 如果没有修改php.ini文件的权限,可以在程序中使用set_include_path()函数来设置包含路径。
  4. 如果使用Apache作为Web服务器,还可以在服务器应用程序的配置文件(通常是httpd.conf)或Apache配置文件(通常是.htaccess)中设置include_path。
  5. .htaccess文件在一些主机托管公司提供的Web空间中特别有用,该文件提供了对服务器环境非常有限的访问权。

5.1.2 自动加载

  1. 在某些情况下,你可能希望一个文件定义一个类,一一对应,便于管理。这种方法会有额外的开销(包含文件会带来开销),但这种组织方法非常有用,特别是系统需要在运行时使用新类的情况下。
  2. PHP5引入了__autoload()拦截器方法来自动包含类文件。当PHP引擎遇到试图实例化未知类的操作时,会调用__autoload()方法(如果已经定义),并将类名当做字符串参数传递给它。
  3. __autoload()的编写者应该自己定义一种策略来定位和包含缺失的类文件。
  4. __autoload()方法是一种根据类和文件的结构,管理类库文件包含的有效方法。
  5. __autoload()是个强大的工具,但也存在一些限制。尤其是,在一个进程中你只能定义它一次。如果需要动态地修改自动加载函数,那么你应该看一下spl_autoload_register()函数,它提供了那项功能。

5.2 类函数和对象函数

  1. 在开发项目时,需要先检查类是否存在、它是否拥有将要使用的方法等,以避免可能存在的风险。

5.2.1 查找类

  1. class_exists()函数接受表示类的字符串,检查并返回布尔值。
  2. get_declared_classes()函数可以获得脚本进程中定义的所有类的数组。

5.2.2 了解对象或类

  1. get_class()函数可以检查对象的类,它接受任何对象作为参数,并以字符串的形式返回类名。
  2. instanceof操作符有两个操作数,要检测的对象在关键字左边,类或接口名在右边。

5.2.3 了解类中的方法

  1. 可以使用get_class_methods()函数来得到一个类中所有方法的列表,该函数需要一个类名作为参数,返回包含类中所有方法名的数组。
  2. 除非你运行的是早期的PHP5版本,否则只有声明为public的方法才会显示到这个结果列表中。
  3. in_array($method, get_class_methods($object))可以判断调用的类方法是否存在。PHP也为此提供了更专业的工具,你可以用函数is_callable()method_exists()来检查。
  4. 在PHP5中,一个方法存在并不意味着它就可以被调用。对于private、protected和public方法,method_exists()都是返回true。

5.2.4 了解类属性

  1. get_class_vars()函数接受类名作为参数,返回关联数组。在返回的数组中,属性名作为键名,属性值作为键值。

5.2.5 了解继承

  1. get_parent_class()可以找到一个类的父类。
  2. is_subclass_of()函数检测类是否是另一个类的派生类。
  3. instanceof操作符可以检测一个类是否实现了某个接口。SPL(Standard PHP Library,标准PHP类库)的class_implements()函数,使用一个类名或对象引用作为参数,会返回一个由接口名构成的数组。

5.2.6 方法调用

  1. PHP提供了call_user_func()方法实现字符串动态调用方法。
  2. call_user_func_array()函数相比更好用,它的使用方法和call_user_func()相同,但它把目标方法所需的任何参数当做数组来接受。

5.3 反射API

  1. PHP中的反射API就像Java中的Java.lang.reflect包一样。它由一系列可以分析属性、方法和类的内置类组成。

5.3.1 入门

  1. 反射API不仅仅被用于检查类。利用反射API中的这些类,可以在运行时访问对象、函数和脚本中的扩展的信息。
  2. 反射API非常强大,是不可缺少的类测试工具。反射的另一用途是根据命名规则创建一个调用模板类中方法的框架。

5.3.2 开始行动

  1. ReflectionClass提供揭示给定类所有信息的方法,无论是用户自定义的类还是PHP自带的内置类。ReflectionClass的构造方法接受类名作为它的唯一参数。
  2. Reflection有一个静态方法export(),用于格式化和输出Reflection对象管理的数据(即任何实现Reflector接口的类的实例)。
  3. Reflection::export()与调试函数var_dump()相比较,var_dump()函数是汇总数据的通用工具,但使用var_dump()在提取摘要前必须实例化一个对象,而且它也无法提供像Reflection::export()提供的那么多的细节。
  4. var_dump()和print_r()是检测PHP代码中数据的利器,但对于类和函数,反射API提供了更高层次的功能。

5.3.3 检查类

  1. ReflectionClass::getName()返回要检查的类名。
  2. ReflectionClass::isUserDefined()判断类是否已经在PHP代码中被定义。
  3. ReflectionClass::isInternal()判断是否是内置类。
  4. ReflectionClass::isAbstract()判断是否是抽象类。
  5. ReflectionClass::isInterface()判断是否是接口。
  6. ReflectionClass::isInstantiable()判断是否可以得到类的实例。
  7. ReflectionClass::getFileName()提供到类文件的绝对路径。
  8. ReflectionClass::getStartLine()提供类的起始行。
  9. ReflectionClass::getEndLine()查找类的终止行。

5.3.4 检查方法

  1. 就像ReflectionClass可以用于检查类一样,ReflectionMethod对象可以用于检查类中的方法。
  2. 获得ReflectionMethod对象的方法有两种:从ReflectionClass::getMethods()获得ReflectionMethod对象的数组;如果需要使用特定的类方法,ReflectionClass::getMethod()可接受一个方法名作为参数并返回相应的ReflectionMethod对象。

5.3.5 检查方法参数

  1. ReflectionMethod::getParameters()方法可以返回ReflectionParameter对象数组。
  2. ReflectionParameter可以告诉你参数的名称,变量是否可以按引用传递(即方法声明前有一个&符号),还可以告诉你参数类型提示和方法是否接受空值作为参数。
0 0