PHP基础学习总结(上)

一、面向对象基础

1.类与对象

  1. 定义类基本语法:class 类名{}
<?php
//定义一个空类
class Nothing{
}
  1. 类无法直接访问,需要得到类的具体对象才能访问,可以通过实例化new来实现对象的创建:new类名[( )]
<?php
class My{}
new My;			//创建一个My类的对象
new My();		//创建一个My类的对象
  1. 对象创建后可以直接使用或者打印,但是为了方便后续使用,通常使用变量保存实例化的对象
<?php
class My{}
var_dump(new My);		//直接打印输出对象

$m = new My;			//保存对象
var_dump($m);
  1. 成员变量:就是类结构{}下直接定义的变量,但是定义的方式与普通变量稍微有点不同,需要在变量名字前使用一个关键字public,定义语法:public变量名字[=值];,成员变量可以赋值也可以不赋值
<?php
class Buyer{
	public $name;		//正确:没有赋值
	public $money = 0;	//正确:有赋值
}
  1. 成员变量访问:成员变量必须通过对象才能进行访问,也就是需要先通过实例化得到对象,然后通过对象实现对成员变量的增删改查:访问语法:$对象名->属性名
<?php
class Buyer{
	public $name;
	public $money = 0;
}
$b = new Buyer();
//访问属性
echo $b->money;
//修改属性
$b->money = 1000;
//删除属性
unset($b->name);
//新增属性
$b->age = 20; 
  1. 成员方法:就是在类结构{}下定义的函数,函数内部的内容与原来函数结构一样,可以有分支、循环结构等
<?php
class Buyer{
	function display(){
		echo __CLASS__;
	}
}
  1. 成员方法访问:成员方法也是需要通过对象进行访问的,访问语法为:$对象名->方法名字
<?php
$b = new Buyer();
$b->display();
  1. 类常量:类常量是在类结构{}下定义的常量,类常量的定义只能使用一种方式:const 常量名 = 值;
<?php
class Buyer{
	const PI = 3.14;
}
  1. 类成员中:属性、类常量和方法都可以无限定义,但是定义的原则是相关性。除了以上三个类成员,不能在类结构{}中直接写其他任何代码
  2. 访问修饰限定符:public、protected、private

2.构造方法

  1. 构造方法实现:在类中增加一个方法__construct()即可
<?php
class Saler{
	public $count;
	private $money;
	//构造方法:初始化属性
	public function __construct($count,$money){
		$this->count = $count;
		$this->money = $money;
	}
}
$s1 = new Saler(100,100);
$s2 = new Saler(1000,1000);

3.析构方法

  1. 析构方法实现:类中增加一个__desturct()方法
<?php
class Saler(){
	//析构方法
	public function __destruct(){
		echo __FUNCTION__;
	}
}
  1. 析构方法是对象用来调用释放对象中的资源,不是用来删除对象的
  2. 对象销毁情形:
  • 保存对象的变量被用来保存其他数据,导致对象内存没有任何变量引用
  • 删除对象变量
  • 脚本执行结束:释放所有变量

4.对象传值

  1. 对象传值就是保存对象的变量赋值给另外一个变量
  2. 对象传值是引用传递,不管对象赋值给多少个变量,内存中只有一个对象
<?php
class Saler{}
$s1 = new Saler();
$s2 = $s1;
//证明
var_dump($s1,$s2);		//同一个对象
$s1->name = 'Saler';	//更改一个变量所保存对象的属性
echo $s2->name;			//输出Saler

5.范围解析操作符

  1. 范围解析操作符,由两个冒号组成“::”,是专门用于类实现类成员操作的,可以实现类直接访问类成员
  2. 类常量的访问方式:类名:: 常量名
<?php
class Saler{
	//类常量
	const PI = 3.14;
}
echo Saler::PI;

6.静态常量

  1. 静态属性:在类中定义属性的时候使用static关键字修饰,访问的时候只能使用类+范围解析操作符+静态属性访问
  2. 静态方法:在类中定义方法的时候使用static关键字修饰,访问的时候使用类+范围解析操作符+静态方法名字()访问
<?php
class Saler{
	//属性
	public $money = 0;
	public static $count = 0;	//静态属性
	//静态方法
	public static function showCount(){
		//输出静态属性
		echo Saler::$count,__FUNCTION__,'<br/>';
}

//静态成员可以直接使用类访问,而不需要先实例化对象
echo Saler::$count;
Saler::showCount();

//普通属性访问
$s = new Saler();
var_dump($s);
echo $s->money;
  1. 在类的内部也可以访问静态成员,同样是使用类名+范围解析操作符+静态属性/静态方法()
  2. 静态方法的本质是给类访问,所以不允许在静态方法内部使用$this对象
  3. 静态成员的访问效率比非静态成员高,因此有种说法是能用静态的时候就不用非静态

7.self关键字

  1. self关键字是一种在类的内部(方法里面)使用,代替类名的写法。能够保障用户方便修改类名字
  2. self是用来代替类名的,与范围解析符::一起使用的
  3. self也可以在类的内部方便实例化对象:比如构造方法被私有化之后,就没有办法在类外部实例化对象,此时可以在类内部进行对象实例化
<?php
class Sale{
	//属性
	private static $count = 0;			//私有,不允许外部直接访问
	//方法
	public static function showClass(){
		echo Saler::$count;
		echo self::$count;				//代替类名
	}
	//构造方法:私有化
	private function __construct(){}
	//静态方法
	public static function getInstance(){
		//return new Sale();
		return new self();
	}
}
sale::showClass();

8.类的加载

  1. 定义:所谓类的加载,本质是因为类的访问必须保证类在内存中已经存在,所以需要在用类之前将类所在的PHP文件加载到内存
  2. 手动加载:即要访问某个类之前,使用文件包含将类所在的文件加载进来
类文件:Saler.php
<?php
class Saler{}
?>

应用文件:useSaler.php
<?php
//使用Saler类需要先包含Saler类所在的文件
include_once'Saler.php';			//通常使用include_once,因为类不允许重名
$s = new Saler();
?>
  1. 加载类文件是一种比较消耗资源的方式,所以有的时候不确定是否在内存中存在,可以事先使用class_exists()函数来判断是否存在,存在就不用加载,不存在才加载
<?php
//使用Saler类,但是不确定内存中是否存在
if(!class_exists('Saler')){
	//不存在:加载
	include_once'Saler.php';
}
//使用
$s = new Saler();
  1. 自动加载:PHP没有那么智能的系统自动加载,所谓自动加载只是PHP提供了一种加载机制:即事先定义一个函数__autoload(),然后当系统需要使用类,而内存中又不存在的时候,系统就会自动调用__autoload()函数来加载类文件
<?php
//自动加载机制:利用系统提供的__autoload()函数
function __autoload($classname){			//参数为类名,即当前需要访问的类的名字
	//需要人为定义去哪加载,怎么加载
	include_once $classname . '.php';		//假定为当前目录下,类文件名字为:类名.php
	exit;
}

//使用类:内存目前并没有
$s = new Saler();			//系统发现内存没有Saler,所以调用__autoload()去加载
?>
  1. 一个系统里,可能类文件会放到不同的路径下,因此一个完整的自动加载函数,应该进行文件判定以及加载功能
  2. 随着PHP版本的提升,在7以后,采用一种注册机制,将用户自定义的函数,放到系统内部,使用spl_autoload_register(定义好的函数)
<?php
//定义自动加载
function my__autoload($classname){
	//组织文件路径:假设当前路径下,有两个文件夹下都有类c和m
	$c_file = 'c/' . $classname . '.php';		//如c/Saler.php
	if(file_exists($c_file)){
		include_once $c_file;
		exit;
	}else{
		//说明c文件夹没有对应的文件
		$m_file = 'm/' . $classname . '.php';	//如m/Saler.php
		if(file_exists($m_file)){
			include_once $m_file;
		}
	}
}
//此时,上述函数永远不会执行,除非将函数注册到系统内部
spl_autoload_register('my_autoload');

?>
  1. 同时,spl_autoload_register()函数可以注册多个自定义的加载函数,更方便管理
<?php
function c_autoload($classname){
	$c_file = 'c/' . $classname . '.php';
	if(file_exists($c_file)){
		include_once $c_file;
	}
}
function m_autoload($classname){
	$c_file = 'm/' . $classname . '.php';
	if(file_exists($m_file)){
		include_once $m_file;
	}
}

//全部注册
spl_autoload_register('c_autoload');	//先尝试调用第一个自定义加载函数:找到了结束;找不到找第二个函数
spl_autoload_register('m_autoload');
  1. 类实现自动加载
class Autoload{
	//实现不同文件夹的自动加载
	public static function loadC($classname){
		$c_file = 'c/' . $classname . '.class.php';
		if(file_exists($c_file))require_once $c_file;
	}
	public static function loadM($classname){
		$m_file = 'm/' . $classname . '.class.php';
		if(file_exists($m_file))require_once $m_file;
	}
}
//自动加载
spl_autoload_register(array('Autoload','loadC'));
spl_autoload_register(array('Autoload','loadM'));

9.对象克隆

