>백엔드 개발 >PHP 튜토리얼 >PHP의 매직 메소드

PHP의 매직 메소드

WBOY
WBOY원래의
2016-08-08 09:30:101069검색

PHP 매직 메소드:

__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 및 __debugInfo()와 같은 메서드는 PHP에서 "매직 메서드"라고 합니다. 매직 기능을 사용하려는 경우가 아니면 자체 클래스 메서드 이름을 지정할 때 이러한 메서드 이름을 사용할 수 없습니다.

__construct(),类的构造函数
__destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法(私有或者不存在)时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用。
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用。
__clone(),当对象复制完成时调用

__construct() 및 __destruct()
객체가 생성될 때 생성자 __construct()가 호출되고 객체가 종료될 때 소멸자 __destruct()가 호출됩니다. 🎜>

<?php &#160;
class ConDes
{
&#160;&#160;&#160; protected $a = &#39;&#39;;

&#160;&#160;&#160; function __construct(){
&#160;&#160;&#160;&#160;&#160;&#160;&#160; echo &#39;在构造函数中<br>';
    }

    function __destruct(){

        echo '在析构函数中<br>';
    }
}

$val = new ConDes();
unset($val);

?><pre name="code" class="php">
출력:
생성자 및 소멸자에서

__call() 및 __callStatic()은 객체에서 액세스할 수 없는 메서드가 호출될 때 호출됩니다. 후자는 정적 메서드입니다.

출력:
<?php  
class MethodTest  
{
    public function __call ($name, $arguments) {
    var_dump($arguments);
        echo "object method $name and ".implode(',',$arguments)."<br>";
    }

    public static function __callStatic ($name, $arguments) {
        echo "static method $name and ".implode(',',$arguments)."<br>";
    }
}

$obj = new MethodTest;
$obj->runTest('in object context','another arg');
MethodTest::runTest('in static context');  
?>
배열(크기=2)

0 => 문자열 '객체 컨텍스트'(길이=17)
1 => 문자열 '다른 인수'(길이=11)
객체 메서드 runTest 및 in 객체 컨텍스트, 또 다른 인수
정적 메서드 runTest 및 정적 컨텍스트

__get(), __set(), __isset() 및 __unset()

에서 액세스할 수 없는 클래스 멤버를 가져올 때 이 두 함수가 호출됩니다. 액세스할 수 없는 클래스 멤버 변수를 설정할 때. <br><br>

출력:
<?php
class MethodTest  
{
    private $data = array();
    private $a = &#39;&#39;;
    public $bbb = &#39;&#39;;

    public function __set($name, $value){
        $this->data[$name] = $value;
		echo '__set';
		var_dump($this->data);
    }

    public function __get($name){
		echo '__get';
		var_dump($this->data);
        if(array_key_exists($name, $this->data))
            return $this->data[$name];
        return NULL;
    }

    public function __isset($name){
		echo '__isset';
        return isset($this->data[$name]);
    }

    public function __unset($name){
		echo '__unset';
        unset($this->data[$name]);
    }
}

$in = new MethodTest();
$in->a = 'aaaa';
$aaa = $in->a;
$res = isset($in->c)? 'set':'not set';
echo '<br>'.$res.'<br>';
unset($in->a);
?>
__set

배열(크기=1)
'a' => 문자열 'aaaa'(길이=4)
__get
배열(크기=1)
'a' = > string 'aaaa' (길이=4)
__isset
설정되지 않음
__unset

__sleep() 및 __wakeup()

serialize()를 실행할 때 및 unserialize할 때 (), 이 두 함수가 먼저 호출됩니다. 예를 들어, 객체를 직렬화할 때 객체에 데이터베이스 링크가 있습니다. 역직렬화 중에 링크 상태를 복원하려면 이 두 함수를 재구성하여 링크를 복원할 수 있습니다.

<p><code><span></span>

<?php
class Connection {
&#160;&#160;&#160; public $link;
&#160;&#160;&#160; private $server, $username, $password, $db;
&#160;&#160; &#160;
&#160;&#160;&#160; public function __construct($server, $username, $password, $db)
&#160;&#160;&#160; {
&#160;&#160;&#160;&#160;&#160;&#160;&#160; $this->server = $server;
        $this->username = $username;
        $this->password = $password;
        $this->db = $db;
        $this->connect();
    }
    
    private function connect()
    {
        $this->link = mysql_connect($this->server, $this->username, $this->password);
        mysql_select_db($this->db, $this->link);
    }
    
    public function __sleep()
    {
    echo 'sleep<br>';
        return array('server', 'username', 'password', 'db');
    }
    
    public function __wakeup()
    {
    echo 'wakeup<br>';
        $this->connect();
    }
}


