フレームワークを自作しており、クラスを作成する機能があります。classA に classes と呼ばれるプロパティがある場合、classA は、key=className および value=classInstance の配列である classes プロパティに含まれるすべてのクラスを必要とすることを意味します。
つまり、このクラスがロードされた場合、foo および biz インスタンスが作成され、null がそれらに置き換えられます。
class foo
{
public $classes=array('bar'=>null, 'biz'=>null);
}
私のフレームワークは、依存関係が 1 つしかない場合は正常に動作しますが、依存関係が複数ある場合は、配列の最後の 1 つだけが正常に読み込まれます。残りはfalseに設定されています=/エラーのあるプロパティにメッセージを設定する必要があるため、これは不可解ですが、そうではありません...
とにかく、ここはローディングとエラーを処理するメインクラスで、クラスを作成するメソッドは create() です。
<?php
session_start();
class yamiko
{
public $paths=array
(
'php'=>'_php/',
'js'=>'_js/',
'css'=>'_style/',
'template'=>'_template/'
);
public $url=null;#defined in constructor
public $classes=array();
private $errors=array();
private $warnings=array();
/*
* define $this->url
* @RETURN: none
*/
public function __construct()
{
$this->url=urlencode($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]);
}
###################
##### CLASSES #####
###################
/*
* create a class instance
* @RETURN OBJECT||false: returns reference to object of false if failed
* @PARAM $class STRING: path and class name.
*/
public function &create($class, $php=false, $c=0)
{
#check if php class
if($php)
{
#make instance
if(!$this->get_class($class))
{
$this->classes[$class]=new $class;
}
return $this->classes[$class];
}else#non php class
{
$path=$class;
$pos=strrpos($path, '/');
$class=substr($path, $pos+1);
$path=substr($path, 0, $pos+1);
if($this->get_class($class))
return $this->classes[$class];#return existing class
if(file_exists($path.$class.'.php'))
{
include_once($path.$class.'.php');
} else
{
$this->set_error("unable to include $path$class");
return false;
}
$this->classes[$class]=new $class;
#get required classes for class
if(property_exists($this->classes[$class], 'classes'))#if class has a classes property
{
foreach($this->classes[$class]->classes as $k=>$v)
{
$required_class=$this->get_class($k);#check if it already exist
if(!$required_class)
{
$required_class=&$this->create($path.$k, false, $c+1);
if(!$required_class)
{
$this->set_error("Class $class requires class $k");
return FALSE;
}
}
$this->classes[$class]->classes[$k]=&$required_class;
}
}
return $this->classes[$class];
}
}
/*
* gets a references to a class or returns false
* @RETURN OBJECT||false: returns reference to class or false if not found
*/
public function &get_class($class)
{
if($this->classes[$class] instanceof $class)
return $this->classes[$class];
$this->set_warn("$class does not exist");
return false;
}
###################
##### ERRORS ######
###################
public function set_error($e)
{
$this->errors[]=$e;
}
public function get_error($r)
{
if(empty($this->errors))
return false;
switch ($r)
{
case 'html':
$html='<ul>';
foreach($this->errors as $k=>$v)
{
$html.="<li><b>ERROR $k:</b> $v </li>";
}
$html.='</ul>';
return $html;
break;
default:#array
return $this->errors;
break;
}
}
####################
##### WARNINGS #####
####################
public function set_warn($w)
{
$this->warnings[]=$w;
}
public function get_warn($r)
{
if(!empty($this->warnings))
return false;
switch ($r)
{
case 'html':
$html='<ul>';
foreach($this->warnings as $k=>$v)
{
$html.="<li><b>WARNING $k:</b> $v </li>";
}
$html.='</ul>';
return $html;
break;
default:#array
return $this->warnings;
break;
}
}
################
##### DEBUG ####
################
public function debug($msg, $r)
{
if(!is_string($msg))
{
$this->set_error('yamiko->debug msg is not a string');
return false;
}
if($msg!='li'&&$msg!='br'&&$msg!='h1'&&$msg!='h2'&&$msg!='h3')
{
$this->set_error('yamiko->debug PARAM $r must be li, br, h1, h2, or h3');
return false;
}
switch($r)
{
case 'li':
echo "<li>$msg</li>";
break;
case 'br':
echo "$msg<br />";
break;
case 'h1':
echo "<h1>$msg</h1>";
break;
case 'h2':
echo "<h2>$msg</h2>";
break;
case 'h3':
echo "<h3>$msg</h3>";
break;
}
}
}
global $yamiko;
$yamiko=new yamiko;
$GLOBALS['yamiko']=&$yamiko;
?>
ロードしようとしているクラスは以下のように設定され、最初のクラスのみがロードされます。順序を入れ替えると、再びファースト クラスのみがロードされます。
<?php
class account
{
public $classes=array
(
'yamiko_mysqli'=>NULL,
'yamiko_encrypt'=>NULL
);
}
?>