カットの下-私がそれをやった方法の物語。 これは最も賢く、最高で、最も美しい解決策ではないので、あなたのアドバイスやコメントを聞いてうれしいです。 一般に、このトピックはアドバイスとコメントのためのものです-ケースに関するものであり、スペルミスなどのゴミに関するものではありません。 よろしくお願いします!
最初は、Zend_Loader(より正確にはZend_Loader_Autoloader-Zend_Applicationが使用するもの)を使用し、インクルードを含むファイルをロードしないことに同意しました。
その後、私はこのように行動することにしました:
- APPLICATION_PATHに必要なすべてのマジックファイルを収集します。 '/../data/files.txt'
- APPLICATION_PATHを開きます。 '/../data/files.txt'そしてそれらを1つの魔法のAPPLICATION_PATHに収集します。 '/../data/HotPlug.php'、途中でインクルージョンとコメントを切り取ります
したがって、まず:data.txtでファイルを収集します。
Zend_Loader_PluginLoaderはそのようなリスト自体を作成できますが(少し曲がって)、Zend_Loader_Autoloaderは作成できません。 しかし、それは問題ではありません。 オートローダーを継承し、すべてを正直に行うことは価値がありますが、私は無駄で、自分でZFをダウンロードしました。 幸いなことに、幽霊バージョンを本番環境にアップロードする必要はありません。HotPlug.phpは自宅で作成できます。
/ *ライブラリ/ Zend / Loader.php * / パブリック静的関数loadClass($クラス、$ dirs = null) { if(class_exists($ class、false)|| interface_exists($ class、false)){ 帰る } if((null!== $ dirs)&&!is_string($ dirs)&&!is_array($ dirs)){ // require_once 'Zend / Exception.php'; 新しいZend_Exceptionをスローします(「ディレクトリ引数は文字列または配列でなければなりません」); } //クラス名からパスを自動検出します $ file = str_replace( '_'、DIRECTORY_SEPARATOR、$クラス)。 '.php'; if(!empty($ dirs)){ //自動検出されたパスを使用します $ dirPath = dirname($ファイル); if(is_string($ dirs)){ $ dirs = explode(PATH_SEPARATOR、$ dirs); } foreach($キーとして$ dirs => $ dir){ if($ dir == '。'){ $ dirs [$ key] = $ dirPath; } else { $ dir = rtrim($ dir、 '\\ /'); $ dirs [$ key] = $ dir。 DIRECTORY_SEPARATOR。 $ dirPath; } } $ file = basename($ file); self :: loadFile($ファイル、$ dirs、true); } else { self :: _ securityCheck($ファイル); インクルード$ファイル。 } //ここから追加 $ files = file(APPLICATION_PATH。 '/../data/files.txt'); $ファイル[] = $ファイル; $ files = array_unique($ファイル); file_put_contents(APPLICATION_PATH。 '/../data/files.txt'、implode( "\ n"、$ files)); //ここ if(!class_exists($ class、false)&&!interface_exists($ class、false)){ // require_once 'Zend / Exception.php'; 新しいZend_Exceptionをスローします( "ファイル\" $ファイル\ "存在しないか、クラス\" $クラス\ "ファイルに見つかりませんでした"); } }
サイトを開いてしばらく走りました。 私はこのサイトと、広大なAPPLICATION_PATHが気に入りました。 '/../data/files.txt'-いいえ。 しかし、これは大したことではないと思い、ビルドスクリプトをスケッチしました。 繰り返しますが、スマートで、美しく、オブジェクト指向で、コンソールにする価値はありましたが、無駄になり、愚かにも/ htdocs /にcompose.phpを作成しました
<? $ skip = array( T_COMMENT、T_OPEN_TAG、T_CLOSE_TAG、T_DOC_COMMENT、T_ML_COMMENT // HotPlugからのコメントを参照してください! あらゆる種類の<? そして?> nafigも ); $ dir = "d:\ work \ non-clause \ library \\"; $ files = file( 'd:\ work \ non-clause \ app \ data \ files.txt'); $ res = '<?'; foreach($ファイルを$ファイルとして){ if(substr(trim($ file)、-4)!= '.php') $ file = str_replace( '_'、 '\\'、trim($ file))。 「.php」; //ファイルではなくクラス名がある場合-再実行 if(is_file($ fileName = trim($ dir。$ file)))){ $ res。= "\ n / * $ file * / \ n"; $ tokens = token_get_all(file_get_contents($ fileName)); $ was_require_once = 0; $ was_shit_require_once = 0; foreach($トークンを$トークンとして){ if(is_array($ token)){ if(in_array($トークン[0]、$ skip)) 続ける; if($トークン[0] == T_WHITESPACE){ $ res。= ''; //タブのスペースが少なくなります 続ける; } if($ was_require_once){ if($ token [0] == T_CONSTANT_ENCAPSED_STRING){// require_onceをスキップし、その後に引用符付き文字列を続けます。 もし$ fileのようなものが入ったら-スキップする必要はありません! また、かなり汚いメソッド、それは考える価値があるだろう $ was_shit_require_once = 1; } else { $ res。= 'require_once'。 $トークン[1]; } $ was_require_once = 0; 続ける; } if($トークン[0] == T_REQUIRE_ONCE){ $ was_require_once = 1; } else { $ res。= $トークン[1]; } } else { if(!$ was_shit_require_once)//そのため、「;」 削除するrequire_onceを削除した後 $ res。= $トークン; $ was_shit_require_once = 0; } } $ res。= "\ n"; } } file_put_contents( "d:\ work \ non-verbosity \ app \ data \ HotPlug.php"、$ res);
その後、幸いにもこのファイルをインデックスに貼り付けました。 そして、あなたはそれが私に言ったことを知っていますか? 彼にはクラスが不足している。 「Wtf?!」-考えて、不足しているクラスをキャッチし始め、それらをペンでfiles.txtに追加し、HotPlug.phpを再構築します:)
そして、Zendクラスの先頭にrequire_onceが含まれているため、Loaderがこれらのファイルを認識していないため、これらのファイルは認識されないことがわかりました。 しかし、それらは含まれません%)
これらのrequire_onceすべてにコメントする別のスクリプトを作成する必要がありました。
<? 関数getDirectoryTree($ outerDir){ $ dirs = array_diff(scandir($ outerDir)、Array( "。"、 "..")); $ dir_array = Array(); foreach($ drs as $ d){ if(is_dir($ outerDir。 "/"。$ d))$ dir_array [$ d] = getDirectoryTree($ outerDir。 "/"。$ d); それ以外の場合$ dir_array [$ d] = $ d; } return $ dir_array; } $ dirs = getDirectoryTree( "d:\ work \ acne \ library \ Zend"); function gotcha($ fname、$ key、$ dir){ if(is_array($ fname)){ array_walk($ fname、 'gotcha'、$ dir。DIRECTORY_SEPARATOR。$ key); 帰る } $ fname = $ dir。 DIRECTORY_SEPARATOR。 $ fname; file_put_contents($ fname、preg_replace( "/ require_once \\ s + \ 'Zend /"、 "// require_once \' Zend"、file_get_contents($ fname))); //書く価値があります/(必須| include)_once \\ s +(\ '| \ ")/またはそのようなものですが、このpregをテストするのは無駄だったので、スクリプトを4回続けて実行しました。その後、それはまったく必要ありません:) } array_walk($ dirs、 'gotcha'、 "d:\ work \ acne \ library \ Zend");
HotPlug.phpを再構築しましたが、すべてが素晴らしかったです!
-ステップ2
Zend_Loader_Autoloaderに加えて、Zend_Loader_PluginLoaderはインクルードについても認識しており、Zend_Loaderなしで自分自身をインクルードします。 しかし、彼はリストをコンパイルする方法を知っています。 このように:
// Bootstrap.phpのどこか、または-私と一緒に-/library/R00/Bootstrap.phpにあり、そこから私のプロジェクトのブートストラップが継承されます Zend_Loader_PluginLoader :: setIncludeFileCache(APPLICATION_PATH。 '/../Data/cache.php');
いくつかの起動後のこのcache.phpには、これらのプラグインを自動的にロードするために必要な多くのinclude_onceが含まれています。 私はまだこれからの成長が何であるか理解できず、これらのファイルを私のfiles.txtに押し込むように頼むことに決めました
Zend_Loader_PluginLoader :: setIncludeFileCache(APPLICATION_PATH。 '/../Data/files.txt');
文字列include_once '...'を解析しないために。 私は電話を切った(結局、なんとろくでなしだ!)Zend / Loader / PluginLoader.php
保護された静的関数_appendIncFile($ incFile) { if(!file_exists(self :: $ _ includeFileCache)){ $ file = ''; //時間が変わる } else { $ file = file_get_contents(self :: $ _ includeFileCache); } if(!strstr($ file、$ incFile)){ $ file。= "\ n $ incFile \ n"; // 2つの変更 file_put_contents(self :: $ _ includeFileCache、$ file); } }
繰り返しになりますが、これを本番環境に送信する必要はありません。 そして自宅で-まあ、自宅で、それは自宅にしましょう。 ZFを更新してから、HotPlug.phpを再構築する必要があります。まあ、もう一度やり直します。または、人間ですべてを行います。
今でも、サイトを駆け回ってプラグインを収集し、HotPlug.phpを再構築しました。 私の人生は良くなりました!
では、同様の問題を解決するためのベストプラクティスについて教えてください:)そして、不要なハッキングのない通常の合理的なオブジェクト指向ソリューションを作成しましょう。