$a = new Connection('localhost','mosi','moshi','test');
$sql = 'select id,username from user limit 1';
$res = mysql_query($sql,$a->link);
$res = mysql_fetch_array($res);
var_dump($res);

$sres = serialize($a);
mysql_close($a->link);
//unset($a);

$unsres = unserialize($sres);
var_dump($unsres);
$sql = 'select id,username from user limit 1';
$ress = mysql_query($sql,$unsres->link);
$ress = mysql_fetch_array($ress);
var_dump($ress);


?>
출력:

<code><span>array (size=4)<br>  0 => string '1' (length=1)<br>  'id' => string '1' (length=1)<br>  1 => string 'm0sh1' (length=5)<br>  'username' => string 'm0sh1' (length=5)<br>sleep<br>wakeup<br>object(Connection)[2]<br>  public 'link' => resource(6, mysql link)<br>  private 'server' => string 'localhost' (length=9)<br>  private 'username' => string 'moshi' (length=4)<br>  private 'password' => string 'moshi' (length=5)<br>  private 'db' => string 'test' (length=4)<br>array (size=4)<br>  0 => string '1' (length=1)<br>  'id' => string '1' (length=1)<br>  1 => string 'm0sh1' (length=5)<br>  'username' => string 'm0sh1' (length=5)</span>배열(크기=4)

0 => 문자열 '1'(길이=1)

'id' => 문자열 '1'(길이=1) 1 => 문자열 'm0sh1'(길이=5)

'username' => 문자열 'm0sh1'(길이=5)

sleep<span>__toString()<br>对象当成字符串时的回应方法。例如使用echo $obj;</span>wakeup

object(Connection)[2 ]

공개 '링크' => 리소스(6, mysql 링크)<span></span> 비공개 '서버' => 문자열 'localhost'(길이=9)

비공개 '사용자 이름' => 길이=4)
<?php  
class TestClass  
{
    public function __toString() {
        return &#39;this is a object&#39;;
    }
}

$class = new TestClass();
echo $class;  
?>
개인 '비밀번호' => 문자열 'moshi'(길이=5)

개인 'db' => 문자열 '테스트'(길이=4)<span></span>배열(크기 =4) )<span></span> 0 => 문자열 '1'(길이=1)

'id' => 문자열 '1'(길이=1)

1 => 문자열 'm0sh1' )
'사용자 이름' => 문자열 'm0sh1'(길이=5)


<?php
class Invoke{
	public function __invoke(){
		echo 'in invoke<br>';
	}
}

class noInvoke{

}

$obj = new Invoke();
$obj();

var_dump(is_callable($obj));

$obj2 = new noInvoke();
//$obj2();
var_dump(is_callable($obj2));

<p>__toString ()<br>객체를 문자열로 처리할 때의 응답 방식입니다. 예를 들어 echo $obj;<br></p>

<br><br>

<?php  
class A  
{
    public $var1;
    public $var2;
	public static function __set_state ($arr) {
        $obj = new A;
        $obj->var1 = 'var11';
        $obj->var2 = $arr['var2'];
        return $obj;
    }
}

$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
var_dump($a);  
var_export($a);  

eval('$ress = '.var_export($a,true).';');
var_dump($ress);

?>
를 사용하여 다음을 출력합니다.

<br><br>이것은 객체입니다<br><br>이 메서드는 문자열만 반환할 수 있으며 Throw할 수 없습니다. 이 메서드에서는 예외가 발생합니다. 그렇지 않으면 치명적인 오류가 발생합니다. <br><br>

__invoke()

함수를 호출하여 객체를 호출할 때의 응답 메서드입니다.

<?php  
class Singleton {  
    private static $_instance = NULL;

    // 私有构造方法 
    private function __construct() {}

    public static function getInstance() {
        if (is_null(self::$_instance)) {
            self::$_instance = new Singleton();
        }
        return self::$_instance;
    }

    // 防止克隆实例
    public function __clone(){
        die('Clone is not allowed error: ' . E_USER_ERROR);
    }
}


$a = Singleton::getInstance();
$b = Singleton::getInstance();

if( $a === $b ){
	echo 'equal<br>';
}

$c = clone $b;
?>
출력:
invoke

boolean true
boolean false

__set_state()
이 정적 메서드는 클래스를 내보내기 위해 var_export()가 호출될 때 호출됩니다.

출력:

object(A)[1] public 'var1' => int 5 public 'var2' => string 'foo ' (길이=3)A::__set_state(array( 'var1' => 5, 'var2' => 'foo', ))object(A)[2] 공개 'var1' => string 'var11' (길이=5) public 'var2' => string 'foo' (길이=3)__clone()객체를 복사할 때 호출되는 경우 완료되었습니다. 출력: 같음복제가 허용되지 않음 오류: 256PHP 매직 상수: 소개 이상에서는 관련 내용을 포함하여 PHP의 매직 메소드를 소개했습니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.