面向对象编程
类: 在现实世界中, 任何事物都有种类的概念: 车
类是由特征和行为构成的.
特征: 都是不动的, 从出厂的时候就已经内置好了(属性)
行为: 一种动的状态.(方法(函数))
行为依赖于这些特征, 而特征只有通过这些行为才能施展.
对象调用属性, 方法
- <?php
- header("Content-Type:text/html; charset=utf-8");
- class Persion{
- const NAME = "小王";
- public $name = "小明"; //public 访问控制符
- public $name1 = "小红";
- public function run($my_nume){
- echo $my_nume;
- }
- }
- // 对象调用属性 以及方法 使用 ->
- // 对象调用属性的时候, 直接加属性名, 不要加 $ 符
- // 对象调用方法的时候, 直接写方法名就可以了
- // 调用类常量, 可以用当前对象, 加:: 的形式来调用
- $p = new Persion(); // 返回的是一个对象
- echo $p->name;
- $p->run("小蓝");
- echo $p::NAME;
- echo Persion::NAME; // 也通过直接调用当前类 加:: 的形式来调用
类常量: const
const 用于类成员常量的定义, 一经定义, 不可修改.
const 和 define 的区别:
1,const 可以在类中使用, define 不能
2,const 不能在条件语句中定义常量
const 定义的常量是大小写敏感, 而 define 可以通第三个参数来指定大小写是否敏感.
构造函数:__construct()
我们在创建一个类的时候有时候需要初始化一些操作, 这个时候我们需要使用初始化函数, 在 PHP 中有两种初始化方法:
1, 构造函数:__construct() . 注意: 构造函数是自动运行的, 在你实例化的时候就自动执行了.
- class MyPc
- {
- function __construct(){
- // 初始化操作
- }
- }
- new MyPc();
构造函数怎么传递参数呢? 通过在类名实例化的小括号里传递我们的参数:
- class MyPc{
- function __construct($name)
- {
- echo '你好'.$name;
- }
- }
- new MyPc("小王");
2, 建立一个对象方法
注意: 此时测方法名没有大小写区分, 只要与类名一致, 均会被当成构造函数, 在实例化时自动调用.
- class MyPc
- {
- function MyPc(){ // 当方法名跟我们的类名一致的时候, PHP 就会自动的把它当成构造函数来使用
- echo "123";
- }
- }
- new MyPc();
注意:
__construct 的优先级比对象方法高, 当类中有__construct 时必须放在类的开头.
- class MyPc{
- function __construct($name)
- {
- // 如果用__construct 方法, 则必须放在类中的开头
- echo '你好'.$name;
- }
- function MyPc()
- {
- // 此时的 MyPc()方法就是一个普通的方法
- echo "asd";
- }
- }
- (new MyPc("小王"))->MyPc();
- // 此时要实例化类, 则必须传入一个参数, 因为构造函数定义的时候需要一个参数, 之后由于没有定义一个参数来赋值类, 所以用括号扩起来.
析构函数:__destruct() 了解就好
能够在对象释放时自动被调用的方法被称为析构函数.
理解:
我们可以理解为垃圾回收机制, 当对象内部的操作执行完毕的时候,__destruct()被调用, 然后对象所使用的内存被释放出来.
规则:
先进先出
$this 关键字
$this 关键字: 是用来访问当前对象中的对象属性和对象方法的系统变量
理解:
我们可以理解为 $this 是在对象中特殊的一种使用构造函数和变量的方法.
注意:$this 仅能在当前对象中使用
- class Pc{
- public $name = "小马";
- function computer($name='小明',$c='')
- {
- $this->name = $name;
- // 可以动态的修改类的属性, 第一个 name 不加 $, 表示类的属性
- // 第二个是传入的参数
- echo $this->name;
- // 在类的里面, 调用其他属性和方法用 $this
- // 用 $this 加 ->调用属性和方法
- // 注意, 这里的 name 不用加 $ 符号
- }
- }
- // 类不被实例化, 是不会展示类里面所有功能的.
- $p = new Pc();
- $p->computer();
- // 这里没有传递参数, 则定义时必须给形参一个默认值
类成员的访问控制
访问控制符:
就是把一些相关的属性和行为隐藏起来, 从而得到保护和安全.
public:
表示全局, 在类的内部和外部子类都可以访问.
protected:
表示受保护的, 只有本类或子类或父类中使用.
private:
表示私有, 只有本类内部可以使用.
类, 是要被实例化返回一个对象的, 在对象访问的时候, 访问属性和方法只能用 public 来访问, 不能用其他两个. 即无法用 ->来访问 proteced 和 private 的属性和方法.
- class Pc{
- public $name = "小马";
- protected $age = '18';
- // 受保护的, 在本类中可以使用 $this->来调用, 但是在外部实例化的时候是不能调用的
- // 可继承
- private $city = '上海';
- public function test()
- {
- return $this->name."在".$this->city;
- // 方法最好有返回值热, retur 和 echo 都可以, 建议用 return
- //$this 调用本类的属性和方法
- }
- }
- // 类的外面想要调用属性, 要先实例化该类
- $p = new Pc();
- /*echo $p->name; // 正常调用
- echo $p->age; //Fatal error: Cannot access protected property
- echo $p->city; //Fatal error: Cannot access private property */
- echo $p->test();
类的自动加载:__autoload()
使用 "__" 开头的基本上都是系统的构造函数
作用:
快速取得对象名称并自动载入进当前页面, 当实例化类的时候, 会自动获取类的名称, 并在当前文件中及当前文件目录下自动加载
- <?php
- header("Content-Type:text/html; charset=utf-8");
- // 类的自动加载
- // 自动加载函数, 可以放到类的外面, 执行该文件的时候会自动执行
- function __autoload($class_name){
- include($class_name.".php");
- // 如果本文件中没有这个类, 那么会在本文件目录下自动加载以该类名称命名的文件
- }
- $p = new Pc();
- echo $p->name;
- #$p = new MyPc();
- // 如果本文件中没有这个类, 那么会在本文件目录下自动加载以该类名称命名的文件
- class Pc
- {
- public $name = "adf";
- }
类的继承: extends
PHP 类的继承, 我们可以理解成共享被继承类的内容. PHP 中使用 extends 单一继承的方法, 请切记:(非 C++ 多继承)被继承的类我们叫做父类(基类), 继承者称为子类(派生类).
PHP 继承的规则:
可多重继承, 但是不能同时继承多个. 可避免属性和方法的重名.
关键字: patent
子类 (派生类) 继承父类(基类). 子类想访问跟子类方法同名的父类的时候, 并且子类的方法也不想被方法重载的时候. 这时候使用 parent.
在类中定义方法的时候, 如果不写访问控制符, 那么默认是 public 属性.
- // 基类, 父类
- class A
- {
- function test(){
- echo "父类";
- }
- }
- class B extends A
- {
- function test()
- {
- #echo "子类";
- parent::test();
- }
- }
- $p = new B();
- $p->test();
- // 如果子类中的方法名与父类中的方法名重复, 那么子类的方法会覆盖父类中的方法.(方法的重载)
当子类和父类的方法重名的时候, 由于直接调用方法会默认调用子类的方法, 因此我们使用 parent 关键字来调用父类中的方法.(在子类中使用)
方法重载
基类方法重载:
因为属于向下继承的原理, 基类不能使用派生类里的内容, 这时基类的一些方法不能完成我们的一些派生类的功能.
我们就可以进行方法重载, 避免新建方法带来的混乱.
理解: 方法重载我们也可以理解为方法覆盖, 在派生类中使用与基类方法重名的方法名来执行重载.
例子与上面 parent 一样.
范围操作符: "::"
注意: 这个符号用于类中 (而不是对象中) 访问成员, 对象访问成员使用的是 "->" 符号.
使用场景:
1, 在使用类的时候, 父类和子类具有相同的属性和方法时, 利用它可以避免混淆.
2, 在类外的时候, 没有创建对象的情况下使用该操作符访问类的成员.
记住:
在多数情况下, 我们使用范围解析操作符是为了访问被重写的方法. 我们也可以用其访问静态和常数成员.
- // 基类, 父类
- class A
- {
- const Name='小明';
- public static function test()
- {
- echo "静态方法";
- }
- public function aa()
- {
- }
- }
- // 调取类常量
- echo A::Name;
- A::test();
- // 加:: 来调用一些静态的属性和方法
- A::aa();
- // 不可以调用普通的方法名, Non-static method A::aa() should not be called statically
注意: 不允许直接调用普通方法.
静态成员的作用
静态: 只要在成员前加上关键字 static, 该变量就成为静态成员了.
1, 静态变量属于类, 而不属于类的某个实例. 这个变量对所有实例都有效.
2, 声明为 static 的类, 函数和变量将不能引用实例方法或变量.
3, 静态变量和方法必须通过类名进行引用而不能通过实例对象引用.
- // 基类, 父类
- class A
- {
- public static function test()
- {
- echo "这是一个普通方法";
- }
- }
- // 调用静态的, 无论是方法还是属性, 都可以用::
- A::test();
匿名类 (了解即可, php7 新加入的)
PHP7 支持通过 new class 来实例化一个匿名类, 这可以用来替代一些 "用后即焚" 的完整类定义.
trait 技术
Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制. Trait 为了减少单继承语言的限制, 使开发人员能够自由地在不同层次结构内独立的类中复用方法集.
作用: 我们在没有增加代码复杂的情况下, 实现了代码的复用.
trait 类可以理解为复制粘贴类, 由 trait 关键字定义, 用 use 关键字调用(粘贴).
- // 基类, 父类
- trait Pc
- {
- public function usb()
- {
- echo "usb";
- }
- function key()
- {
- echo "key";
- }
- }
- //trati 类, 复制粘贴类
- class A
- {
- use Pc;
- }
- $a = new A();
- $a->key();
问题: trait 类和继承类有什么区别 ???
抽象类: abstract(类似纯虚函数, 纯虚函数的定义是在虚函数定义的基础上, 再让函数等于 0 即可)
抽象就是无法确切的说明, 但又有一定的概念或者名称, 在 PHP 中声明一个抽象类或者方法我们需要使用 abstract 关键字.
定义:
一个类中至少有一个方法是抽象的, 我们称之为抽象类. 所以如果定义抽象类首先定义抽象方法.
总结:
1, 类中至少有一个抽象方法, 可以有其他普通方法.
2, 抽象方法不允许有{ }, 即不能有方法体.
3, 抽象方法前面必须加 abstract.
几个特点:
1, 不能被实例化, 只能被继承.
2, 继承的派生类当中要把所有的抽象方法重载才能实例化.
- abstract class A
- {
- abstract function usb();
- function test(){
- }
- }
- #new A();
- // 抽象类不能被实例化
- //Cannot instantiate abstract class A
- class B extends A{
- function usb(){
- echo "子类重载";
- }
- // 如果没有重载抽象类中的所有抽象方法, 会出现以下报错
- //Class B contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (A::useb)
- }
- $b = new b();
- $b->usb();
派生类里面必须实现抽象类里面的所有方法, 少了一个都不行.
接口: interface(类似 C++ 的抽象类, 但是 C++ 抽象类的定义是: 包含由纯虚函数的类被称为抽象类)
接口: 一种成员属性全部为抽象的特殊抽象类, 在程序中同为规范的作用.
接口的引用:
接口引用区别之前我们学的继承关键字 extends, 继承只能是单一性, 而接口可以使用关键字: implement 引用多个引用并用逗号 "," 分开.
- interface Pc
- {
- // 接口类的所有方法都是抽象方法
- // 所有抽象方法都必须是 public 属性, 默认是 publi.
- function key();
- function usb($name);
- }
- interface person{
- public function age();
- public function name($p_name);
- }
- // 接口类只允许被实现和引用
- // 接口允许多引用, 然后用 "," 分开就行
- class B implements Pc,person
- {
- // 如果要实现接口类, 要把接口类里面的所有抽象方法都给实现
- // 少一个都不行
- function key(){
- }
- function usb($name){
- echo "这是一个参数".$name;
- }
- function age(){
- echo "18";
- }
- function name($p_name){
- echo "名字是:".$p_name;
- }
- }
- $b = new B();
- #b->usb("鼠标");
- $b->age();
- $b->name("小红");
关键字: self:
self 用来访问当前类的内容的关键字, 类似于 $this 关键字, 但 $this 是需要类实例化以后才可以使用, self 可以直接访问当前类中的内部成员.
注意:
因为没有实例化类访问内部属性或者方法是没有意义的,
所以 self 一般用来访问类中的: 静态成员, 常量, 或者其他定义内容.
关键字: final
final 是用来定义类和方法的一个重要关键字, 当定义类的时候该类将不能被继承, 当用来定义方法的时候该方法将不能被重载.
- // 使用 final 关键字, A 类将不被任何类继承
- #final class A
- class A
- {
- public $name = "小明";
- // 如果不想父类的方法被重写, 使用 final 关键字
- final public function test(){
- echo "父类";
- }
- }
- // 此时 B 类继承 A 类将会报错: Class B may not inherit from final class (A)
- class B extends A
- {
- // 此时父类方法使用 final 关键字, 子类就不能再进行重载了, 会报错: Cannot override final method A::test()
- public function test()
- {
- echo $this->name;
- }
- }
- $a = new B();
- $a->test();
对象复制与克隆
产生背景:
有时候我们需要在一个项目里面使用两个或多个一样的对象, 如果使用 new 关键字重新创建对象, 再赋值上相同的属性, 这样做比较繁琐而且也容易出错, PHP 提供了对象克隆功能, 可以根据一个对象完全克隆出一个一模一样的对象, 而且克隆以后, 两个对象互不干扰.
关键字: clone
$ 克隆对象名称 = clone $ 原对象名称;
克隆一个跟 $ 原对象名称一模一样的一个对象.
__clone()
如果想在克隆后改变原对象的内容, 需要在类中添加一个特殊的__clone()方法来重写原本的属性和方法.__clone()方法只会在对象呗克隆的时候自动调用.
MySQLoi 基本操作 1
1, 面向过程:
我们用 mysqli_connect()函数建立一个连接. 然后选择数据库, 然后发送 SQL 指令, 最后释放资源.
2, 面向对象:
new 新建一个 mysqli 对象, 传入数据库连接的相关参数就可以获得一个 mysqli 对象. 可以通过 $mysqli->connect_errno 判断连接是否有误.
MySQLoi 基本操作 2
查询:
面向对象执行操作也有 4 中. 分别为查询, 新增, 更新, 删除.
- // 查询:
- $result = $link->query('select * from user');
- // 获得结果集中行的数目:
- $num_rows = $result->num_rows.'<br/>';
- <?php
- header("Content-Type:text/html; charset=utf-8");
- // 连接数据库
- $link = new mysqli('localhost','root','123qwe','test');
- // 设置字符集
- $link->set_charset('utf8');
- $sql = 'select * from user';
- // 返回一个结果集
- $link_result = $link->query($sql);
- // 取出结果集
- $resulut = $link_result->fetch_assoc();
- #$resulut = $link_result->fetch_row();
- #$resulut = $link_result->fetch_array();
- var_dump($resulut);
- // 释放结果集
- $link_result->close();
- // 关闭资源
- $link->close();
- ---------------------------------------------------------------------------------------------------------
哪几种形式:
fetch_assoc()
查询到的一条数据以关联数组的形式返回
- ---------------------------------------------------------------------------------------------------------
- fetch_row()
查询到的一条数据以索引数组的形式返回
- --------------------------------------------------------------------------------------------------------
- fetch_array()
查询到的一条数据以索引数组和关联数组的混合形式返回
---------------------------------------------------------------------------------------------------------
魔术方法:__get
__get(string $name)
在读取不可访问的属性的值时该函数会被调用.$name 是属性名.
- class Demo
- {
- private $age= 18;
- public $name;
- // 当你访问不存在的或者权限不够的时候
- function __get($name){
- if($this->name == 'admin'){
- return $this->$name;
- }else{
- return "数据出错";
- }
- }
- }
- $a = new Demo();
- $a->name='admin';
- echo $a->age;
- // 此时__get()的参数 $name 为 age
魔术方法:__set
__set(string $name,mixed $val)
设置不可访问的值时会调用该方法
- class Demo
- {
- private $age;
- public $name;
- // 当你设置不存在的或者权限不够的属性时, 自动调用该方法
- // 起到一层过滤作用, 一种安全机制
- function __set($name,$val){
- if($this->name == 'admin'){
- echo $this->$name=$val;
- }else{
- echo "权限不够";
- }
- }
- }
- $a = new Demo();
- $a->name = 'admin';
- $a->age=18;
- // 此时__set()的参数 $name 为 age,$val 为 18
来源: https://www.cnblogs.com/fox-yu/p/8684881.html