目录
0x00 接口 interface
php是单继承的语言,即儿子只能有一个父,一个儿子不能有多个爸爸
而接口是特殊的抽象类,可以让php实现多继承(让一个儿子有多个爸爸)
- 方法必须都是抽象方法(省略abstract),且必须都是public
- 接口中不能定义变量属性,只能声明常量
- 子类必须实现接口的每一个方法
定义:
interface 接口名称{
}
<?php
interface A{
const NAME = 'xidian';
public function test1();
public function test2();
}
interface C{
public function test3();
}
class B implements A,C{
public function test1(){
echo 'test1';
}
public function test2(){
echo 'test2';
}
public function test3(){
echo 'test3';
}
}
$b = new B;
$b->test1();
?>
接口也可以通过extends 继承其他接口
0x01 trait
不能被实例化
用来实现多继承
其他类可以使用关键字 use 来继承trait类,
<?php
trait A{
public $a = 'a';
public function test1(){
echo 'test1';
}
}
trait B{
public $b = 'b';
public function test2(){
echo 'test2';
}
}
class C{
use A,B;
}
$c = new C;
$c->test1();
$c->test2();
?>
0x02 namespace 命名空间
用来解决命名冲突问题
命名空间的定义:
namespace + 空间名字
<?php
namespace Mobile;
class send{
}
namespace Mail;
class send{
}
?>
注意:
1.第一个namespace 前不要有代码。一般在脚本开头定义。
2.namespace 的作用域从声明开始 到遇到下一个namespace结束/到脚本结束。
3.一般一个文件定义一个命名空间。
命名空间的子空间:
用反斜线\隔开,子空间下可以还有子空间,类似于目录结构。
namespace Order\pay;
class send{
}
namespace Order\Address\test;
class send{
}
公共空间:
没有声明namespace的名字都属于公共空间。
命名空间的使用:
方法一:
直接实例化
new \命名空间名\类名
<?php
namespace xidian;
class send{
public function run(){
echo 'hello xidian';
}
}
$s = new \xidian\send();
//$s = new send(); 这样写也是正确的,解释器会默认在当前命名空间中找这个类
$s->run();
namespace chendian;
class send{
public function run(){
echo 'hello chendian';
}
}
$c = new \xidian\send();
$c->run();
?>
class send{
public function go(){
echo 'go';
}
}
$s = new \send();
$s->go();
在公共空间中,实例化空间中的类可以直接 new 类名,或者也可以在类名前加一个反斜杠,表示让解释器在公共空间下找这个类名。公共空间可以理解为根目录
直接new 类名,相当于告诉解释器在当前命名空间下找这个类。
注意:
xidian.php
class send{
function run(){
echo 'hello xidian';
}
}
没有namespace声明,脚本中的类默认在公共空间中,即便是其他文件require该文件,该文件中的类还是属于公共空间,比如如下情况:
<?php
namespace chendian;
require_once 'xidian.php';
$s = new send();//error;
$s = new \send();//right;
$s->run();
?>
千万不要认为在chendian命名空间中require了xidian.php,xidian.php中的类就进入了chendian命名空间。
这些类仍然属于原来的命名空间。
开头加\:相当于绝对路径
开头不加\:相当于相对路径。
方法二:使用use关键字
use关键字相当于一个重命名的作用
例如:use xidian\cs 相当于用 cs\ 替代了\xidian\cs
当然这种重命名我们可以自己通过as来指定
use xxx as xxx
实际开发场景通常是这样的:
比方说我们现在有两个脚本文件xidian.php和chendian.php,他们的内容如下:
xidian.php
<?php
namespace xidian\cs;
class Send{
public function run(){
echo 'hello xidian';
}
}
?>
chendian.php
<?php
namespace chendian\cs;
class Send{
public function run(){
echo 'welcome to chendian';
}
}
?>
在University.php中想使用这两个类:
<?php
namespace university;
use xidian\cs as XDCS;
use chendian\cs;
class University{
public function run(){
require_once 'xidian.php';
require_once 'chendian.php';
$xd = new XDCS\send();
$xd->run();
$cd = new cs\send();
$cd->run();
}
}
$u = new University;
$u->run();
?>
以上是use到子空间的版本,也可以直接use到类名
比如use chendian\cs\Send 相当于用Send替换了\chendian\cs\Send
为了能够让使用的人一眼看出那个是子空间名,那个是类名,phper应该严格遵守命名规范:
- 子空间名和空间名 全部用小写
- 类名首字母大写
- 空间名 一般以 脚本所在文件夹名 命名
<?php
namespace university;
use xidian\cs\Send as Xd_send;
use chendian\cs\Send;
class University{
public function run(){
require_once 'xidian.php';
require_once 'chendian.php';
$xd = new Xd_send();
$xd->run();
$cd = new Send();
$cd->run();
}
}
$u = new University;
$u->run();
?>
0x03 魔术常量补充
__FUNCTION__:返回当前函数的名称
__CLASS__:返回当前的类名(包括该类的作用区域和命名空间)
__TRAIT__:返回当前的trait名称(包括命名空间)
__METHOD__:专门用于返回类中的方法名(命名空间名/类名/方法名)
__NAMESPACE__:返回命名空间
0x04 与类和对象有关的系统函数
1.bool class_exists(‘命名空间\类名’)
判断类是否存在,有命名空间带上命名空间,没有直接写类名即可
2.get_class('对象名')
获取对象的类名
3.get_class_method('对象名')
获取对象的所有方法名
4.get_class_var('类名')
获取类所有的属性
5.is_object('变量名')
判断变量是不是对象