PHP魔术方法和oop
AI-摘要
切换
Tianli GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
本文最后更新于 2024-07-19,文章内容可能已经过时。
OOP入门
OOP
一、概述
oop(object orientied programming ) 面向属性编程。
1、类
具有相同属性和行为的事物
属性:用于表述个体特征的标识
行为:事物所表现出的动作。在类中也叫方法。
2、对象
类的实例化个体。
二、类定义
class 类名{
访问修饰符 ; //属性
访问修饰符 function 方法名(形参列表){ //方法
方法体;
}
}
访问修饰符:
属性:
public : 该成员能被外部代码访问和操作
proteted :只允许该类的子类进行访问
private :只允许同一个类内部进行访问
方法:
public : 该成员能被外部代码访问和操作
proteted: 只允许该类的子类进行访问
private :只允许同一个类内部进行访问
class Human{
public $name="zhang";
private $age=1;
public function talk(){
return "我是".$this->name."--我今年".$this->age."岁了";
}
private function run(){
echo "跑步";
}
}
$h = new Human;//使用new关键字创建一个Human类的对象
$re = $h->talk();//调用对象的talk方法
echo $re;//打印talk方法返回的结果
$h->run();//这一行会报错,因为
run方法是用private修饰的
三、继承
一个类可以复用另外一个类的属性、方法
至少涉及两个类,父类和子类,使用关键字extends表示继承关系
class Dad{
public $height=1.8;
public $eyecolor="blue";
private $weight=200;
public function swim(){
return "我会游泳";
}
protected function sing(){
return "我会唱歌";
}
private function speakEnglish(){
return "我会讲英文";
}
}
class Son extends Dad{
//定义一个静态方法
public static function run(){
echo '静态方法run';
}
}
$s = new Son;
echo $s->height;
echo $s->eyecolor;
// echo $son->weight;//这行报错,因为weight是用private修饰的
echo $s->swim();
Son::run();//调用静态方法,只用类名就可以,不需要对象
// echo $son->sing();//这行报错,因为sing是用protected修饰的,只能在子类Son中使用,不能在外部用
// echo $son->speakEnglish();//这行报错,因为speakEnglish是用private修饰的
四、魔术方法
方法 | 描述 |
---|---|
__construct( ) | 新对象被创建时候调用 |
__destruct() | 对象被销毁时候调用 |
__call() | 在对象中调用一个不可访问方法时,__call()会被调用。 |
__callStatic() | 在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用。 |
__get() | 读取不可访问(protected 或 private)或不存在的属性的值时会被调用 |
__set() | 在给不可访问(protected 或 private)或不存在的属性赋值时会被调用 |
__isset() | 当对不可访问(protected 或 private)或不存在的属性调用 isset()或 empty() 时,__isset() 会被调用。 |
__unset() | 当对不可访问(protected 或 private)或不存在的属性调用 unset()时,__unset() 会被调用。 |
__sleep() | 执行序列化操作时候先执行这个方法 |
__wakeup() | 执行反序列化操作时候先执行这个方法 |
__toString() | 当一个类被当成字符串使用的时候会调用 |
__invoke() | 当尝试以调用函数的方式调用一个对象时这个方法会调用 |
__clone() | 当复制完成时,如果定义了__clone() 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用,可用于修改属性的值(如果有必要的话)。 |
class Human{
public $name="zhang";
private $age=1;
public function talk(){
return "我是".$this->name."--我今年".$this->age."岁了";
}
//创建对象时候调用
public function __construct(){
echo "__contruct<br>";
}
//对象销毁时候调用
public function __destruct(){
echo "<br>__destruct";
}
//调用不存在的方法时候,会调用这个
public function __call($name,$args){
echo "你调用了不存在的方法:".$name."<br>";
}
//调用不存在的静态方法时候,会调用这个
public static function __callstatic ($name,$args){
echo "你调用了不存在的静态方法:".$name."<br>";
}
//读取不存在或者无法访问到的属性时候,会调用这个方法
public function __get($name){
echo "读取不存在或者无法访问到的属性:".$name."<br>";
}
//设置不存在或者无法访问到的属性时候,会调用这个方法
public function __set($name,$value){
echo "设置不存在或者无法访问到的属性:".$name."<br>";
}
//当对不可访问(protected 或 private)或不存在的属性调用 isset()或 empty() 时,__isset() 会被调用
public function __isset($name){
echo "当对不可访问(protected 或 private)或不存在的属性调用 isset()或 empty() 时,__isset() 会被调用:".$name."<br>";
}
//当对不可访问(protected 或 private)或不存在的属性调用 unset()时,__unset() 会被调用。
public function __unset($name){
echo "当对不可访问(protected 或 private)或不存在的属性调用 unset()时,__unset() 会被调用:".$name."<br>";
}
//当一个类被当成字符串使用的时候会调用
public function __toString()
{
return "对象要转成字符串__toString方法调用"."<br>";
}
//当一个类被当成字符串使用的时候会调用
public function __invoke($value){
echo "当尝试以调用函数的方式调用一个对象时这个__invoke方法会调用"."<br>";
}
//当复制完成时,如果定义了\__clone() 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用
public function __clone(){
$this->name="woniu";
echo "新对象克隆完成:"."<br>";
}
}
$hu = new Human;//对象初始化
$hu->abc();//调用不存在的方法
Human::staticMethod();//调用不存在的静态方法
echo $hu->xyz;//读取不存在或者无法访问到的属性
$hu->xxx="abc";////设置不存在或者无法访问到的属性
isset($hu->xyz);//对不可访问(protected 或 private)或不存在的属性调用 isset()
unset($hu->xyz);//当对不可访问(protected 或 private)或不存在的属性调用 unset()时,__unset() 会被调用。
echo $hu; //当一个类被当成字符串使用的时候会调用
$hu(1);//当尝试以调用函数的方式调用一个对象时这个方法会调用
$newhu = clone $hu;//克隆新对象
echo $newhu->name;//打印新对象的name属性
五、序列化和反序列化
1、序列化
在页面使用面向对象方式时,传递数据中如果需要使用对象。则需要将对象转化为可以还原的字符串。通常使用序列化对象的方式,将对象转化为序列化字符串。
serialize(对象) ==> 生成了序列化字符串
//定义Human类,并且序列化
class Human{
public $name="zhang";
private $age=1;
protected $score=100;
//创建对象时候调用
public function __construct(){
echo "__contruct<br>";
}
//对象销毁时候调用
public function __destruct(){
echo "<br>__destruct";
}
//对象序列化时候调用
public function __sleep(){
return array('name', 'age', 'score');
}
//对象反序列化时候调用
public function __wakeup() {
echo "<br>__wakeup";
}
}
$hu = new Human;
echo serialize($hu);//这个是不使用编码输出的序列化结果
echo "<hr>";
echo urlencode(serialize($hu));//这个是使用编码输出的序列化结果
以上要注意序列化时候自动 调用了魔术方法__sleep()
注意:如果遇到属性有proteted或者private,需要将字符串转码,防止出现无法复制的字符
urlencode(serialize(对象)) ==> url编码的序列化字符串:
结果:
O%3A5%3A%22Human%22%3A3%3A%7Bs%3A4%3A%22name%22%3Bs%3A5%3A%22zhang%22%3Bs%3A10%3A%22%00Human%00age%22%3Bi%3A1%3Bs%3A8%3A%22%00%2A%00score%22%3Bi%3A100%3B%7D
2、反序列化
在php页面上,通过unserialize() 接收传入的序列化字符串,还原对象。
$obj = unserialize($_GET['str']);
url; xxx.php?str=O%3A5%3A%22Human%22%3A3%3A%7Bs%3A4%3A%22name%22%3Bs%3A5%3A%22zhang%22%3Bs%3A10%3A%22%00Human%00age%22%3Bi%3A1%3Bs%3A8%3A%22%00%2A%00score%22%3Bi%3A100%3B%7D
class Human{
public $name="zhang";
private $age=1;
protected $score=100;
//创建对象时候调用
public function __construct(){
echo "__contruct<br>";
}
//对象销毁时候调用
public function __destruct(){
echo "<br>__destruct";
}
//对象序列化时候调用
public function __sleep(){
return array('name', 'age', 'score');
}
//对象反序列化时候调用
public function __wakeup() {
echo "<br>__wakeup";
}
}
$obj = unserialize($_GET['str']);//获取到浏览器传的序列化的结果,并执行反序列化
echo "<br>".$obj->name;//从反序列化的对象中获取变量name的值
序列化字符串中,只包含类名,属性名:属性值。 没有方法。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Windesky
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果