Help us understand the problem. What is going on with this article?

PHP基礎構文 マジックメソッドを全て利用してみる

前提

  • 実行環境
    • PHP 7.1.32
  • 本エントリーでは、PHPが用意する全マジックメソッドに関する挙動について触れる

マジックメソッドとは

インスタンスがある特定の条件になったときに、明示的にcallしなくても暗黙的にcallされるメソッド

引用元便利だけど使いどころが難しいPHPの代表的なマジックメソッドと無名関数の使い方

  • 暗黙的にコールされる事がポイント

__construct()

class Message
{
    public function __construct()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
    }
}

var_dump(new Message());

/* 出力結果 */
call Message::__construct
object(Message)#1 (0) {
}

__destruct()

class Message
{
    public function __construct()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
    }

    public function __destruct()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
    }
}

var_dump(new Message());

/* 出力結果 */
call Message::__construct
object(Message)#1 (0) {
}
call Message::__destruct

__call()

<?php

class Message
{
    public function __call(string $name, array $arguments)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        print 'Value of first argument $name: ' . $name . PHP_EOL;
        print 'Value of second argument $arguments: ' . implode($arguments) . PHP_EOL;
    }
}

$message = new Message();
$message->getMessage('Hello');
var_dump($message);

/* 出力結果 */
call Message::__call
Value of first argument $name: getMessage
Value of second argument $arguments: Hello
object(Message)#1 (0) {
}

__callStatic()

  • アクセス不能メソッドを静的にアクセスした時にコールされるメソッド
class Message
{
    public static function __callStatic(string $name, array $arguments)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        print 'Value of first argument $name: ' . $name . PHP_EOL;
        print 'Value of second argument $arguments: ' . implode($arguments) . PHP_EOL;
    }
}

$message = new Message();
$message::getMessage('Hello');
var_dump($message);

/* 出力結果 */
call Message::__callStatic
Value of first argument $name: getMessage
Value of second argument $arguments: Hello
object(Message)#1 (0) {
}

__get()

<?php

class Message
{
    private $message = [];

    public function __get(string $name)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        print 'Value of first argument $name: ' . $name . PHP_EOL;
        return $this->message;
    }
}

$message = new Message();
var_dump($message->message);

/* 出力結果 */
call Message::__get
Value of first argument $name: message
array(0) {
}

__set()

<?php

class Message
{
    private $message = [];

    public function __get(string $name)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        print 'Value of first argument $name: ' . $name . PHP_EOL;
        if (array_key_exists($name, $this->message)) {
            return true;
        } else {
            return false;
        }
    }

    public function __set(string $name, $value)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        print 'Value of first argument $name: ' . $name . PHP_EOL;
        print 'Value of second argument $value: ' . $value . PHP_EOL;
        $this->message[$name] = $value;
        print PHP_EOL;
    }
}

$message = new Message();
$message->message = 'Hello';
var_dump($message->message);

/* 出力結果 */
call Message::__set
Value of first argument $name: message
Value of second argument $value: Hello

call Message::__get
Value of first argument $name: message
bool(true)

__isset()

<?php

class Message
{
    private $message = [];

    public function __isset(string $name)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        print 'Value of first argument $name: ' . $name . PHP_EOL;
        return isset($this->message[$name]);
    }
}

$message = new Message();
var_dump(isset($message->message));

/* 出力結果 */
call Message::__isset
Value of first argument $name: message
bool(false)

__unset()

<?php

class Message
{
    private $message = [];

    public function __unset(string $name)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        print 'Value of first argument $name: ' . $name . PHP_EOL;
        unset($this->message[$name]);
    }
}

$message = new Message();
unset($message->message);

/* 出力結果 */
call Message::__unset
Value of first argument $name: message

__sleep()

class Message
{
    public function __sleep()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        return [];
    }
}
$message = new Message();
var_dump(serialize($message));

/* 出力結果 */
call Message::__sleep
string(18) "O:7:"Message":0:{}"

__wakeup()

  • unserialize()をコールした時にコールされるメソッド
class Message
{
    public function __wakeup()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        return [];
    }
}
$message = new Message();
$serializedMessage = serialize($message);
var_dump(unserialize($serializedMessage));

/* 出力結果 */
call Message::__wakeup
object(Message)#2 (0) {
}

__toString()

class Message
{
    public function __toString()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        return 'Hello' . PHP_EOL;
    }
}

$message = new Message();
echo $message;

/* 出力結果 */
call Message::__toString
Hello

__invoke()

class Message
{
    public function __invoke($value)
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        echo $value . PHP_EOL;
    }
}

$message = new Message();
$message('Hello');
var_dump($message);

/* 出力結果 */
call Message::__invoke
Hello
object(Message)#1 (0) {
}

__set_state()

class Message
{
    public $val_a;
    public $val_b;

    public static function __set_state(array $properties)
    {
        $this->val_a = $properties['val_a'];
        $this->val_b = $properties['val_b'];
        print 'call ' . __METHOD__ . PHP_EOL;
    }
}

$message = new Message();
$message->val_a = 'Hello';
$message->val_b = 'Good morning';
var_export($message);

/* 出力結果 */
Message::__set_state(array(
   'val_a' => 'Hello',
   'val_b' => 'Good morning',
))

__clone()

class Message
{
    public function __clone()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
    }
}

$message = new Message();
var_dump(clone $message);

/* 出力結果 */
call Message::__clone
object(Message)#2 (0) {
}

__debugInfo()

class Message
{
    public function __debugInfo()
    {
        print 'call ' . __METHOD__ . PHP_EOL;
        return [];
    }
}

var_dump(new Message());

/* 出力結果 */
call Message::__debugInfo
object(Message)#1 (0) {
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした