面向对象编程
类:在现实世界中,任何事物都有种类的概念:车
类是由特征和行为构成的。
特征:都是不动的,从出厂的时候就已经内置好了(属性)
行为:一种动的状态。(方法(函数))
行为依赖于这些特征,而特征只有通过这些行为才能施展。
对象调用属性、方法
<?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