クラスを1つのファイルに収集することにより、Zend Frameworkのパフォーマンスを向上させます。

リンクを開始し、ZendFramworkがサーバー上でリンクを処理するたびに、PHPインタープリターが実行中のコードをコンパイルするときに不快なパフォーマンスのオーバーヘッドが発生します。



PHPは、APC、Memcachedなどを使用してメモリにオペコードをキャッシュする方法を確かに知っています。 ただし、メモリからオペコードを取得する前に、最後の変更の日付が更新されたことを確認するためにハードドライブに移動します。 ファイルが少ない場合、これは見過ごされます。 それらがたくさんあると、生産性の低下が顕著になり始めます。



(もちろん、APCでは、ファイルの日付をチェックしないようにPHPインタープリターを構成できますが、ファイルを変更した場合はApacheを再起動する必要があり、開発には非常に不便です)。



クラスコレクターは既にネットワーク上で会っていますが、必要なものを常に正しく収集しているわけではありません。



はい、このトピックはすでに繰り返し取り上げられていますが、Zend_Controller_Router_Route_AbstractクラスとZend_Controller_Router_Route_Chainクラスを正しく接続する単一のスクリプトは見つかりませんでした。







ファイルを調べて1つにまとめるだけではうまくいきません。 円では、クラスとインターフェイスからの継承が使用されます。 そして、正しいコンパイルのためには、実装または拡張の後に来るクラスをコードでより早く宣言する必要があります。



この機能は次のクラスで実装され、アセンブリ中に問題が発生するとは思わない。



そのため、 Zend_Controller_Front :: getInstance()-> dispatch();の後、スクリプトの最後でコンパイラを実行できます (通常、プロジェクトのルートフォルダーにあるindex.phpのこの行)次のコードを使用します。

ZCompile::make( 'd:/www/project/lib/zendframework-1.7.1/Zend.compiled.phplib' ,

array(),

'd:/www/project/lib/zendframework-1.7.1/'

);




* This source code was highlighted with Source Code Highlighter .








最初のパラメーター -すべてのクラスが収集されるファイルへのパスを示します。

2番目のパラメーターには、接続する必要がある追加ファイルの配列が含まれます(それについては少し後で)。

3番目のパラメーター -フレームワークライブラリへのパスが含まれ、 最後に直接スラッシュ 「/」が必要です ! このディレクトリはZendと呼ばれます。 つまり 私の例では、Zendクラスファイルはdディレクトリにあります:/www/project/lib/zendframework-1.7.1/Zend/。 繰り返しますが、Zendフォルダーへのパスのみを指定する必要があります。



スクリプトを実行すると、ZCompileは必要なクラスのリストを自動的に取得し、それらを単一のファイルに書き込み、継承階層を監視します。



コードでは、通常、次の構成を使用して、コンパイル済みファイルまたは標準ライブラリからロードするフレームワークを選択します。

if (FRAMEWORK_LOAD_COMPILED_ZEND==1) {

require 'Zend.compiled.phplib' ;

} else {

require 'Zend/Loader.php' ;

}

Zend_Loader::registerAutoload( 'Zend_Loader' );




* This source code was highlighted with Source Code Highlighter .






「コンパイル済み」ファイルとZCompileクラスをZendフォルダー(フレームワークライブラリ)と同じレベルに保存すると非常に便利です。 つまり 私はそれらをdディレクトリに保存しています:/www/project/lib/zendframework-1.7.1/



したがって、 2番目のパラメーター配列について説明したことを思い出してください。 そのため、現在のスクリプトでは使用されなかったが、プロジェクトでは必要なクラスを接続できます。

そこで、接続する必要のある主要なクラスまたはディレクトリを単に示します。 例:

array(

'Zend/Auth/' , // ,

'Zend/Acl/' , // ,

'Zend/View/Helper/HeadTitle.php' , //

'Zend/View/Helper/Url.php' , //

)




* This source code was highlighted with Source Code Highlighter .








ディレクトリが接続されると、すべてのファイルは現在のレベルでのみ読み取られ、サブディレクトリには移動しません。 純粋なクラスを接続するときは、それだけを読み取ります。

ただし、クラスを(ディレクトリ経由または直接)接続すると、ZCompileは指定されたファイルが機能するために必要なすべてのクラスを収集します。 つまり ディレクトリ「Zend / Auth /」を指定した場合、サブディレクトリを含む指定されたフォルダに含まれるすべてを収集する可能性が高いです。



次のコードを別のファイルで実行するだけで、AclとAuthが収集されます。

<?php



set_include_path(

'd:/www/ksystem/lib/zendframework-1.7.1/'

. PATH_SEPARATOR . get_include_path());



ZCompile::make( 'd:/www/project/lib/zendframework-1.7.1/Zend.compiled.phplib' ,

array( 'Zend/Auth/' , 'Zend/Acl/' ),

'd:/www/ksystem/lib/zendframework-1.7.1/'

);

?>




* This source code was highlighted with Source Code Highlighter .








