モジュールを操作する

チャレンジ:

影響力の新しいメソッドを追加できるクラスを使用して、後で使用できるようにします。 同時に、これらのメソッドを異なるファイルに分離します。

以下を使用する宇宙船を想像してください。

a)モーター関連の空間ナビゲーション方法

b)ソーラーパネルに関連するエネルギー充電方法

c)など



オプションがあります:

1)オブジェクトに変数を作成し、新しいクラスのように__constructを使用して変数を初期化します。

しかし、新しいオブジェクトを作成するたびに、パフォーマンスが低下し、クラスが常に変更されます(複数のプログラマの作業が複雑になる可能性があります)。

2)関数__call、__ get、__ setを使用します。

これらの機能の3〜10倍遅い動作。 特に、パラメーターを指定してcall_user_func_arrayを呼び出す場合。



オプションを提供します。

高速で最適化されていますが、デバッグはほとんど困難ではありません。



このhabratopikaでは、トピックについて触れます。

1.オーバーロード

2.モジュールのロードを高速化します。 モジュールの関連付け。

3.最適化



代替アプローチ



同じクラスを1つにマージしながら、すべてのモジュールを1つのファイルに結合できます。



このために、少し後で分析するモジュールを作成しました。



モジュールを操作するには、モジュールを使用します(シングルトンパターンと同様) -mods関数。 モジュールを初期化し、次のようになります。

/**

* modules

*

* @return <modules> -

*/



function mods(){

static $mod;

if (!isset($mod))

$mod= new modules;

return $mod;

}






結合モジュールの場合、2つのキャッシュファイルが使用されます。



接続されたすべてのクラスを(シリアル化形式で)保存するには、そのうちの1つが必要です。 それらのうち、__autoload関数を使用して、作業に必要な必要なものが選択されます。

2番目のファイルは、phpファイルにマージされたすべての必要なモジュールです。 すべてのモジュールではなく、ロードするだけです。



これらの2つのファイルの初期化は、モジュールが初期化される最初に発生します。

mods()->cache( 'cache.data' )

->phpcache( 'cache.php' );




ファイルは異なって設定できます。 たとえば、サイトの異なるページ(異なるモジュールを使用)で異なるphpcacheファイルを使用しています。



すべてのファイルを1つに結合することにより、ファイルのダウンロードが高速になります。 (さらに、ファイルがすぐにダウンロードされるように、eAcceleratorをインストールすることをお勧めします)



ただし、システムにロードされるモジュールを追加する必要があります(これは単純なインクルードとして機能します)。

mods()->include_php( 'modules/mod1.php' );



最後に、モジュールを単一のファイルに変換してロードします。

mods()->include_modules();





モジュールの使用例

// ( )

define ( 'PHP_DEBUG_MODE' ,1);



// php-

mods()->cache( 'cache.file' )

->phpcache( 'cache.php' );



//

if (PHP_DEBUG_MODE==1){

$files = glob($moddir. '/*.inc' );

foreach ($files as $file){

mods()->include_php($file);

}



//

mods()->include_modules();






PHP_DEBUG_MODEを定義することに注意を払いたいです。 毎回変更をチェックするためのすべてのモジュールを研究するために-必要はありません。 したがって、内部モジュールが変更されない場合、このチェックを無効にして( PHP_DEBUG_MODEを0に設定)、必要なすべてのクラスを含む接続準備が整ったcache-php-module(include_modules)のみを残すことができます。



何が起こる

1)クラスのマージ。

//file_A.php

class A{

public $start;



function start(){

$ this ->start=1;

}

}




//file_B.php

class A{

private $stop;



function stop(){

$ this ->stop=1;

}

}




結果:

//result_cache.php

class A{

public $start;

private $stop;



function start(){

$ this ->start=1;

}



function stop(){

$ this ->stop=1;

}

}








2)クラス内の関数のマージ

//file_A.php

class A{

public $start;



function __construct(){

$ this ->start=1;

}

}




//file_B.php

class A{

public $stop;



function __construct(){

$ this ->stop=1;

}

}




結果:

//result_cache.php

class A{

public $stop;

public $start;



function __construct(){

$ this ->stop=1;

$ this ->start=1;

}

}








