Senin tek endişe plugin1 dahil değil bir hata yaratacak ise, o zaman otomatik plugin2 yük plugin1 var hakklı için çare olabilir:
PHP Manual on spl_autoload olarak yorumlardan
// Your custom class dir
define('CLASS_DIR', 'class/')
// Add your class dir to include path
set_include_path(get_include_path().PATH_SEPARATOR.CLASS_DIR);
// You can use this trick to make autoloader look
// for commonly used "My.class.php" type filenames
spl_autoload_extensions('.class.php');
// Use default autoload implementation
spl_autoload_register();
Ancak, bir özellikleri / mixin-gibi özelliği arıyorsanız, eğer, o zaman cevap hayır. PHP şimdi bu desteklemez. En az not without patching the core veya üretim kodunda kullanmak istemiyorum these two API'leri başvuruyorlar.
Bir nesne zamanında nasıl davrandığını değiştirmek için doğru yolu kullanmak olacaktır Decorators:
$class = new BasicCache( new BasicValidators ( new Basic ) );
ya da Strategy desenler
$class = new Basic;
$class->setStrategy(function() { return 'foo'} );
echo $class->callStrategy(); // foo
$class->setStrategy(function() { return 'bar'} );
echo $class->callStrategy(); // bar
http://sourcemaking.com/design_patterns, en yaygın modeller için bkz.
EDIT İşte dekoratörler ile eklentileri oluşturmak için nasıl bir örnektir. Bazı olmayan oyuncu karakterleri sanal uzayda dolaşmak ve zaman zaman ana karakteri selamlıyorum çeşit bir oyun var, varsayalım. Yani şimdi yapmak hepsi bu. Biz onlar biz bu senaryoda bizim eklentileri / dekoratörler ihtiyaç neden olsa da, hangi selamlıyorum nasıl bazı varyasyon istiyorum.
İlk create an interface o selamlamak mümkün herhangi bir nesne olması gereken bazı yöntemler tanımlar. Biz bu yöntemler, belirli bir nesne üzerinde çağrıldığında ne yapar umurumda değil. Biz sadece emin yöntemleri mevcuttur olduklarını ve açıkça tanımlanmış bir girişi ile denir ki yapmak istiyorum:
interface GreetInterface
{
public function greet($name);
public function setGreeting($greeting);
}
Bir arabirim temelde herhangi bir uygulama bir nesne yerine getirmelidir bir sözleşmedir. Eğer selamlıyorum bir nesne varsa bizim durumumuzda, sözleşme diyor, siz iki yöntem olmalıdır. Bunları istediğiniz herhangi bir şekilde uygulamak, ancak bu yöntemler var.
Kullanıcı bu arabirimi uygulayan, şimdi bizim olmayan oyuncu karakter sınıfları inşa edelim
class Dude implements GreetInterface
{
protected $greeting = 'hello';
public function greet($name)
{
return sprintf('%s %s', $this->greeting, $name);
}
public function setGreeting($greeting)
{
$this->greeting = $greeting;
return $this;
}
}
Bu oldukça sanırım straigtforward oluyor. Dostum sınıfı sadece arabiriminden iki yöntemi tanımlar. Selamlıyorum () çağrıldığında, bu selamlıyorum yönteme geçirilen param tebrik depolanan dize ve prepend almak olacaktır. SetGreeting yöntem bize zamanında tebrik değiştirmenizi sağlar. Note: you could add a getter as well (I was just lazy)
Şimdi eklentileri üzerinde. Bizim gerçek eklentileri kod çoğaltmak istemiyorum çünkü biz, bazı shared boilerplate code içeren soyut bir GreetPlugin sınıf oluşturmak olacaktır. Soyut eklentisi sınıfı GreetInterface uygulayacak, böylece tüm alt sınıfları çok arabirimi uygulamak emin olabilirsiniz.
Dostum zaten de arabirimini uygulayan yana, eklentileri Dude genişletmek olabilir, ama uzanan bir is-a ilişkisi oluşturur, ama bir eklenti bir Dostum değil, çünkü bu, kavramsal yanlış olur.
abstract class GreetPluginAbstract implements GreetInterface
{
protected $inner;
public function __construct(GreetInterface $inner)
{
$this->inner = $inner;
}
public function setGreeting($greeting)
{
$this->inner->setGreeting($greeting);
return $this;
}
public function greet($name)
{
return $this->inner->greet($name);
}
}
GreetInterface uygularken herhangi bir sınıf: eklentisi sınıfı başlatıldı tek argüman kabul eder. TypeHint Emin, sınıf ahdine vefa yapar. Eğer kodda görebileceğiniz gibi, bizim eklentileri yapıcısı geçti sınıf arayüzü yöntemleri çağırmak gerekir, çünkü bu, gerekli oluyor. Biz Dude uzatıldı olsaydı, biz şimdi biraz garip olan, ahbaplar içine dudes sarmak mümkün olacaktır. Bunu yapmamak için bir başka neden.
Şimdi ilk eklenti üzerinde. Biz çocuklardan bazıları biryere aksan kullanımı anlamına gelen bir fantezi Fransız aksanı ile konuşmak istiyorum, ancak uygun bir h telaffuz edemez. Disclaimer: yes, I know that's a cliche. Please bear with my examples
class FrenchPlugin extends GreetPluginAbstract
{
public function greet($name) {
return str_replace(array('h', 'e'), array('', 'é'),
$this->inner->greet($name));
}
}
Plugin soyut eklenti uzanır yana, biz şimdi normal bir dostum Selamını yapacağını nasıl değiştirir gerçek kodu odaklanabilirsiniz. Selamlıyorum () çağrıldığında, biz sarılı elemanına () selamlıyorum ve sonra da tüm h karakterleri kaldırmak ve tüm es es içine çevirmek diyoruz. Her şey değiştirilmemiş soyut davranıştır.
Başka bir eklenti, biz tebrik ifadeleri değiştirmek istiyorsanız, bu yüzden bazı ahbaplar yerine sadece Hello Heya, demek var. Sadece bazı değişim eklemek.
class EasyGoingPlugin extends GreetPluginAbstract
{
protected $inner;
public function __construct(GreetInterface $inner) {
$this->inner = $inner->setGreeting('heya');
parent::__construct($inner);
}
}
Selamlıyorum yöntem sadece o olacak ne olursa olsun dönmek gerekir, çünkü bu şekilde biz sadece, kurucu geçersiz kılar. Bu yüzden bu eklenti geçirilen nesne üzerinde setGreeting yöntemi diyoruz. Nesne GreetInterface uygulamak zorundadır, çünkü biz bu çalıştığından emin olabilirsiniz.
Ben iç nesne olarak setGreeting dönüş değeri atama ediyorum unutmayın. Ben $ this dönmek çünkü setMethod denir zaman bu mümkündür. Bu arayüz üzerinden zorunlu olamaz, bu yüzden bu forma arayüz güvenemezsiniz. method chaining: Ben sadece başka bir tekniği göstermek için eklendi.
İki eklentileri bitmiş, biz yeterince farklılık var hissediyorum. Şimdi sadece Dudes oluşturmak için uygun bir yol gerekir. Bunun için bu gibi küçük bir sınıf oluşturmak:
class DudeBuilder
{
public static function build()
{
$dude = new Dude();
$decorators = func_get_args();
foreach($decorators as $decorator) {
$decorator .= "Plugin";
// require_once $decorator;
$dude = new $decorator($dude);
}
return $dude;
}
}
Note: I always mix up Builder and AbstractFactory, so if the above is a Factory, well, then it's a factory. Check out the design patterns links I gave earlier on ;)
Bütün bu Builder, düzenli bir ahbap oluşturmak ve sonra sarmak / biz onu kullanmak anlatmak ve geri daha ne eklentileri ile / onu içine dekore edilir gelmez. Oluşturucu hayır kendi devletini kapsüller, çünkü biz inşa yöntemi statik yapmak.
Bu örnek için ben sana sağ üst verdi autoloading kodu kullanmış varsayalım. Değilse, sen foreach döngüsünde eklenti dosyaları içerebilir. Onlar yalnızca gerektiğinde tembel onları yükleme üstüne hepsini içeren üzerinde size birkaç mikrosaniye daha hızlı yükleme süreleri verecektir. Umarım, bu da ben davranış, bir dosya ekleme ile kontrol edilmemelidir savundu zaman çeşitli yorumlar ne anlama geldiğini açıklıyor. Dosya dahil sadece bir zorunluluktur. PHP bilmiyor bir sınıf kullanamazsınız. Ama gerçekten sınıfı kullanıldığı, yapı yöntemine eklenti isimleri geçerek, tek başına bizim kod tarafından kontrol edilir.
Şimdi bunu yapalım
$regularDude = DudeBuilder::build();
$frenchDude = DudeBuilder::build('French');
$easygoingDude = DudeBuilder::build('EasyGoing');
$frenchEasyGoingDude = DudeBuilder::build('French', 'EasyGoing');
Bu, etkili bir yapıyor olarak aynıdır:
$regularDude = new Dude;
$frenchDude = new FrenchPlugin(new Dude);
$easygoingDude = new EasyGoingPlugin(new Dude);
$frenchEasyGoingDude = new FrenchPlugin(new EasyGoingPlugin(new Dude));
Sadece iki eklentileri ile, biz şimdi Dudes üç tür oluşturabilirsiniz. Bırakalım selamlıyorum atalım:
echo $regularDude->greet('Yuri'), PHP_EOL,
$frenchDude->greet('Yuri'), PHP_EOL,
$easygoingDude->greet('Yuri'), PHP_EOL,
$frenchEasyGoingDude->greet('Yuri'), PHP_EOL;
// gives
hello Yuri
éllo Yuri
heya Yuri
éya Yuri
Biz şimdi temel sınıfları süslemek için ek eklentileri oluşturabilirsiniz. Nedense, sizin oyun olarak iyi at veya araba konuşurken olmalıdır karar verirseniz, aynı zamanda bir sınıf Araba veya Atı oluşturmak ve çok selamlıyorum arabirimini uygulayan ve onlar için bir Builder eklemek olabilir. Daha sonra Fransız EasyGoing Otomobil veya Horses oluşturmak için eklentileri yeniden kullanabilirsiniz.