构造函数__construct()和析构函数__destruct()

大多数类都有一种称为构造函数的特殊方法。当创建一个对象时,它将自动调用构造函数,也就是使用new这个关键字来实例化对象的时候自动调用构造方法。构 造函数的声明与其它操作的声明一样,只是其名称必须是__construct( )。这是PHP5中的变化,以前的版本中,构造函数的名称必须与类名相同,这种在PHP5中仍然可以用,但现在以经很少有人用了,这样做的好处是可以使构 造函数独立于类名,当类名发生改变时不需要改相应的构造函数名称了。为了向下兼容,如果一个类中没有名为__construct( )的方法,PHP将搜索一个php4中的写法,与类名相同名的构造方法。
格式:function __construct ( [参数] ) { ... ... }
在一个类中只能声明一个构造方法,而是只有在每次创建对象的时候都会去调用一次构造方法,不能主动的调用这个方法,所以通常用它执行一些有用的初始化任务。比如对成属性在创建对象的时候赋初值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?
// 创建一个人类
class Person {
// 下面是人的成员属性
var $name; // 人的名子
var $sex; // 人的性别
var $age; // 人的年龄

// 定义一个构造方法参数为姓名$name、性别$sex和年龄$age
function __construct($name, $sex, $age) {
// 通过构造方法传进来的$name给成员属性$this->name赋初使值
$this->name = $name;

// 通过构造方法传进来的$sex给成员属性$this->sex赋初使值
$this->sex = $sex;

// 通过构造方法传进来的$age给成员属性$this->age赋初使值
$this->age = $age;
}

// 这个人的说话方法
function say() {
echo "我的名子叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age;
}
}

// 通过构造方法创建3个对象$p1、p2、$p3,分别传入三个不同的实参为姓名、性别和年龄
$p1 = new Person("张三","男", 20);
$p2 = new Person("李四","女", 30);
$p3 = new Person("王五","男", 40);

// 下面访问$p1对象中的说话方法
$p1->say();

// 下面访问$p2对象中的说话方法
$p2->say();

// 下面访问$p3对象中的说话方法
$p3->say();
?>
输出结果为:
我的名子叫:张三 性别:男 我的年龄是:20我的名子叫:李四 性别:女 我的年龄是:30我的名子叫:王五 性别:男 我的年龄是:40
如图:
析构函数:
与构造函数相对的就是析构函数。析构函数是PHP5新添加的内容,在PHP4中没有析构函数。 析构函数允许在销毁一个类之前执行的一些操作或完成一些功能,比如说关闭文件, 释放结果集等,析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行,也就是对象在内存中被销毁前调用析构函数。与构造函数的名称类似, 一个类的析构函数名称必须是__destruct( )。 析构函数不能带有任何参数
格式:function __destruct ( ) { ... ... }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?
// 创建一个人类
class Person {
// 下面是人的成员属性
var $name; // 人的名子
var $sex; // 人的性别
var $age; // 人的年龄

// 定义一个构造方法参数为姓名$name、性别$sex和年龄$age
function __construct($name, $sex, $age) {
// 通过构造方法传进来的$name给成员属性$this->name赋初使值
$this->name = $name;

// 通过构造方法传进来的$sex给成员属性$this->sex赋初使值
$this->sex = $sex;

// 通过构造方法传进来的$age给成员属性$this->age赋初使值
$this->age = $age;
}

// 这个人的说话方法
function say() {
echo "我的名子叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age;
}

// 这是一个析构函数,在对象销毁前调用
function __destruct() {
echo "再见" . $this->name;
}
}

// 通过构造方法创建3个对象$p1、p2、$p3,分别传入三个不同的实参为姓名、性别和年龄
$p1 = new Person("张三", "男", 20);
$p2 = new Person("李四", "女", 30);
$p3 = new Person("王五", "男", 40);

// 下面访问$p1对象中的说话方法
$p1->say();

// 下面访问$p2对象中的说话方法
$p2->say();

// 下面访问$p3对象中的说话方法
$p3->say();
?>
输出结果为:
我的名子叫:张三 性别:男 我的年龄是:20我的名子叫:李四 性别:女 我的年龄是:30我的名子叫:王五 性别:男 我的年龄是:40
再见王五
再见李四
再见张三
注意: 由于类实例是以 堆栈 的形式放在内存中,所以最后调用  析构函数  的时候,输出顺序是按  后进先出  的原则!
### PHP反序列化漏洞中的`__destruct`方法及其利用 在PHP中,反序列化过程可能引发的安全问题是由于某些特定的魔术方法(magic methods),如`__destruct()`、`__wakeup()`、`__toString()`等,在对象生命周期的不同阶段会被自动调用。如果这些方法被恶意设计或者与其他危险函数组合在一起,则可能导致严重的安全问题。 #### `__destruct`方法的作用 `__destruct`是一个特殊的魔术方法,它会在对象即将销毁时被调用[^1]。这意味着只要一个对象通过`unserialize()`成功还原出来并最终不再被引用,就会触发该方法。因此,攻击者可以构造一个特制的对象序列化字符串来控制程序行为。 #### 利用链的构建逻辑 为了实现有效的攻击,通常需要找到一系列类之间的交互关系形成所谓的“POP Chain” (Property Oriented Programming Chain),即属性导向编程链条。这种链条由多个相互关联的操作组成,每一个环节都依赖于上一步的结果完成下一步的任务直到达到预期效果比如远程命令执行(RCE)[^2]。 下面给出基于上述理论的一个简单例子: ```php <?php class sp4c1ous { private $test; public function __construct() { $this->test = new sdpc(); } // 当这个对象被销毁时会调用此方法 public function __destruct(){ $this->test->action(); // 调用了另一个类的方法 } } // 正常情况下应该定义的动作类 class sdpc{ public function action(){ echo "This is a normal output."; } } // 攻击向量使用的伪造动作类 class EvilAction{ protected $cmd; public function __construct($command){ $this->cmd=$command; } public function action(){ system($this->cmd); // 执行系统命令 } } if(isset($_GET['data'])){ @unserialize(urldecode($_GET['data'])); // 用户输入的数据在这里得到处理 }else{ die('No data provided'); } ?> ``` 在这个案例里,我们创建了一个名为`EvilAction`的新类别用于模拟潜在威胁场景下的非法活动——这里假设它可以接受来自外部未经验证的指令并通过内置函数`system()`去实际运行它们;而原本合法路径上的`sdpsec`已被替换成了我们的恶意版本。接着,当受害者访问含有特殊编码后的URL参数请求服务器端脚本时,便能激活整个流程从而达成目的[^3]。 需要注意的是,真实的环境中还需要考虑更多因素才能顺利完成此类攻击,例如目标环境的具体配置情况以及是否存在防护措施等等[^4]。 另外值得注意的一点在于,并非所有的`__destruct`都会带来风险,只有那些内部包含了敏感操作(如同上面提到过的`eval`, `system`)或者其他能够间接影响到应用正常运转的部分才值得特别关注[^5]。 ### 结论 综上所述,通过对PHP反序列化的深入研究可以看出,合理运用像`__destruct`这样的机制确实可以在一定条件下帮助黑客突破防线获取额外权限甚至完全掌控受害主机资源。然而与此同时也要强调加强防范意识的重要性,定期审查源码结构排除隐患所在之处同样不可忽视。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值