LoginSignup
2
3

More than 5 years have passed since last update.

PHP クラスにおけるメンバ変数(プロパティ)内の関数オブジェクトの呼び出し

Posted at

デザインパターンの勉強をしていたところ、
ストラテジーパターンは今なら無名関数で出来るよね~みたいな話を見かけ、
wikipediaを見ながら実装しようとしたら思いもよらないところでつまったのでメモ。

wikiに見るPythonのストラテジーパターン実装例

Python では関数が第一級オブジェクトであり、このパターンを明示的に定義する必要はない。
下記はコールバック関数を用いる GUI プログラミングで見られる例である。

class Button:
    """A very basic button widget."""
    def __init__(self, submit_func, label):
        self.on_submit = submit_func   # strategy 関数を直接生成
        self.label = label

# 異なる戦略を持つ二つのインスタンスを作成
button1 = Button(sum, "Add 'em")
button2 = Button(lambda nums: " ".join(map(str, nums)), "Join 'em")

# ボタンをテストする
numbers = range(1, 10) # A list of numbers 1 through 9
print button1.on_submit(numbers) # displays "45"
print button2.on_submit(numbers) # displays "1 2 3 4 5 6 7 8 9"

PHPで同様のものを実装してみる

class Button
{
    public $submit;

    public function __construct(callable $submit_func)
    {
        $this->submit = $submit_func;
    }
}

$button1 = new Button('array_sum');
$button2 = new Button(function($nums) { return implode(' ', $nums); });

$nums = range(1, 9);

echo $button1->submit($nums);
echo $button2->submit($nums);

すると…

PHP Fatal error:  Call to undefined method Button::submit() in ...

そんなメソッドないでしょと怒られる

呼び出し方が違うようなので探したところきちんと書いてあるところがありました。
それにそって正しく実装してみます。

PHPで正しく同様のものを実装してみる

class Button
{
    public $submit;

    public function __construct(callable $submit_func)
    {
        $this->submit = $submit_func;
    }
}

$button1 = new Button('array_sum');
$button2 = new Button(function($nums) { return implode(' ', $nums); });

$nums = range(1, 9);

echo call_user_func($button1->submit, $nums);
echo call_user_func($button2->submit, $nums);

もしくは

$button1 = (new Button('array_sum'))->submit;
$button2 = (new Button(function($nums) { return implode(' ', $nums); }))->submit;

$nums = range(1, 9);

echo $button1($nums);
echo $button2($nums);

参考URL

[PHP] クラスにおけるメンバ変数(プロパティ)内の関数オブジェクトとメソッドの性質:無名関数(クロージャ)について
Strategy パターン

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3