  1. 克隆对象clone,即通过已有的对象复制一个新的同样地对象,但是两者之间并非同一个对象
  2. 对象克隆是通过clone关键字实现,即:clone对象
  3. 克隆出来的对象与原来对象是两个内存地址,因此是两个不同的对象
<?php
class Saler{
	//属性
	public $count;
	private $money;
}
//实例化
$s1 = new Saler();
$s1->count = 1;

//克隆
$s2 = clone $s1;
?>
  1. 对象在实例化的时候会自动调用存在的构造方法__construct(),同样地,在类的内部,PHP允许定义一个__clone()的方法,在对象被克隆后,新克隆出来的对象会自动调用
  2. 如果不允许对象被克隆,可以将__clone()方法私有化(本质是不允许对象在外部被克隆)

二、设计模式

1.单例模式

  1. 定义:单例模式singleton,是一种类的设计最多只会产生一个对象的设计思想
  2. 单例模式的目的是为了保护资源的唯一性
    –私有化构造方法:禁止在类外无限实例化对象
    –私有化静态属性:禁止对象无限克隆对象
    –公有化静态方法:允许外部通过调用类内部方法获取对象
<?php
	//私有化构造方法
class Singleton{
	//静态属性:保存生产出来的对象
	private static $object = NULL;
	
	private function __construct(){}
	//类入口:允许类进入类内部
	public static function getInstance(){
		//判定静态属性是否存在当前类的对象
		if(!(self::$object instanceof self)){
			//当前保存的object数据不是Singleton的对象
			//产生对象
			self::$object = new self();
		}
		return self::$object;
	}
	//私有化克隆方法
	private function __clone(){}
}
//外部获取对象
$s = Singleton::getInstance();

2.工厂模式

  1. 工厂模式factory,是指像工厂一样流水线生产对象,由一个地方生产对象,其他位置就不需要额外实例化对象,从而可以方便后期代码统一的维护。而且工厂模式下可以方便隐藏真实的类结构,因此更加安全
  2. 工厂模式针对的是“相同模型”的统一产出,即使用工厂模式产出对象的类都有相同的结构或者功能。所以,首先要有一批具有类似功能的类(其实本质是同样的大类下的小类)
//工厂类
class factory{
	//静态工厂方法:专门产生类的对象的
	public static function getInstance($classname){
		return new $classname();
	}
}
//使用工厂
$m = factory::getInstance('  ');

三、PHP继承

1.基本实现

  1. 继承基本语法:class 子类 extends 父类{}
<?php
//定义基类
class Human{
	//方法
	public function showName(){
		echo __CLASS__;
	}
}
//子类(派生类)
class Man extends Human{
}
//实例化子类
$m = new Man();
$m->showName();			//访问继承自父类的方法

2.有限继承

  1. 继承内容:PHP中继承是子类继承父类所有的公有成员、受保护成员和私有属性,不能继承父类的私有方法
  2. 静态成员(类常量)也遵循继承规则(PHP继承本质是对象),只是访问方式是由类进行访问
  3. 构造方法和析构方法也可以被子类继承,此时需要注意子类对象实例化时对应的父类构造方法的参数

3.重写override

  1. 定义:重写,即子类中定义了与父类重名的成员,子类可以重写父类任意类成员,通常重写是用来重写父类的方法,用于扩展或者更改某些业务逻辑
  2. 重写父类成员之后,子类只会直接访问子类的成员(覆盖)
  3. 不管是公有还是受保护属性,一旦重写,父类的就会不存在,而私有属性不会被覆盖而丢失
  4. 重写的要求:
    ① 子类重写父类的方法,控制权不能高于父类,即子类可以比父类更开放;
    ② PHP中重写要求子类重写父类方法的时候,必须保证与父类同名方法参数一致(在方法参数一致不单单要求数量一致,而且数据类型要求也必须相同,但形参名字可以不同);
    ③重写针对的是被继承的成员,父类私有方法不会被继承,因此不受要求。
  5. 重写是指子类拥有特殊的情况,一般是需要在父类的基础上进行扩展,此时如果想要继续保证父类被重写的方法继续执行(默认永远只访问子类重写的新方法),需要在子类重写方法的时候使用parent关键字
<?php
//父类
class Human{
	protected function show(){
		echo __CLASS__,'<br/>';
	}
}
//子类继承
class Man extends Human{
	//重写
	public function show(){
		//强制调用父类被重写方法
		parent::show();
		//扩展业务逻辑
		echo __CLASS__,'<br/>';
	}
}
  1. parent不能访问父类的属性,可以访问静态属性、静态方法、类常量和普通方法

4.PHP继承特点

  1. PHP中继承只能单继承:即子类只有一个父类(有些语言支持多继承)
  2. PHP若想继承多个类,可以使用链式继承
  3. PHP中继承只有私有方法不能被继承
  4. PHP允许子类继承父类的构造方法和析构方法

5.静态延迟绑定

  1. 静态延迟绑定,即在类的内部用来代表类本身的关键字部分不是在类编译时固定好,而是当方法被访问时动态地选择来访者所属的类。静态延迟绑定就是利用static关键字静态绑定self,静态延迟绑定需要使用到静态成员的重写
  2. 静态延迟绑定一定是通过继承后的子类来进行访问才有效果
//父类
class Human{
	public static $name = 'Human';
	public static function showName(){
		//静态绑定
		echo self::$name,'<br/>';
		//静态延迟绑定
		echo static::$name,'<br/>';
	}
}
//子类
class Man extends Human{
	//重写父类静态属性
	public static $name = 'Man';	//静态属性因为存储在类内部,因此不会被覆盖
}
//子类访问
Man::showName();			//输出Human和Man

6.Final关键字

