
影響力の新しいメソッドを追加できるクラスを使用して、後で使用できるようにします。 同時に、これらのメソッドを異なるファイルに分離します。
以下を使用する宇宙船を想像してください。
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つのファイルの初期化は、モジュールが初期化される最初に発生します。
ファイルは異なって設定できます。 たとえば、サイトの異なるページ(異なるモジュールを使用)で異なるphpcacheファイルを使用しています。mods()->cache( 'cache.data' )
->phpcache( 'cache.php' );
すべてのファイルを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 .
健康に使用してください。