>php教程 >php手册 >php魔术方法构造函数和析构函数,php魔术构造函数

php魔术方法构造函数和析构函数,php魔术构造函数

WBOY
WBOY원래의
2016-06-13 08:45:371042검색

php魔术方法——构造函数和析构函数,php魔术构造函数

php有一类很神奇的方法,这些方法是保留方法,通常不会在外部被显式调用,他们使用双下划线(__)开头,他们被称为魔术方法(Magic Methods)。php官方也不建议定义其他双下划线开头的方法。

这次介绍最常见的魔术方法:构造函数和析构函数。

1. 构造函数(__construct)

void __construct ([ <span>mixed</span> <span>$args</span> [, $... ]] )

构造函数:拥有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象前做一些初始化服务。

注意:

  1. clone并不会调用构造函数

  2. 如果子类定义了构造函数,则不会隐式调用父类的构造函数

  3. 子类的构造函数允许和父类的构造函数参数不一致

  4. 如果子类没有定义构造函数,php会尝试寻找父类的构造函数

  5. 如果父类没有定义构造函数,使用parent关键字显式调用父类构造函数,会导致致命错误

<span> 1</span> <?<span>php
</span><span> 2</span> 
<span> 3</span> <span>class</span><span> P{
</span><span> 4</span> 
<span> 5</span>     <span>public</span> <span>function</span><span> __construct(){
</span><span> 6</span>         <span>echo</span> <span>__CLASS__</span> . "\n"<span>;
</span><span> 7</span> <span>    }
</span><span> 8</span> 
<span> 9</span> <span>}
</span><span>10</span> 
<span>11</span> <span>class</span> C1 <span>extends</span><span> P{
</span><span>12</span> 
<span>13</span>     <span>public</span> <span>function</span><span> __construct(){
</span><span>14</span>         <span>echo</span> <span>__CLASS__</span> . "\n"<span>;
</span><span>15</span> <span>    }
</span><span>16</span> 
<span>17</span> <span>}
</span><span>18</span> 
<span>19</span> <span>class</span> C2 <span>extends</span><span> P{
</span><span>20</span> 
<span>21</span>     <span>public</span> <span>function</span><span> __construct(){
</span><span>22</span>         parent::<span>__construct();
</span><span>23</span>         <span>echo</span> <span>__CLASS__</span> . "\n"<span>;
</span><span>24</span> <span>    }
</span><span>25</span> 
<span>26</span> <span>}
</span><span>27</span> 
<span>28</span> <span>class</span> C3 <span>extends</span><span> P{
</span><span>29</span> 
<span>30</span> <span>}
</span><span>31</span> 
<span>32</span> <span>//</span><span> P</span>
<span>33</span> <span>$ins</span> = <span>new</span><span> P();
</span><span>34</span> 
<span>35</span> <span>//</span><span> Nothing</span>
<span>36</span> <span>$ins2</span> = <span>clone</span> <span>$ins</span><span>;
</span><span>37</span> 
<span>38</span> <span>//</span><span> C1</span>
<span>39</span> <span>new</span><span> C1();
</span><span>40</span> 
<span>41</span> <span>//</span><span> P
</span><span>42</span> <span>// C2</span>
<span>43</span> <span>new</span><span> C2();
</span><span>44</span> 
<span>45</span> <span>//</span><span> P</span>
<span>46</span> <span>new</span> C3();

除了魔术方法的构造函数,php还支持与类名相同的构造函数,不过优先级比魔术方法低:

<span> 1</span> <?<span>php
</span><span> 2</span> 
<span> 3</span> <span>class</span><span> C1{
</span><span> 4</span> 
<span> 5</span>     <span>public</span> <span>function</span><span> C1(){
</span><span> 6</span>         <span>echo</span> <span>__CLASS__</span> . "1\n"<span>;
</span><span> 7</span> <span>    }
</span><span> 8</span> 
<span> 9</span>     <span>public</span> <span>function</span><span> __construct(){
</span><span>10</span>         <span>echo</span> <span>__CLASS__</span> . "2\n"<span>;
</span><span>11</span> <span>    }
</span><span>12</span> 
<span>13</span> <span>}
</span><span>14</span> 
<span>15</span> <span>class</span><span> C2{
</span><span>16</span> 
<span>17</span>     <span>public</span> <span>function</span><span> C2(){
</span><span>18</span>         <span>echo</span> <span>__CLASS__</span> . "1\n"<span>;
</span><span>19</span> <span>    }
</span><span>20</span> 
<span>21</span> <span>}
</span><span>22</span> 
<span>23</span> <span>class</span><span> C3{
</span><span>24</span> 
<span>25</span>     <span>public</span> <span>function</span><span> C3(){
</span><span>26</span>         <span>echo</span> <span>__CLASS__</span> . "1\n"<span>;
</span><span>27</span> <span>    }
</span><span>28</span> 
<span>29</span>     <span>public</span> <span>function</span><span> __construct(){
</span><span>30</span>         <span>echo</span> <span>__CLASS__</span> . "2\n"<span>;
</span><span>31</span>         <span>$this</span>-><span>C3();
</span><span>32</span> <span>    }
</span><span>33</span> 
<span>34</span> <span>}
</span><span>35</span> 
<span>36</span> <span>//</span><span> C12</span>
<span>37</span> <span>new</span><span> C1();
</span><span>38</span> 
<span>39</span> <span>//</span><span> C21</span>
<span>40</span> <span>new</span><span> C2();
</span><span>41</span> 
<span>42</span> <span>//</span><span> C32
</span><span>43</span> <span>// C31</span>
<span>44</span> <span>new</span> C3();