  1. 定义:最终类,使用final关键字修饰类名,表示此类不可以被继承
  2. 基本语法:final class 类名
  3. final关键字不止修饰类表示类不可被继承,还能修饰方法,表示方法不能被重写
//父类
class Human{
	public function show(){				//普通方法
	public final function walk(){		//最终方法
}
//子类
class Man extends Human{
	//重写
	public function show(){}
	public function walk(){}			//不能重写父类中的最终方法
}		

7.Abstract关键字

  1. 定义:抽象类,使用abstract关键字修饰的类,表示该类只能被继承,不能被实例化
  2. 抽象类只能被继承
//抽象类
abstract class Human{}
  1. abstract关键字还可以用来修饰方法(抽象方法),abstract修饰的方法不能有方法体,而且有抽象方法的类必须声明为抽象类
  2. 抽象方法因为要被子类继承实现,所以不能使用private修饰(私有方法不会被继承)
  3. 子类继承抽象类后,如果抽象类中有抽象方法,那么子类必须选择自己成为抽象类或者实现抽象方法(所有抽象方法)

8.接口Interface

  1. 定义:使用interface关键字定义,与类类似,专门用来规范一些共性类必须实现的方法
  2. 接口定义:使用interface关键字,后跟接口名字(与类结构一样)
interface Human{}
  1. 接口不是类,不可以被实例化
  2. 接口实现:接口只能被类实现:implements
class Man implements Human{}
  1. 接口成员:接口中只能定义公有抽象方法接口常量
interface Human{
	//接口常量
	const NAME = '人';
	//接口抽象方法
	public function eat();			//在接口中:方法默认就是自带abstract关键字
	//错误示例
	public function go(){}			//错误:接口中的方法必须为抽象
	public $age;					//错误:接口中不能有属性
	public static $count = 0;		//错误:接口中不能有静态属性(成员属性)
	protected function walk();		//错误:接口方法必须为公有抽象方法
}
  1. 实现接口的类成员,不允许重写接口中的常量,不允许增加接口方法的控制权限
  2. 接口可以继承接口:extends,而且接口可以多继承接口
interface Human{
	public function walk();
}
interface Animal{
	public function eat();
}
//单继承
interface Man extends Human{}
//多继承
interface Ape extends Human,Animal{}

9.trait代码复用

  1. Trait是为类似PHP的单继承语音而准备的一种代码复用机制,是一种类似class的关键字
trait Eat{
}
  1. trait内部可以拥有一个类能拥有的成员属性(包含静态),成员方法(包含静态),但不能有类常量
  2. trait是用来实现代码的复用的,不可以被实例化也不可以被继承(不是类)
  3. trait是用来将公共代码提供给其他类使用的,而类要使用trait的前提是加载对应的trait
trait Eat{
	public function show(){
		echo 'eat';
	}
}
//类中加载trait
class Human{
	//加载:使用use关键字
	use Eat;					//use就表示将trait Eat中的所有东西拿到了当前类Human中
}
//使用trait中的内容
$h = new Human();
$h->show();						//eat:Human类自己没有show方法,但是因为使用了trait Eat,所以可用
  1. 如果同时引入的多个trait中有同名方法,那么会产生冲突:解决冲突的方法是使用insteadof代替处理以及对被替代方法使用别名
trait t1{
    public function eat(){
        echo 't1,eat';
    }
}
trait t2{
    public function eat(){
        echo 't2,eat';
    }
}

class Human{
    use t1,t2;				//错误:eat()方法冲突
}

//解决方案:明确替代
class Person{
    use t1,t2{					//花括号
        t2::eat insteadof t1;	 //t2的eat代替t1的eat
    }
}
$p = new Person();
$p->eat();						//t2,eat

//解决方案:先替换后别名
class Animal{
    use t1,t2{
        t1::eat insteadof t2;	//明确使用t1中的eat方法
        t2::eat as eat2;		//t2中的eat方法改名叫eat2
    }
}
$a = new Animal();
$a->eat();						//t1,eat
$a->eat2();						//t2,eat
  1. 同名覆盖问题:如果类中有与引入的trait同名成员,会有不同处理
  • 属性:不允许重名,即类中不允许定义与trait中同名的成员属性(静态属性也一样)
  • 方法:类覆盖trait
  1. 继承覆盖问题:如果类中在使用trait的同时,也是继承自父类,而trait中与父类中有同名方法,那么trait中将覆盖父类同名方法;如果要访问父类方法,可以在trait同名方法中使用parent关键字访问父类同名方法
  2. 另外,trait自己不能访问,只是用来给其他类提供代码复用的,因此允许类在使用trait时更高里面方法的访问控制权:在as之后,使用目标访问修饰限定符
trait Eat{
    private function show(){
        echo 'eat';
    }
}
class Human{
    use Eat{
        show as public eshow;				
        //注意:as是用来设定别名的,虽然没有同名show,但是系统认为show已经存在,所以必须别名
    }
}
$h = new Human();
$h->eshow();

10.PHP重载

  1. 定义:重载overload,本意指在一个类中可以出现多个同名方法,彼此之间参数个数和类型不一样。但是PHP中不支持同名方法,而且也不区分数据类型(弱类型语言),所以PHP不支持传统重载。PHP中的重载指的是当某些不允许操作发生时,会自动调用的一种内部机制,即自动调用相关的魔术方法。
  2. 魔术方法:指系统为类中预先设计好的,只需要开发者实现的方法,魔术方法以双下划线__开始。对象在某些特定情况下会自动调用的方法。构造方法、析构方法和克隆方法就是魔术方法
class Man{
    public function __construct(){}
}
new Man();			//实例化后对象自动调用(触发时机:对象被实例化)
  1. PHP重载是指某些容错处理(也可以理解为为了某些特殊情况而自动调用),在访问没有权限或者不存在的属性或者方法的时候,会自动触发的魔术方法。
  • 属性重载
  • 方法重载
  1. 属性重载:当PHP对象访问不存在的或者没有权限访问的属性的时候会自动调用的方法
  • __get($key):读属性的时候触发
  • __set($ key,$value):写属性的时候触发
  • __isset($key):外部调用isset()函数或者empty()函数时自动触发
  • __unset($key):外部调用unset()结构删除对象属性时自动触发
  • __toString():对象被当做普通变量输出或者连接时自动调用
class Man{
    private $age = 10;
    
    //读取重载
    public function __get($key){
        echo $key,__METHOD__,'<br/>';
    }
    
    //写重载
    public function __set($key,$value){
        echo $key . ' : ' . $value . '<br/>';
    }
    
    //查是否存在重载
    public function __isset($key){
        echo $key,__METHOD__,'<br/>'
    }
    
    //删除属性重载
    public function __unset($key){
        echo $key,__METHOD__,'<br/>';
    }
    
    //对象字符串化
    public function __toString(){
        echo __METHOD__,'<br/>';
    }
}
//实例化
$m = new Man();
$m->age;			//类外访问私有属性:原本不允许
$m->age = 100;		//设置
isset($m->age);		//判定
unset($m->age);		//删除
  1. 属性重载的目的:一方面为了不让程序运行出错,另一方面可以在类内部由我们自己控制内容的访问
class Man{
    private $age = 10;
    
    //读取重载
    public function __get($key){
        //echo $key,'<br/>';
        //定义一个允许访问列表:假设有很多私有属性
        $allow = array('age');
        //判定是否在列表内:在就允许访问,不在就返回NULL或者false
        if(in_array($key,$allow)){
            return $this->$key;				//可变属性:$key是外部访问的目标,最终为$this->age
        }
        
        //不允许访问
        return false;
    }
    
    //写重载(该方法没有返回值)
    public function __set($key,$value){
        //echo $key . ' : ' . $value . '<br/>';
        //与__get理论类似:允许的设置,不允许的不设置(什么都不做即可)        
    }
    
    //判定重载
    public function __isset($key){
        //给出内部判定结果
        return isset($this->$key);
    }
    
    //对象重载
    public function __toString(){
        //返回一个指定字符串(一般是当类有属性保存某些信息时,输出某个属性)
        return __METHOD__;	
    }
}
  1. 方法重载:当PHP对象访问不存在的方法或者不允许访问的方法时自动调用的方法(抑或是谋者特殊情况,如构造方法)
  • __call($ function_name, [$args]):对象调用不可调用方法时触发
  • __callStatic($ function_name, [$args]):类访问不可调用静态方法时触发
class Man{
    private function show(){
        echo __METHOD__,'<br/>';
    }
    private static function staticShow(){
        echo __METHOD__,'<br/>';
    }
    
    //普通方法重载
    public function __call($name){
        echo $name,__METHOD__,'<br/>';
    }
    
    //静态方法重载
    public static function __callStatic($name){
        echo $name,__METHOD__,'<br/>';
    }
}

//访问不可访问的方法
Man::staticShow();
$m = new Man();
$m->show();
  1. 方法重载的主要目的:不让外部访问出错。当然,如果必要时也可以进行内部访问
class Man{
    private function show(){
        echo __METHOD__,'<br/>';
    }
    private static function staticShow(){
        echo __METHOD__,'<br/>';
    }
    
    //方法重载
    public function __call($name,$arg){
        //允许访问列表
        $allow = array('show');
        
        //判定是否在列表中
        if(in_array($name,$allow)) return $this->$name($arg);
        //其他情况
        return false;
    }
    public static function __callStatic($name){
        //不允许访问
        return false;
    }
}
  1. 并非所有类都需要实现这些重载,只是如果有类需要对外提供访问使用的时候才有必要采取

11.对象遍历foreach

  1. 定义:遍历对象,其实就是指将对象中的所有属性(公有属性)以键值对的形式取出并进行访问
//定义类
class Man{
    public $name = 'LiLei';
    public $height = 178;
    public $weight = 140;
    protected $age = 30;
    private $money = 1000;
}
//实例化
$m = new Man();
//遍历
foreach($m as $k => $v){
    echo $k . ' : ' . $v . '<br/>';		//$k为属性名,$v为属性值
}

四、命名空间

1.命名空间基础

  1. 定义:命名空间namespace,是指人为的将内存进行分隔,让不同内存区域的同名结构共存。从而解决在大型项目中可能出现的重名结构问题
  2. 基本语法:namespace 空间名字;
<?php
//定义空间
namespace my_space;			//定义一个叫做my_space的空间
  1. 命名空间的命名规则
  • 由字母、下划线和数字构成
  • 可以以字母和下划线开头
  • 较少出现多单词空间名,一般使用下划线法
  1. 命名空间的作用:能够创建同名结构,包含函数、常量和类
  2. 命名空间注意事项:命名空间的声明(第一次)必须在所有代码之前

2.命名空间子空间

  1. 定义:子空间,即在已有空间之上,再在内部进行空间划分,让每个小空间独立起来
  2. 命名空间子空间是直接通过namespace+路径符号 \ 实现
namespace space;			//创建一个一级空间
function display(){}

//创建子空间
namespace space\space1;		//在space空间下创建一个叫做space1的子空间
function display(){}
  1. 子空间的创建不一定非要在前面创建了上级空间,即可以直接在某个脚本中创建子空间

3.命名空间访问

  1. 在PHP命名空间中,提供了三种空间元素的访问方式:非限定名称、限定名称和完全限定名称
  2. 非限定名称:即直接访问空间元素的名字,此类访问方式访问的是当前代码所属空间内的元素
namespace space1;
function display(){
	echo 'space1';
}
namespace space2;
function display(){
	echo 'space2';
}
//非限定名称访问
display();			//输出space2,因为当前display函数调用所属空间为space2
  1. 限定名称访问,即在访问元素的前面使用相应的空间名字,非限定名称的访问是基于子空间来实现的
//定义子空间
namespace space\space1;
function display(){
	echo 'space\space1<br/>';
}
//定义子空间
namespace space\space2;
function display(){
	echo 'space\space2<br/>';
}
//所属父空间
namespace space;
function display(){
	echo 'space<br/>';
}
//非限定名称访问
display();				//space:当前向上所属空间
space1\display();		//space\space1:实际为当前空间space+space1\display()
  1. 完全限定名称访问,即从根目录(全局空间)开始访问,使用 \ 作为全局空间开始符号
//完全限定名称访问
\space\display();			//space空间下的display
\space\space1\display();	//space下space1空间的display

4.全局空间

  1. 没有指定空间的元素所属的空间属于全局空间
//不定义空间
function display(){
	echo __NAMESPACE__'<br/>';
}
  1. 所有的空间本质都是在全局空间下的划分
  2. 全局空间元素的访问:使用完全限定名称访问
//不定义空间
function display(){
	echo __NAMESPACE__,'<br/>';
}
display();				//非限定名称访问:本身当前就是全局空间内,所以可以访问
\display();				//完全限定名称访问:全局符号“ \ ”+全局空间元素

5.命名空间引入

  1. 空间引入方式:use关键字
namespace space;
class Man{}

namespace space1;
//引入空间元素
use space\Man;

new Man();
  1. use进行空间包含的时候,默认是从全局空间开始构建空间路径的(不是自己空间的相对路径),所以上述代码等价于以下代码
namespace space;
class Man{}

namespace space1;
//引入空间元素
use \space\Man;
  1. 空间引入的元素默认是类,如果要引入其他元素,就必须使用相应关键字:function和const
namespace space;
function display(){}
class Man{}
const PI = 3.14;

namespace space1;
//引入空间元素
use function space\display;		//引入函数
use space\Man;					//引入类
use const space\PI;				//引入常量

display();
new Man();
echo PI;
  1. 如果被引入的元素在当前空间已经存在,则会出现重名,解决方案是使用别名as alias
namespace space;
function display(){}
class Man{}
const PI = 3.14;

namespace space1;
class Man{}
//引入空间元素
//use space\Man			//错误:当前空间已经存在Man
use space\Man as M;
use function space\display as dis;
use const space\PI as D;
  1. 一旦引入的时候使用了别名,那么在使用的时候就直接通过别名使用(且只能使用别名)
  2. 如果一个空间中有多个元素要引入,那么可以进行一次引入多个,使用逗号,分隔即可,以上方式都是在引入同一种元素,如果要引入多个不同元素,可以如下使用
//引入space\space1下的三个类,两个函数和一个常量
use space\space1\{
	Man as M,
	Woman,
	Ladyboy,
	function display,
	function show,
	const PI as P
};					//注意分号
  1. 如果说确定一个空间里的所有元素都需要引入进来,也可以直接引入空间
namespace space;
class Man{}

namespace space1;
//引入空间
use space;
  1. 如果是直接进行空间引入,那么被引入的空间属于当前空间的一个元素,要访问引入空间的其他元素,得从引入的空间开始:即引入的空间最后一级空间名字+元素(引入空间当做当前空间的子空间)
namespace space\space1\space2;
class Man{}

namespace space3;
class Man{}
//引入空间
use space\space1\space2;

new Man();					//访问的是space3\Man
new space2\Man();			//使用引入空间的最后一级空间访问

五、PDO

  • PDO类:统一的数据库的初始化操作,包括连接认证和执行SQL指令
  • PDOStatement类:数据解析操作,主要针对数据结果操作(有数据结果返回)
  • PDOException类:异常处理操作,针对所有PDO操作可能出现的错误采用的异常处理模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值