やったことだけ書く備忘録

直前にrequireで読み込んだクラスファイルに定義されたクラスを取得するちょっとしたアイデア

オートロード機構の所で悩んでたんですが、多分これでうまくいくかなというメモ。



フレームワークとかで困った所


大体最近のFWにはクラスのオートロード機構が備わってますが、その内部では、spl_autoload_register(__autoload()でもいいですが)に登録された関数でrequireするのが定石です。で、namespaceは別として、require(_once)で読み込まれたファイルに実際に特定のクラスが存在しているかどうかをチェックする方法に悩んでました。

今まではこんな感じで存在チェックしてました:




$class 
'Hoge';
require_once(
'/path/to/' $class '.php');
if ( ! 
class_exists($classFALSE) ) {
  throw new 
RuntimeException('うんたらかんたら');
}

return new 
$class();
 


他にいい方法はないものか


上記だと、フレームワームのnamespaceとかでプレフィックスがついていた場合、例えば、ファイルはHoge.phpだけど中で定義するクラスはAPP_Hogeだったりする場合(それが本当にいいのかは置いときまして)、本当にそのクラスが定義されているかどうかをチェックする方法ってないのかなーって考えてました。で、暫定で下のコード。




$prefix 
'APP_'// FWのどっかで定数で定義されてる
$class 'Hoge';
require_once(
'/path/to/' $class '.php');
if ( ! 
class_exists($classFALSE) ) {
  
// プレフィックスつきも検索
  
$class $prefix $class;
  if ( ! 
class_exists($classFALSE) ) {
    throw new 
RuntimeException('うんたらかんたら');
  }
}

return new 
$class();
 


これでも良いんですが、アプリケーションを実装する人によってはプレフィックス有り/無しは自由であって欲しい。そして自分の中では、「プレフィックス付き = コアクラス拡張」、「プレフィックス無し = オーバーライド」という位置づけを目指してました。なのでもうちょっと確実に定義されたクラスって取れないかなーって考えたのが以下です。




$class 
'Hoge';
require_once(
'/path/to/' $class '.php');
$declared end(get_declared_classes());
if ( ! 
preg_match('/.+' $class '$/'$declared) ) {
   throw new 
RuntimeException('うんたらかんたら');
}

return new 
$declared();
 


これならクラスの存在は少なくとも保証されているので、ちょっといい感じかな、と。プレフィックスの有り/無しもあまり気にする事もありませんね。継承関係があり、基底クラスのオートロードが走った場合でも、クラスの宣言順はHogeクラスが最後になるので大丈夫でした。理屈的には、

「extendsキーワードがあれば、先に基底クラスのクラスチェック(なければオートロード走る)を行い、続いて継承を行い、クラス宣言を完了とする」

という動きのようなので、継承関係があってもget_declared_classes()の最後のインデックスにはHogeが入りますね。



ただし


当たり前ですが、1ファイル中に複数のクラス宣言があった場合は、一番最後のクラス宣言を取得するので、「1ファイル1クラス」というルールが成立する上での手法ですね(というか大体そういうルールですよね?ね?)

« 前の記事 次の記事 »

6件のコメント

Janesa さん

This was so helpful and easy! Do you have any arelicts on rehab?

Keyanna さん

This makes <a href="http://xkogwyjm.com">evyhntrieg</a> so completely painless.

owagafomutid さん

http://levitrageneric-cheapest-price.net/ - levitrageneric-cheapest-price.net.ankor <a href="http://cheapest-priceventolinonline.net/">cheapest-priceventolinonline.net.ankor</a> http://levitra-online-cheap.net/

isafoqeniwex さん

http://levitrageneric-cheapest-price.net/ - levitrageneric-cheapest-price.net.ankor <a href="http://cheapest-priceventolinonline.net/">cheapest-priceventolinonline.net.ankor</a> http://levitra-online-cheap.net/

ovisadiziu さん

http://levitra-20mg-priceof.online/ - levitra-20mg-priceof.online.ankor <a href="http://pricespharmacy-canadian.online/">pricespharmacy-canadian.online.ankor</a> http://buy-amoxicillin-amoxil.online/

exaceviyu さん

http://doxycycline-cheapbuy.site/ - doxycycline-cheapbuy.site.ankor <a href="http://onlinebuycytotec.site/">onlinebuycytotec.site.ankor</a> http://tadalafilcialis-cheapestprice.site/

コメントを投稿する

 画像に表示されている文字を入力してください。