php学习笔记2016.1

基本类型    PHP是一种弱类型语言。   
 
PHP类型检查函数   is_bool()    is_integer()  is_double()  is_string()   is_object()  is_array()  is_resource()   is_null()
 
继承   继承是从一个基类获得一个或多个派生系类的机制。  继承自另外一个类的类被称为该类的子类。  子类能够增长父类(也称超类,superclass)以外新的功能,所以子类也被称为扩展。
 
构造方法和继承   句柄(handle)  php为此提供了parent关键字    parent ::__construct()    意为“调用父类的__construct()方法”
 
public  private  protected  管理类的访问   若使用旧的var关键字,方法和属性默认设置为public.
在任何地方均可以访问public属性和方法。
只能在当前类忠才能访问private方法或属性,及时在子类中叶不能访问。
能够在当前类或者子类中访问protected方法或属性,其余外部代码无权访问。
 
访问方法  比较好的作法是不要允许直接访问属性,而是提供方法来取得须要的值,这样的方法被称为访问方法,也可称为getter和setter.
 
静态方法和属性   把类当作生成对象的模板,吧对象做为活动组件,对象的方法能够被调用,对象的属性能够被访问。   面向对象编程中的实际操做都是经过类的实例(而不是类自己)完成的。类仅仅是对象的模板。
静态方法是以类做为做用域的函数。静态方法不能访问这个类忠的普通属性,由于那些属性属于一个对象,但能够访问静态属性。 static 关键字
 
常量属性    能够在类中定义常量属性。和全局常量同样,类常量一旦设置后就不能改变。常量属性用const关键字来声明,常量不像常规属性那样以美圆符号开头,按照惯例,只能用大写字母来命名常量。常量属性只包含基本数据类型的值,不能将一个对象指派给常量。像静态属性同样,只能经过类而不能经过类的实例访问常量属性。引用常量时不须要用美圆符号做为前导符,如print ShopProduct :: AVAILABLE;   给已经声明过的常量赋值会引发解析错误。当须要在类的全部实例中都能访问某个属性,而且属性值无需改变时,应该使用常量。
 
抽象类(abstract class)   抽象类不能被直接实例化。抽象类中只定义(或部分实现)子类须要的方法。子类能够继承它而且经过实现其中的抽象方法,使抽象类具体化。  可使用abstract关键字定义一个抽象类。和普通的类同样,能够建立抽象类的方法和属性,可是实例化一个抽象类会产生错误,如一个抽象类, abstract class ShopProductWriter   如今去实例化它    $writer = new ShopProductWriter()  会提示输出严重错误:不能实例化抽象类。  建立抽象方法后,要确保全部子类中都实现了该方法, 但实现的细节能够先不肯定。抽象类的每一个子类都必须实现抽象类中全部的抽象方法,或者把它们自身也声明为抽象方法。  扩展类不只仅负责简单实现抽象类中的方法,还必须从新声明方法。新的实现方法的访问控制不能比抽象方法的访问控制更严格,新的实现方法的参数个数应该和抽象方法的参数个数同样,从新生成对应的类型提示。
 
接口(interface)   抽象类提供了具体实现标准,而接口(interface)则是纯粹的模板。接口只能定义功能,而不包含实现的内容。接口可用关键字interface来声明。接口能够包含属性和方法声明,可是方法体为空。  例如定义一个接口     
interface Chargeable{
      public function getPrice();
}
接口和类很是类似。任何实现接口的类要实现接口中所定义的全部方法,不然该类必须声明为abstract。
一个类能够在声明中使用implements关键字来实现某个接口。这么作以后,实现接口的具体过程和扩展一个仅包含抽象方法的抽象类是同样的。  好比让ShopProduct类实现Chargeable接口,class ShopProduct implements Chargeable    实现多个接口能够用逗号隔开,例如Bookable是接口名  class Consultancy extends TimedService implentes Bookable, Cargeable   这样Consultancy类就实现了不止一个接口,php只支持继承自一个父类,所以extends关键字只能在一个类名以前。
 
 
延迟静态绑定: static关键字  
 
 
错误处理    能够中止执行代码,简单激烈,虽然__construct 和 write() 这样的方法能够检测到错误,可是它们并不知道该如何处理错误。    不在类中直接处理错误,而只返回某种错误标志。错误标志能够是布尔值或整数值。一些类也能够设置错误字符串或标志,让客户端代码在失败以后能够得到更多信息。
 
 
异常(exception)    异常是从php内置的Exception类(或其子类)实例化获得的特殊对象。Exception类型的对象用于存放和报告错误信息。exception类的构造方法接受两个可选参数:消息字符串和错误代码。抛出异常,能够联合使用throw关键字和Exception对象抛出异常。这会中止执行当前方法,并负责将错误返回给调用代码。 异常子类化,若是要建立用户自定义的异常类,能够从exceotion类继承,能够扩展异常类的功能,子类定义了新的异常类型,能够进行本身特有的错误处理。实际上,定义多个catch子句时,也只需一个try语句。
 
 
Final类和方法    继承为类层次(class hierarchy)内毒带来了巨大的灵活性。经过覆写类或方法,根据调用的是哪一个类的实例,调用一样的类方法能够获得彻底不一样的结果。但有时候可能须要类或方法保持不变。若是但愿类或方法完成肯定不变的功能,担忧覆写它会破坏这个功能,那么须要使用final关键字。  final关键字能够终止类的继承。 final类不能有子类,final方法不能被覆写。
 
 
使用拦截器interceptor
 
