构造方法的定义

构造方法又称为构造函数、是对象被创建时自动调用的方法、用来完成类初始化的工作。

特性

  • 构造方法和其他函数一样、可以传递参数、可以设定参数默认值。
  • 构造方法可以调用属性、也可以调用方法。
  • 构造方法可以被其他方法显式调用。

构造方法的声明

在PHP5中规定构造方法使用 __construct()函数表示构造方法,

在PHP4中使用与类名同名的方法为构造方法。在PHP5中依然支持了这种方式。PHP7.09报错但也输出了结果

<?php

class Test
{
    public $name = "李四";
    public $age = 23;

    public function __construct()
    {
        echo "我是构造方法";
    }
}

$p = new Test();
//既然是构造方法对象初始化自动调用的,那么下个例子
echo "<br/>;";

class Test2
{
    public $name;
    public $age;

    public function __construct($name, $age = null)
    {
        echo $this->name = $name, "的年龄是" . $this->age = $age;
    }

    public function setNameAge($name)
    {
        //通过方法内部调用构造函数
        $this->__construct($name);
    }
}

$name = "李四";
$age = "24";
$p2 = new Test2($name, $age); //直接输出 李四的年龄是24
echo "<br/>";
//直接调用构造函数
$p2->__construct("张三", 12); //echo   的年龄 xxx
echo "<br/>";
$p2->setNameAge("赵四");

析构函数和垃圾回收机制

析构函数:当某个对象的所有引用都被删除(成为垃圾)或者当对象被显式销毁时执行的函数,也就是对象在内存中被销毁前调用析构函数。

特性

析构函数是PHP新增的、析构函数是由系统自动调用的,虽然析构函数也可以被现实调用,但强烈建议不要使用。声明析构函数名称必须是__destruct(),并且不能带有参数。

PHP的垃圾回收机制

在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾。PHP会将其在内存中销毁。这是PHP的GC(Garage Collector)垃圾处理机制,目的是防止内存溢出。

PHP中变量在内存中是存在于一个ZVAL的变量容器中。结构如下

变量类型 变量值 is_ref refcount

is_ref是个bool值,用来区分变量是否属于引用集合。表示变量是否有一个以上的别名。

refcount 引用计数器,表示指向这zval变量容器的变量个数。当refcount值为1时,is_ref的值false。因为refcount为1,此变量不可能有多个别名,也就不存在引用了。为refcount为0时,zval以成为垃圾可回收。

<?php
class Test{
    public function __construct()
    {
        echo "有新对象创建了<br/>";
    }
    public function __destruct()
    {
        echo "有对象销毁了<br/>";
    }
}
//当运行脚本结束之后调用析构函数
$p=new Test();
 echo "<hr/>";  运行结果是横线下方: 有对象销毁了

显示的销毁对象、调用析构

<?php
class Test
{
    public function __construct()
    {
        echo "有新对象创建了<br/>";
    }
    public function __destruct()
    {
        echo "有对象销毁了<br/>";
    }
}
//当运行脚本结束之后调用析构函数
$p = new Test();
//此函数是PHP调试函数 必须需要装扩展xdebug、用来查看引用的
echo xdebug_debug_zval('p');
unset($p);
//显示的销毁对象、自动调用析构
$p = 2;
//$p重新赋值、等对象没有了引用、变成垃圾自动销毁
echo xdebug_debug_zval('p');
echo "<hr/>";
//我是横线 在最下方

当refcount值为0的时候,会自动调用__destruct.会执行PHP的垃圾回收机制。

<?php
class Test{
    public function __construct()
    {
        echo "有新对象创建了<br/>";
    }
    public function __destruct()
    {
        echo "有对象销毁了<br/>";
    }
}
//当运行脚本结束之后调用析构函数
$p=new Test();
echo xdebug_debug_zval('p');
$p1=$p; //$p1指向 test类
echo xdebug_debug_zval('p');
unset($p); //会不会调用__destruct()? 答案是不会。虽然删除了$p但是 但是$p1还是在引用test
echo xdebug_debug_zval('p1');
echo "<hr/>";  // 有对象销毁了。在横线的上面。 除非在unset($p1)会在横线上面re

refcount通过赋值就能增加 is_ref通过引用赋值增加

<?php
class Test
{
    public function __construct()
    {
        echo "有新对象创建了<br/>";
    }
    public function __destruct()
    {
        echo "有对象销毁了<br/>";
    }
}
//当运行脚本结束之后调用析构函数
//$p=$p1=$p2=new Test();
//echo xdebug_debug_zval('p');
//增加了refcount的值 、对象实际存放一个
//通过引用赋值  增加is_ref  引用地址赋值
$p[] = new Test();
$p[] =&$p;
echo xdebug_debug_zval('p');
unset($p);  //删除 $p对象 但并没销毁、$p内部还有一个指向
echo "<br/>";
Last modification:January 6, 2020
如果觉得我的文章对你有用,请随意赞赏