搜索
首页
笔记
案例
关于
课程列表
PHP
php基础
基本语法
流程控制
函数
数组
对象
Trait
字符串处理
正则表达式
SPL
输出缓存
php与xml
生成器
php常用扩展
错误与异常处理
日期与时间
文件系统
图像处理
数据库开发
Mysqli扩展
Db类
高级功能
会话控制
CURL
PHP安全
PHP版本
从5.6到7.0
从7.0到7.1
课程导航
计算机基础知识
C
Linux
linux常用软件
计算机网络
程序员修养
设计模式
工具
Git
composer
vim
IntelliJ IDEA
wireshark
laravel
Spring
SpringMVC
Maven
数据库
MySQL
Redis
MongoDB
JDBC
Mybatis
MyBatis-Plus
服务端编程
PHP
Java
shell script
JavaWeb
HTML / CSS
HTML
CSS
HTML5
CSS3
BOOTSTRAP
JavaScript
JavaScript
JQuery
layui
数组
Trait
对象
## 抽象一个类 [一些修饰的关键字] class 类名 { 类中成员; } ``` class People { public $name = ''; public $age = 0; public $sex = ''; public function sayName() { echo "my name is $this->name"; } public function ability ($str) { echo $str; } } ``` ## 通过类实例化对象 $变量名 = new 类名称([参数列表]); $变量名 = new 类名称; ``` $p1 = new People(); $p2 = new People; ``` ### 特殊的对象引用“$this” 对象一旦被创建,在对象中的每个成员方法里面都会存在一个特殊的对象引用“$this”。成员方法属于哪个对象,$this就代表哪个对象,专门用来完成对象内部成员之间的访问。 ### 构造方法与析构方法 ``` class People { public $name = ''; public $age = 0; public $sex = ''; public function __construct($name, $age, $sex = '男') { $this->name = $name; $this->age = $age; $this->sex = $sex; } public function sayName() { echo "my name is $this->name"; } public function ability ($str) { echo $str; } public function __destruct() { echo '对象被销毁时我被调用'; } } $p1 = new People('gwx', 29); ``` ## 封装性 ### 私有成员设置及访问 ``` class Person { private $name = ''; public function sayName () { echo $this->name; } } ``` ### \__set()、\__get() \__unset()、\__isset() ``` name = $name; $this->age = $age; $this->sex = $sex; } public function __get($propertyName) { if (isset($this->$propertyName)) { return $this->$propertyName; } } public function __set($propertyName, $val) { if ( array_key_exists( $propertyName, get_object_vars($this) ) ) { $this->$propertyName = $val; } else { echo '禁止设置其他属性值'; } } public function __isset($propertyName) { return isset($this->$propertyName) ? true : false; } public function __unset($propertyName) { unset($this->$propertyName); } } $p1 = new People('gwx', 29); echo $p1->name; // gwx $p1->name = '桂文贤'; echo $p1->name; // 桂文贤 $p1->wifi = '宋娜娜'; // 禁止设置其他属性值 function printProperty($obj, $propertyName) { if ( isset($obj->$propertyName) ) { echo $obj->$propertyName . '
'; } else { echo '该属性不存在
'; } } printProperty($p1, 'name'); // 桂文贤 unset($p1->name); printProperty($p1, 'name'); // 该属性不存在 ``` ## 继承性 ### 类继承的应用 ``` class People { private $name = ''; private $age = 0; private $sex = ''; public function __construct($name, $age, $sex = '男') { $this->name = $name; $this->age = $age; $this->sex = $sex; } public function sayName () { echo '我的名字是' . $this->name . '
'; } } class Student extends People { public function study () { echo '学生在学习
'; } } $stu1 = new Student('桂琳琅', 1, '女'); $stu1->sayName(); $stu1->study(); //我的名字是桂琳琅 //学生在学习 ``` ### 访问类型控制 | | private | protected | public | | ---- | ---- | ---- | ---- | | 同一个类中 | ok | ok | ok | | 子类中 | |ok | ok | | 外部成员 | | | ok | ### 子类重载父类的方法 子类中重载父类的方法就是在子类中覆盖父类中继承过来的方法。 ``` class People { private $name = ''; private $age = 0; private $sex = ''; public function __construct($name, $age, $sex = '男') { $this->name = $name; $this->age = $age; $this->sex = $sex; } } class Student extends People { public function __construct($name, $age, string $sex = '男', $school) { parent::__construct($name, $age, $sex); $this->school = $school; } } ``` ## 常见关键字及魔术方法 ### final关键字 final作用: 使用final标识的类不能被继承。 在类中使用final标识的成员方法,在子类中不能被覆盖。 ### static关键字 使用static关键字可以将类中成员标识为静态的,既可以用来标识成员属性,也可以标识成员方法。用static标识的成员是属于类的,所以与对象实例和其他的类无关。类的静态属性非常类似函数的全局变量。 **类名::静态成员属性名;** **类名::静态成员方法名;** 在类中声明的成员方法中,也可以使用关键字“self”来访问其他静态成员。因为静态成员是属于类的,而不属于任何对象,所以不能用$this来引用它,而在php中给我们提供的关键字self,就是在类中成员方法中用来代表本类的关键字。格式如下所示: self::静态成员属性名; self::静态成员方法名(); 注:在静态方法中只能访问静态成员。因为非静态成员必须通过对象的引用才能访问,通常是用$this完成的。 ### 单例模式 ``` /** * 单例模式 */ final class DB { static $db = null; private function __construct() { // 连接数据库操作 } static public function getInstance () { if ( is_null(self::$db) ) { self::$db = new self(); } return self::$db; } public function query ($sql) { echo $sql; } private function __clone() {} } $db = DB::getInstance(); $db->query("SELECT * FROM classes"); ``` ### const关键字 ``` showPi(); echo Person::PI; ``` ### instanceof关键字 ``` class Person { const PI = 3.14; public function showPi () { echo self::PI; } } $p1 = new Person; if ($p1 instanceof Person) { echo '$p1是Person类的实例'; } ``` ### 克隆对象 对象默认采用引用传值。 在php中根据现有对象克隆出一个完全一样的对象,克隆以后,原本和副本两个对象完全独立,互不干扰。 ``` class Person { public $name = 'gwx'; public function __construct ($name) { $this->name = $name; } } $p1 = new Person('gwx'); $p2 = $p1; $p1->name = 'snn'; echo $p1->name . '
'; // snn echo $p2->name . '
'; // snn $p3 = new Person('james'); $p4 = clone $p3; $p3->name = 'paul'; echo $p3->name . '
'; // paul echo $p4->name . '
'; // james ``` ### 魔术方法__clone() 略 ### __toString() ``` class Person { public $name = 'gwx'; public function __construct ($name) { $this->name = $name; } public function __toString() { return 'aaa'; } } echo (new Person('name')); ``` ### __call()方法的应用(连贯操作) 如果尝试调用对象中不存在或访问不了的方法则会自动调用__call()方法,它接受两个参数:第一个参数是方法名,第二个参数是以数组形式的参数列表。 ``` '', 'table' => '', 'where' => '', 'group' => '', 'having' => '', 'order' => '', 'limit' => '' ]; public function __call($methodName, $arguments) { $methodName = strtolower($methodName); if (array_key_exists($methodName, $this->sql)) { $this->sql[$methodName] = $arguments[0]; } else { echo '调用的方法' . $methodName . '不存在'; } return $this; } public function select () { echo "SELECT {$this->sql['field']} FROM {$this->sql['table']} WHERE {$this->sql['where']} GROUP BY {$this->sql['group']} HAVING {$this->sql['having']} ORDER BY {$this->sql['order']} LIMIT {$this->sql['limit']} "; } } $db = new DB(); $db->field('sex,count(sex)') ->table('users') ->where('sex in ("男", "女")') ->group("sex") ->having("avg(age) > 25") ->order("sex ASC") ->limit("0,2") ->select(); // SELECT sex,count(sex) FROM users WHERE sex in ("男", "女") GROUP BY sex HAVING avg(age) > 25 ORDER BY sex ASC LIMIT 0,2 ``` ### 自动加载类 当你尝试使用一个php没有组织到的类时,它会自动寻找一个名为__autoload()的全局函数 ``` spl_autoload_register("autoload"); function autoload($className) { include strtolower($className).".php"; } ``` ``` spl_autoload_register(function ($className) { if (is_file('./'.$className.'.php')) { require './'.$className.'.php'; } else { throw new Exception('not find the class'); } }); ``` ### 对象串行化 以下两种情况需要把对象串行化: 1 对象需要在网络中传输时 2 对象需要持久化时 seralize()函数串行化一个对象,返回字符串 unseralize()反串行化 ## 抽象类与接口 ### 抽象类 抽象方法就是没有方法体的方法,所谓没有方法体是指在方法声明时没有花括号及其中的内容,需要使用关键字abstract 如:abstract function fun1(); 只要类中有一个抽象方法,该类就为抽象类,抽象类也要用abstract修饰。 在抽象类中可以有不是抽象的成员方法和成员属性,但访问权限不能使用private关键字修饰为私有的。 ``` name = $name; $this->country = $country; } abstract function say(); abstract function eat(); public function run (){ echo '用两条腿走路.
'; } } class Chinese extends Person { public function say() { echo "{$this->name}是{$this->country}人, 讲汉语
"; } public function eat() { echo "{$this->name}使用筷子吃饭
"; } } class Americans extends Person { public function say() { echo "{$this->name}是{$this->country}人, 讲英语
"; } public function eat() { echo "{$this->name}使用刀叉吃饭
"; } } $chinese = new Chinese('周杰伦', '中国'); $american = new Americans('james', 'America'); $chinese->say(); $chinese->eat(); $american->say(); $american->eat(); ``` ### 接口 接口是为了解决每个类只能继承自一个父类。接口是一种特殊的抽象类,而抽象类又是一种特殊的类,所以接口也是一种特殊的类。如果抽象类中的方法都是抽象方法,那么我们就可以换另外一种声明方式——使用“接口”技术。接口中的所有方法都是抽象方法,另外不能在接口中声明变量,只能使用const关键字声明为常量的成员属性,而且接口中所有成员都必须有public访问权限。 ``` interface 接口名称{ // 常量成员 // 抽象方法 } ``` 实现接口形式为 ``` class 类名 implements 接口一,接口二,……,接口n { // 实现接口中所有抽象方法 } ``` ## 多态性的应用 多态最直接的定义就是让具有继承关系的不同类对象,可以对相同名称的成员函数进行调用,产生不同的反应效果。在php中,多态性指的就是方法的重写。 我们通过计算机usb设备来介绍一下面向对象的多态特性。目前usb设备种类有很多,如usb鼠标、usb键盘、usb存储等,这些计算机设备都是通过usb接口连接计算机以后,被计算机调用并启动运行的。也就是计算机正常运行的同时,没插入一种不同的usb设备,就为计算机扩展了一样功能,这正是我们所说的多态特征。 假设我们有一个主程序已经开发完成,需要在后期由其他开发人员为其扩展一些功能,但需要在不改动主程序的基础上就可以加载这些扩展的功能模块,其实也就是为程序开发一些插件。这就需要在主程序中,为扩展的插件程序写好接口规范,每个插件只有按照规范去实现自己的功能,才能被主程序应用到。 ``` '; } } // 鼠标设备 class Umouse implements USB { function run () { echo '运行鼠标设备
'; } } class Computer { function useUSB ($usb) { $usb->run(); } } $computer = new Computer(); $computer->useUSB(new Ukey()); $computer->useUSB(new Umouse()); ``` ## Trait特性 略 ## 命名空间 命名空间,它的一个最明确的目的就是解决重名问题。命名空间将代码划分出不同的区域,每个区域的常量、函数和类的名字互不影响。 注意:虽然const和define都是用来声明变量的,但是在命名空间里,define的作用是全局的,而const则作用于当前空间。 创建一个命名空间需要使用namespace关键字,这样: ``` ``` 要注意的是,当前脚本文件的第一个命名空间前面不能有任何代码 下面我创建了两个命名空间,顺便为这两个空间各自添加了一个Comment类元素: ``` ``` 在不同空间之间不可以直接调用其它元素,需要使用命名空间的语法: ``` ``` 而且,子空间还可以定义很多层次,比如说 Blog\Article\Archives\Date ### 公共空间 我有一个common_inc.php脚本文件,里面有一些好用的函数和类: ``` ``` 在一个命名空间里引入这个脚本,脚本里的元素不会归属到这个命名空间。如果这个脚本里没有定义其它命名空间,它的元素就始终处于公共空间中: ``` ``` 调用公共空间的方式是直接在元素名称前加 \ 就可以了,否则PHP解析器会认为我想调用当前空间下的元素。除了自定义的元素,还包括PHP自带的元素,都属于公共空间。 要提一下,其实公共空间的函数和常量不用加 \ 也可以正常调用(不明白PHP为什么要这样做),但是为了正确区分元素,还是建议调用函数的时候加上 \ ### 名称术语 在说别名和导入之前,需要知道关于空间三种名称的术语,以及PHP是怎样解析它们的。官方文档说得非常好,我就直接拿来套了。 1.非限定名称,或不包含前缀的类名称,例如 $comment = new Comment();。如果当前命名空间是Blog\Article,Comment将被解析为Blog\Article\Comment。如果使用Comment的代码不包含在任何命名空间中的代码(全局空间中),则Comment会被解析为Comment。 2.限定名称,或包含前缀的名称,例如 $comment = new Article\Comment();。如果当前的命名空间是Blog,则Comment会被解析为Blog\Article\Comment。如果使用Comment的代码不包含在任何命名空间中的代码(全局空间中),则Comment会被解析为Comment。 3.完全限定名称,或包含了全局前缀操作符的名称,例如 $comment = new \Article\Comment();。在这种情况下,Comment总是被解析为代码中的文字名(literal name)Article\Comment。 其实可以把这三种名称类比为文件名(例如 comment.php)、相对路径名(例如 ./article/comment.php)、绝对路径名(例如 /blog/article/comment.php),这样可能会更容易理解。 我用了几个示例来表示它们: ```
数组
Trait
文章目录