析构方法    __destruct()   它只在对象在被垃圾收集器收集前(即对象从内存中删除以前)自动调用。能够利用这个方法进行最后的清理工做,例若有一个类须要把其自身的信息写入数据库,这时可使用__destruct方法在对象实例被删除时确保实例把本身保存到了数据库中   
例如function __destruct() {
    if(!empty($this->id)){
       //保存数据
       printf "saving person\n";
     } 
}
 
使用__clone()复制对象    clone使用“值复制”方式(by-value copy)新生成一个对象
class = CopyMe{}
$first = new CopyMe();
$second = clone $first;
//php5及之后的版本:$second和$first如今是两个不一样的对象
在对象上调用clone时,能够控制复制什么。能够经过实现一个特殊的方法__clone()来达到这个目的(__两个下划线开头的方法都是PHP内置的方法)。当在一个对象上调用clone关键字时,其__clone()方法就会被自动调用。
实现__clone()方法时,要注意当前方法执行的环境。__clone()是复制获得的对象上运行的,而不是在原始对象上运行的。给Person类添加上__clone()方法:
class Person{
    private $name;
    private $age;
    private $id;
 
    function __construct ($name, $age)  {
        $this->name = $name;
        $this->age = $age;
    }
 
    function __construct  ($name, $age) {
        $this->id = $id;
    }
 
    function __clone() {
        $this->id = 0;
    }
}
当在一个Person对象上调用clone时,产生了一个新的副本,而且新副本的__clone()方法会被调用。这意味着咱们在__clone()中从新赋值会生效。
 
 
定义对象的字符串值    经过实现本身的 __toString()方法,能够控制输出字符串的格式。 __toString()方法应当返回一个字符串值。当把对象传递给print或echo时,会自动调用这个方法,并用方法的返回值来替代默认的输出内容。如在Person类中添加__toString()方法:
class Person{
    function getName() {return "Bob";}
    function getAge() {return 44;}
    function __toString() {
        $desc = $this->getName();
        $desc = "(age".$this->getAge().")";
        return $desc;
    }
}
如今把Person对象打印 出来,该对象会被解析为:
$Person = new Person();
print $person;
-----------------------
Bob(age 44)
-----------------------
 
 
回调,匿名函数和闭包   
 
 
 
PHP包和命名空间   命名空间就是一个容器,能够将类,函数和变量放在其中,在命名空间中,能够无条件地访问这些项,在命名空间以外,必须导入或引用命名空间,才能访问它所包含的项。namespace.
使用use关键字,利用该关键字,能够为当前命名空间中的其余命名空间起别名  例:
namespace main;
use com\getinstance\util;
util\Debug::helloWorld();
导入com\getinstance\util命名空间,并隐式地为其使用了别名until。没有使用前导反斜线字符做为开始。这里是从全局命名空间而不是从当前命名空间搜索要使用的参数。若是不想引用命名空间,能够导入Debug类自己:
namespace main;
use com\getinstance\util\Debug;
util\Debug::helloWorld();
以后吐过main命名空间中已经包含了Debug类,会形成命名冲突,解决方案是显式使用别名。
namespace main;
use com\getinstance\util\Debug as uDebug;
.......
......
.....
uDebug::helloWorld();
在use关键字后使用as子句,能够将别名Debug修改成uDebug。
若是打开命名空间块的时候不指定名称,那就能够进入全局空间。
 
 
使用文件系统模拟包
 
PEAR风格的命名方式
 
包含路径
 