実装



/**

*

*

* @param <string> $class -

*/



function __autoload($ class ){

mods()->putclass($ class );

}



/**

* modules

*

* @return <modules> -

*/



function mods(){

static $mod;

if (!isset($mod))

$mod= new modules;

return $mod;

}



class modules{

private $dataclass=array();

private $datacache_date=0;

private $datacache_name= null ;

private $classesfile= null ;

private $classesfiledate=0;

private $classesincluded= false ;



/**

*

*

* @param <string> $file - +

*/



public function cache($file){

$ this ->datacache_name=$file;

if (file_exists($file)){

$ this ->datacache_date=filemtime($file);

}

return $ this ;

}



/**

* php-

*

* @param <string> $file - +

*/



public function phpcache($file){

$ this ->classesfile=$file;

if (file_exists($file))

$ this ->classesfiledate=filemtime($file);

}



/**

*

*

* @param <string> $file -

*/



public function include_php($file){

if (!file_exists($file)){

$ this ->fatalerror( 'no include file \'<b>' .$file. '</b>\'' );

}



if ($ this ->datacache_date<filemtime($file)){

$ this ->loadcachedata();

$ this ->removefile($file);

$ this ->parsephp(file_get_contents($file),$file);

file_put_contents($ this ->datacache_name,serialize($ this ->dataclass));

if ($ this ->classesfiledate!=0){

unlink($ this ->classesfile);

$ this ->classesfiledate=0;

}

}elseif ($ this ->classesfiledate!=0 && $ this ->classesfiledate<filemtime($file)){

unlink($ this ->classesfile);

$ this ->classesfiledate=0;

}



return $ this ;

}



/**

*

*/



public function include_modules(){

if (!$ this ->classesincluded){

if (!file_exists($ this ->classesfile)){

$ this ->loadcachedata();

file_put_contents($ this ->classesfile, "<?\n" .$ this ->printclass( '' ). "\n?>" );

}

include_once($ this ->classesfile);

$ this ->classesincluded= true ;

}

}



/**

*

*

* @param <string> $file -

*/



private function removefile($file){

foreach ($ this ->dataclass as $key=>&$ class ){

foreach ($ class [0] as $name=>$vars)

if ($name==$file)

unset($ class [0][$name]);

foreach ($ class [1] as $fk=>&$ function ){

foreach ($ function as $name=>$vars)

if ($name==$file)

unset($ function [$name]);

if ($ function ==array())

unset($ class [1][$fk]);

}



if ($ class [0]==array() && $ class [1]==array())

unset($ this ->dataclass[$key]);

}

}



/**

* PHP-

*

* @param <string> $class -

* @return <string> -

*/



private function printclass($ class = '' ){

if ($ class == '' ){

$ string =implode( "\n" ,$ this ->dataclass[ '' ][0]);

foreach ($ this ->dataclass[ '' ][1] as $fname=>$ function )

$ string .= "\nfunction " .$fname. "{\n" .implode( "\n" ,$ function ). "\n}" ;

return $ string ;

}



foreach ($ this ->dataclass as $classname=>$data){

$name=preg_split( '/\s/' , $classname);



if ($name[0]==$ class ){

$ string = 'class ' .$classname. '{' .implode( "\n" ,$data[0]);

foreach ($data[1] as $fname=>$ function )

$ string .= "\nfunction " .$fname. "{\n" .implode( "\n" ,$ function ). "\n}" ;



return $ string . '}' ;

}

}

return false ;

}



/**

* cache-

*/



private function loadcachedata(){

if ($ this ->dataclass!=array())

return ;



if (file_exists($ this ->datacache_name))

$ this ->dataclass=unserialize(file_get_contents($ this ->datacache_name));

}



private function classfiles($ class ){

foreach ($ this ->dataclass as $classname=>$data){

$name=preg_split( '/\s/' , $classname);



if ($name[0]==$ class ){

$keys=array();

foreach ($data[1] as $dat)

$keys=array_merge(array_keys($data[0]),$keys);

return implode( ", " ,array_unique(array_merge(array_keys($data[0]),$keys)));

}

}

}





/**

* .

* php-cache .

*

* @param <string> $class -

*/



public function putclass($ class ){

if (!$ this ->classesincluded){

$ this ->includemodules();

if (class_exists($ class , false ))

return ;

}



$ this ->loadcachedata();



if (($evclass=$ this ->printclass($ class ))!== false ){

file_put_contents($ this ->classesfile, "<?\n" .$evclass. "\n?>" ,FILE_APPEND);

chmod($ this ->classesfile,0777);

if (@eval($evclass)=== false ){

$ this ->fatalerror( 'Error in class <b>' .$ class . '</b> in file <b> ' .$ this ->classfiles($ class ). '</b>' );

}

}

}



/**

*

*

* @param <string> $classname -

* @param <array> $class -

* @param <string> $filename - ,

*/



private function mergeclass($classname,$ class ,$filename){

if (!isset($ this ->dataclass[$classname][0][$filename])){

$ this ->dataclass[$classname][0][$filename]= '' ;

}



$ this ->dataclass[$classname][0][$filename].=$ class [0];

if (!isset($ this ->dataclass[$classname][1]))

$ this ->dataclass[$classname][1]=array();



foreach ($ class [1] as $fname=>$ function ){

if (!isset($ this ->dataclass[$classname][1][$fname][$filename]))

$ this ->dataclass[$classname][1][$fname][$filename]= '' ;

$ this ->dataclass[$classname][1][$fname][$filename].=$ function ;

}

}



/**

* php ,

*

* @param <string> $php -

* @param <string> $filename -

*/



private function parsephp($php,$filename){

if (($pos=strpos($php, '<?' ))!== false ){

$pos+=2;

if (strtolower(substr($php,$pos,3))== 'php' )

$pos+=3;

}

if (!preg_match_all( '/((?:[^\'"\/$]|([\'"])(?:\\\\[\s\S]|[\s\S])*\2|\/[^*]|\/\*[\s\S]*\*\/|\$[^;\'"(){}\s]++)*)([{};]|\?>|$|\s(function)\s|\s(class)\s)/DSU' ,$php,$scobe,PREG_SET_ORDER|PREG_OFFSET_CAPTURE,$pos))

return ;



for ($i=0,$j=count($scobe);$i<$j;$i++){

if (isset($scobe[$i][5]) && $scobe[$i][5][0]== 'class' && $i<$j-1 && $scobe[$i+1][3][0]== '{' ){

//is class

$newclass=array( '' ,array());



for ($x=$i+2;$x<$j;$x++){

$test=&$scobe[$x][3][0];



if (isset($scobe[$x][4][0]) && $scobe[$x][4][0]== 'function' && $x<$j-1 && $scobe[$x+1][3][0]== '{' ){



$name=$scobe[$x+1][1][0];

$ function = '' ;

for ($x+=2,$sco=1;$x<$j;$x++){

$test=&$scobe[$x][3][0];

if ($test== '{' )

++$sco;

elseif ($test== '}' )

if (--$sco==0)

break ;

$ function .=$scobe[$x][0][0];

}

if ($x==$j)

$ this ->fatalerror( 'error parsing function' .$name. ' in class <b>' .$scobe[$i+1][1][0]. '</b>, not found }' );



$newclass[1][$name]=$ function ;

}elseif ($test== ';' )

$newclass[0].=$scobe[$x][0][0];

elseif ($test== '}' )

break ;

else $ this ->fatalerror( 'error parsing ' .$test. ' in class <b>' .$scobe[$i+1][1][0]. '</b>' );

}



$ this ->mergeclass($scobe[$i+1][1][0],$newclass,$filename);



$i=$x;

} else {

if ($scobe[$i][3][0]== '?>' )

$ this ->mergeclass( '' ,array($scobe[$i][1][0],array()),$filename);

else

$ this ->mergeclass( '' ,array($scobe[$i][0][0],array()),$filename);

}

}

}



/**

*

*

* @param <string> $error -

*/



private function fatalerror($error){

trigger_error($error. "<br/>\n" , E_USER_ERROR);

die();

}

}




* This source code was highlighted with Source Code Highlighter .






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



All Articles