php5.3.3之后,在命名空间之内使用与类名同名的方法,不再作为构造函数,命名空间之外不变:

<span> 1</span> <?<span>php
</span><span> 2</span> 
<span> 3</span> <span>namespace N;
</span><span> 4</span> 
<span> 5</span> <span>class</span><span> C{
</span><span> 6</span> 
<span> 7</span>     <span>public</span> <span>function</span><span> C(){
</span><span> 8</span>         <span>echo</span> <span>__CLASS__</span> . "\n"<span>;
</span><span> 9</span> <span>    }   
</span><span>10</span> 
<span>11</span> <span>}
</span><span>12</span> 
<span>13</span> <span>//</span><span> Nothing</span>
<span>14</span> <span>new</span> \N\C();

构造函数可以用全部三个访问控制修饰符,如单例模式:

<span> 1</span> <?<span>php
</span><span> 2</span> 
<span> 3</span> <span>class</span><span> Single{
</span><span> 4</span> 
<span> 5</span>     <span>public</span> <span>static</span> <span>function</span><span> getInstance(){
</span><span> 6</span>         <span>static</span> <span>$ins</span> = <span>null</span><span>;
</span><span> 7</span>         <span>if</span>(<span>empty</span>(<span>$ins</span><span>)){
</span><span> 8</span>             <span>$ins</span> = <span>new</span><span> self();
</span><span> 9</span> <span>        }   
</span><span>10</span>         <span>return</span> <span>$ins</span><span>;
</span><span>11</span> <span>    }   
</span><span>12</span> 
<span>13</span>     <span>private</span> <span>function</span><span> __construct(){
</span><span>14</span>         <span>echo</span> <span>__CLASS__</span> . "\n"<span>;
</span><span>15</span> <span>    }   
</span><span>16</span> 
<span>17</span> <span>}
</span><span>18</span> 
<span>19</span> <span>//</span><span> Single</span>
<span>20</span> Single::getInstance();

2. 析构函数(__destruct)

void __destruct ( void )

析构函数:析构函数会在某个对象的引用被全部删除或对象被显示销毁时执行。

注意:

  1. 同构造函数类似,父类的析构函数并不会被引擎暗中调用,必须显式调用parent::__destruct

  2. exit和die并不能阻止析构函数的执行

  3. 致命错误会阻止析构函数的执行

  4. 在析构函数中调用exit,可以阻止其他未执行的析构函数的执行

  5. 如果父类没有定义析构函数,使用parent关键字显式调用父类析构函数,会导致致命错误

<?<span>php

</span><span>class</span><span> P{

    </span><span>function</span><span> __destruct(){
        </span><span>echo</span> <span>get_class</span>(<span>$this</span>) . "\t" . <span>__CLASS__</span> . "\n"<span>;
    }   
}

</span><span>class</span> C1 <span>extends</span><span> P{

    </span><span>function</span><span> __destruct(){
        </span><span>echo</span> <span>get_class</span>(<span>$this</span>) . "\t" . <span>__CLASS__</span> . "\n"<span>;
    }   

}

</span><span>class</span> C2 <span>extends</span><span> P{

    </span><span>function</span><span> __destruct(){
        parent</span>::<span>__destruct();
        </span><span>echo</span> <span>get_class</span>(<span>$this</span>) . "\t" . <span>__CLASS__</span> . "\n"<span>;
    }   

}

</span><span>class</span> C3 <span>extends</span><span> P{

}

</span><span>$insP</span> = <span>new</span><span> P();
</span><span>$ins1</span> = <span>new</span><span> C1();
</span><span>$ins2</span> = <span>new</span><span> C2();
</span><span>$ins3</span> = <span>new</span><span> C3();

</span><span>/*</span><span>*
输出:
C3    P
C2    P
C2    C2
C1    C1
P    P
*</span><span>*/</span>

 

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.