自动加载
 
 
类函数和对象函数      
查找类   class_exists()函数接受表示类的字符串,检查并返回布尔值。若是类存在,则返回true,不然返回false。
对象或类    有不少用于检测对象类型的基本工具。首先可使用get_class()函数检查对象的类。它接受任何对象做为参数,并以字符串的形式返回类名。  instanceof()操做符有两个操做数,要检测的对象在关键字左边,类或借口名在右边。若是是给定类型的实例,则返回true。
 
类中的方法   可使用get_class_methods()函数来获得一个类中全部的方法列表。该函数须要一个类名做为参数,返回包含类中全部方法名的数组。  print_r( get_class_methods(  'CdProduct' ) ); //CdProduct是参数类。在调用某个方法以前,先检测该方法是否存在于get_class_methods()返回的数组中,可使用函数is_callable()和method_exists()来检查。两个函数中is_callable()更高级些,它接受字符串变量形式的方法名做为第一个参数,若是类方法存在且可被调用,则返回true。若是要检测类中的方法能否被调用,能够给函数传递一个数组而不是类方法名做为参数。数组必须包含对象或类名,以将其做为它的第一个元素,要检查的方法名做为第二个元素。若是该方法在类中存在,函数会返回true。
 
 
类属性    get_class_vars()函数接受类名做为参数,返回关联数组。在返回的数组中,属性名做为键名,属性值做为键值。
 
 
继承   get_parent_class()来找到一个类的父类。这个函数须要一个对象或类名做为参数,而且若是父类存在的话,就返回父类的名字。若是不存在这样的类,即咱们检测到的类没有父类,就返回false。  也可可使用is_subclass_of()函数检测类是不是另外一个类的派生系。它须要接受一个子类对象和父类的名字。若是第二个参数是第一个参数的父类的话,该函数就返回true。 is_subclass_of() 只会告诉你类的继承关系,而不会告诉你类是否实现了一个接口。所以若是须要检测一个类是否实现了某个接口,应当使用instanceof操做符,或者可使用一个函数,该函数式SPL(Standard PHP Library, 标准PHP类库)的一部分。class_implements()使用一个类名或一个对象引用做为参数,而且返回一个由接口名构成的数组。
 
方法调用    
使用字符串来动态调用方法的例子
$product = getProduct();     //得到对象
$method = "getTitle";           //定义方法名
print $product->$method;  //调用方法
PHP还提供call_user_func()方法来达到相同的目的。
 
反射API   不可缺乏的类测试工具 ReflectionFuction
var_dump()和姊妹函数print_r()是检测PHP代码中数据的利器,但对于类和函数,反射API提供了更高层次的功能。
 
检查类   ReflectionClass::getName()返回要检查的类名。若是类已经在PHP代码中定义,ReflectionClass::isUSerDefined()方法返回true;若是是内置类,则ReflectionClass::isInsternal()返回true。 能够用ReflectionClass::isAbstract()来测试一个类是不是抽象的,用ReflectionClass::isInterface()来测试类是不是接口。若是想获得类的实例,能够用RefectionClass::isInstantiable()测试是否可行。
 
检查方法   就像ReflectionClass能够用于检查类同样,ReflectionMethod对象能够用于检查类中的方法。 得到ReflectionMethod对象的方法有两种:从ReflectionClass::getMethod()可接受一个方法名做为参数并返回相应的ReflectionMethod对象。
 
检查方法参数   反射API提供了ReflectionParameter类。要得到ReflectionParameter对象,须要Reflection Method对象的帮助。  ReflectionMethod::getParameters()方法可返回ReflectionParameter对象数组。  ReflectionParameter能够告诉你参数的名称,变量是否能够按引用传递(即方法声明前有一个&符号),还能够告诉你参数类型提示和方法是够接受空值做为参数。
 
面向对象设计和过程式编程   
 
内聚(cohesion)是一个模块内部各成分之间的关联程度的度量。理想状况下,应该使各组件职责清晰,分工明确。若是代码间的关联范围太广,维护就会困难,由于你须要在修改某部分代码的同时修改相关的代码。
 
耦合  当系统各部分代码紧密绑在一块儿时,就会产生紧密耦合,这时在一个组件中的变化会迫使其余部件随之改变。紧密耦合并非过程式代码特有的,可是过程式比较容易产生耦合问题。
 
正交(orthogonality)指将职责相关的组件牢牢组合在一块儿,而与外部系统环境隔开,保持独立。正交主张重用组件,指望不须要任何特殊配置就能把一个组件插入到新系统中。这样的组件有明确的与环境无关输入和输出。正交代码使修改变地更简单,由于修改一个实现只会影响到被改动的组件自己。更安全,bug的影响做用域只局限于它的做用域之中。
----------------------------php学习笔记2016.1
相关文章
相关标签/搜索