重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

初めまして。当方PHP初心者です。

標題の通り、PHPでrailsのbefore_filterのような機能を再現できないでしょうか。
要するにクラス内にAメソッド、Bメソッド、Cメソッド、Dメソッドが存在していて、
Bメソッド、Cメソッド、Dメソッドを実行する前に必ずAメソッドを実行させたいのです。

実現できる関数を探してみたのですが、どうにも見つかりませんでした。
皆様のお知恵を拝借したいです。
どうぞ、よろしくお願いします。

A 回答 (1件)

Ruby On Railsは、Ruby言語で開発されたWebアプリケーションフレームワークですので、


素のRubyで存在しているパターンというわけではないんじゃないでしょうか。
PHPでもまた、素のPHPで実現できるものではなく、フレームワークに機能として含まれている場合がある(ソレもアクセス手段を限定的にした場合に動作する)、程度のものだと思います。
PHPはRubyほど柔軟な言語ではないので、ソレを標準的にどこでも利用できるようにするとしたら、PHPの言語自体のソース(C言語作られた元のソース)を紐解いて修正するなり、Extensionを作成する(やっぱりC言語)しかないと思います。

ただ、意図する動作に「近いもの」を実現する方法としてはいくつかあります。下記はその一例です。

<?php

class Test{

protected $before_filter = 'A';

protected function A(){
echo "hoge";
}

protected function _B(){

}

protected function _C(){

}

protected function _D(){

}

public function __call($name, $param){

$name = "_{$name}";

if(method_exists($this, $name)){
if(is_callable(array($this, $this->before_filter))){
call_user_func(array($this, $this->before_filter));
}
return call_user_func_array(array($this, $name), $param);

}
return null;
}

}

$test = new Test();

$test->B();
$test->C();
$test->D();

?>

このようにすれば近い動作はします。
これは、
必要なメソッド名の前に「_(アンダースコア)」をつけたものを作成し、外側の呼び出しでは「$test->C()」というように「_」をはずして呼び出します。
当然存在しないメソッドを呼び出していますので、通常エラーになってしまいますが、PHPのオーバーロードの、マジックメソッドである「__call」にて、存在していないメソッド名と引数に指定されたものを取得します。
そして、取得したメソッド名に「_」を付加し、メンバ変数$before_filterで指定したメソッドをcall_user_func関数で呼び出した後に、call_user_func_array関数にて、それぞれ動的にメソッドを呼び出しています。

マジックメソッドや、call_user_func関数などに関しては、PHPマニュアルや、その他解説サイトなどで詳しく説明されています。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!