したがって、ZCompileクラス自体(コメントに誤りはありません。これは主なことではありません!それらを修正する時間はありませんでした;):

<?php

/**

* ZendFramwork .

*

* @author Nod nodkz.at.mail.ru

*/

class ZCompile

{

static private $path;



/**

* , require/include,

*

* @param string $dest

* @param string $includes ZF

* @return array

*/

public static function make($dest, array $add_includes = array(), $path = '' )

{

self::$path=$path;

$includes=array_merge($add_includes, self::_scanFolderFiles($add_includes), self::_getZendIncludes());



//

foreach ($includes as $key=>&$ value ) {

if (substr($ value ,0,1)== '/' ) {

$includes[$key] = substr($ value ,1);

}

}



//

$ordered_include=Array();

foreach ($includes as $class_file) {

self::_getClassOrderIncludes($class_file, $ordered_include);

}



// '<?php' '? >', , require/include[_once]

//

$pattern[] = '%(^\<\?php|\?\>$)%m' ;

$replacement[] = '' ;

$pattern[] = '%/\*.*?\*/%sm' ;

$replacement[] = '' ;

//$pattern[] ='%//.*$%m';

//$replacement[] = '';

$pattern[] = '%(require_once|include_once|require|include) [("\'](.*?)[)"\'];%sm' ;

$replacement[] = '' ;

$pattern[] = '%(\n){2,}%' ;

$replacement[] = "\n" ;



$body = "<?php\n" ;

$worked_classes = Array();

foreach ($ordered_include as &$fname) {

if (!in_array($fname, $worked_classes)) {

$worked_classes[] = $fname;



$fname = self::$path.$fname;

if (@file_exists($fname)&&is_file($fname)) {

$body.= "/*** FILE: " .$fname. " ***/ \r\n" ;

$body .= preg_replace($pattern, $replacement, file_get_contents($fname, true ));

}

}

}



$size = file_put_contents($dest, $body);



return array( 'includes' => $includes, 'compiledBody' => $body, 'compiledSize' => $size);

}



/**

* (.. /).

* php , ( ).

*

* @param array $add_includes

* @return array

*/

private static function _scanFolderFiles(&$add_includes) {

$add_includes_dirs=array();

foreach ($add_includes as $key=>$elem) {

if (substr($elem,-1)== '/' ) {

if (is_dir(self::$path.$elem)) {

if ($dh = opendir(self::$path.$elem)) {

while (($file = readdir($dh)) !== false ) {

if (strpos(strtolower($file), '.php' )!== false ) {

$add_includes_dirs[]=$elem.$file;

}

}

closedir($dh);

}

}

$add_includes[$key]= '' ;

}

}

return $add_includes_dirs;

}



/**

* , .

*

* @param string $fname

* @param array &$already_included

*/

private static function _getClassOrderIncludes($class_filename, array &$already_included=Array(), array &$stack=Array()) {

//

if (!in_array($class_filename, $stack)) {

array_push($stack, $class_filename);

} else {

if (!in_array($class_filename, $already_included)) {

$already_included[]=$class_filename;

}

return ;

}



//

if (is_file(self::$path.$class_filename) && !in_array($class_filename, $already_included)) {

$class_file_content = file_get_contents(self::$path.$class_filename, true );



//

// .. extends implements,

//

if (preg_match_all( '/class\s+[_\w]+\s+(extends|implements)\s+([_\w]+)/i' , $class_file_content, $arr)) {

foreach ($arr[2] as $new_class_name) {

$new_class_path = str_replace( '_' , '/' ,$new_class_name). '.php' ;

if (!in_array($new_class_path, $already_included)) {

self::_getClassOrderIncludes($new_class_path, $already_included, $stack);

}

}

}



//

if (preg_match_all( '%(require_once|include_once|require|include) [("\'](.*?)[)"\'];%sm' , $class_file_content, $arr)) {

//

foreach ($arr[2] as $new_class_path) {

// , ,

if (!in_array($new_class_path, $already_included) && !in_array($new_class_path, $stack)) {

//

if (strpos($new_class_path, '$' )=== false ) {

// ,

self::_getClassOrderIncludes($new_class_path, $already_included, $stack);

}

}

}

}

if (!in_array($class_filename, $already_included)) {

$already_included[]=$class_filename;

}

}



array_pop($stack);

}



/**

* ZF

*

* @return array

*/

private static function _getZendIncludes()

{

$required = array();

$included_files = get_included_files();

$included_files;

foreach ($included_files as $fname) {

$fname = str_replace( '/' , '\\',$fname);



if (!(strpos($fname, '
\\Zend\\ ') > 0) || (strstr($fname, __CLASS__ . ' .php '))) {

continue;

}



$required[] = str_replace('
\\ ', ' / ', substr($fname, strpos($fname, ' \\Zend\\'), strlen($fname)));

}



return array_unique($required);

}

}

?>




* This source code was highlighted with Source Code Highlighter .








クラスをダウンロードする



健康に使用してください。



All Articles