İşte tam açıklanmıştır:
Eğer class_exists
kullanmak ve ikinci argüman olarak true
geçmesi ardından, bir sınıf örneğini olup olmadığını kontrol etmek istiyorsanız
(ya da dışarıda bırakın,
true
varsayılan) otomatik yükleme, ad alanları desteği, durağan olmayan örneklerden (değişken yollar ile), yükleme hatalarının ve özel istisnaların işlenmesini gösteren fabrika nesnesi.
abstract class AbstractFactory implements \ArrayAccess
{
protected $manifest;
function __construct($manifest)
{
$this->manifest = $manifest;
}
abstract function produce($name);
public function offsetExists($offset)
{
return isset($this->manifest[$offset]);
}
public function offsetGet($offset)
{
return $this->produce($offset);
}
//implement stubs for other ArrayAccess funcs
}
abstract class SimpleFactory extends AbstractFactory {
protected $description;
protected $path;
protected $namespace;
function __construct($manifest, $path, $namespace = "jj\\") {
parent::__construct($manifest);
$this->path = $path;
$this->namespace = $namespace;
if (! spl_autoload_register(array($this, 'autoload'), false)) //throws exceptions on its own, but we want a custom one
throw new \RuntimeException(get_class($this)." failed to register autoload.");
}
function __destruct()
{
spl_autoload_unregister(array($this, 'autoload'));
}
public function autoload($class_name) {
$file = str_replace($this->namespace, '', $class_name);
$filename = $this->path.$file.'.php';
if (file_exists($filename))
try {
require $filename; //TODO add global set_error_handler and try clause to catch parse errors
} catch (Exception $e) {} //autoload exceptions are not passed by design, nothing to do
}
function produce($name) {
if (isset($this->manifest[$name])) {
$class = $this->namespace.$this->manifest[$name];
if (class_exists($class, $autoload = true)) {
return new $class();
} else throw new \jj\SystemConfigurationException('Factory '.get_class($this)." was unable to produce a new class {$class}", 'SYSTEM_ERROR', $this);
//an example of a custom exception with a string code and data container
} else throw new LogicException("Unknown {$this->description} {$name}.");
}
function __toString() //description function if custom exception class wants a string explanation for its container
{
return $this->description." factory ".get_class($this)."(path={$this->path}, namespace={$this->namespace}, map: ".json_encode($this->manifest).")";
}
}
ve son olarak bir örnek
:
namespace jj;
require_once('lib/AbstractFactory.php');
require_once('lib/CurrenciesProvider.php'); //base abstract class for all banking objects that are created
class CurrencyProviders extends SimpleFactory
{
function __construct()
{
$manifest = array(
'Germany' => 'GermanBankCurrencies',
'Switzerland' => 'SwissBankCurrencies'
);
parent::__construct($manifest, __DIR__.'/CurrencyProviders/', //you have total control over relative or absolute paths here
'banks\');
$this->description = 'currency provider country name';
}
}
şimdi yapmak
$currencies_cache = (new \jj\CurrencyProviders())['Germany'];
veya
$currencies_cache = (new \jj\CurrencyProviders())['Ukraine'];
LogicException("Unknown currency provider country name Ukraine")
hiçbir yoksa/CurrencyProviders/in SwissCurrencies.php dosyası, yeterli çaba ile
\jj\SystemConfigurationException('Factory jj\CurrencyProviders was unable to produce a new class banks\SwissCurrencies. Debug data: currency provider country name factory jj\CurrencyProviders(path=/var/www/hosted/site/.../CurrencyProviders/, namespace=banks\, map: {"Germany": "GermanBankCurrencies", "Switzerland":"SwissBankCurrencies"}')
bu fabrika hataları (How to catch error of require() or include() in PHP?) ayrıştırması yakalamak ve kurucular argüman geçmek uzatılabilir.
Tam olarak ne olur? Sadece başarısız olduğunu söyledin, ama nasıl başarısız olduğunu değil. – Charles
Yukarıdaki kod çağrıldığında, bir istisna belirtisi yoktur, bunun yerine standart bir "Önemli hata: Sınıf 'foobarDomain', bla içinde bulunamadı" standardı alıyorum. Ve betiğin yürütülmesi sona erer. – clops
Harika, teşekkürler. İşe alınmadan önce istisna ilk şey işlevine bastığınızda ne olur? – Charles