Bir çiftleşmiş sınıf modeli nasıl

4 Cevap php

Benim kendi proje için bir temel çiftleşmiş sınıf yazıyorum. Temel kullanım şudur:

$template = new Template('template_file.php');
$template->assignVariable('pageTitle', 'Home page');
$template->render();

'Template_file.php' İçeriği:

<?php print $pageTitle; ?>

Bu şablon sınıf adım adım ne olduğunu:

  1. AssignVariable yöntemi denilen bir özel dizi Mağazaları değişkenler
  2. Yöntem, adı ekstreler değişkenler saklanan a ob_start() ve ob_end_clean() bloğunda şablon dosyası içerir hale zaman. ob_get_contents() ve ardından baskılar çıktı depolanmış olan bir değişkene Mağazaları çıktı.

Ben bu çok basit bir çiftleşmiş sınıf ama beklendiği gibi çalıştığını biliyorum. Soru Ben başka bir sınıfa şablon dosyası da dahil olmak üzere temsilci gerekir? Ben bu sınıf için birim testleri yazarken ben bu soru vardı. Ben dosya sistemi etkileşim kapsüllü gerektiğini düşündüm. Sen ne düşünüyorsun? Eğer, nasıl benim testlerde bir dosyaya dahil taklit edemez gerektiğini düşünüyorsanız?

Belki de sadece bu gibi sınıf şablon dosyasının içeriğini geçmek:

$templateContent = file_get_contents('template_file.php');
$template = new Template($templateContent);
...

Düzenleme: Ben daha iyi birim testleri ve kapsüllemeyi yazma uğruna şablon sınıfın giriş sürecini saklanması karar verdi. Johannes Ama çekti, ben doğru değil gibiydi bu amaç için eval() kullanmak gerekiyordu. Johannes ünite testleri dahil alay için akım sarmalayıcılarla yönünde beni işaret etti. Ama bu bana yeni bir ilham kaynağı olmuştur. İşte ben yapacağım budur; Benim şablon sınıfı include() kullanmaya devam edecek, ancak akım sarmalayıcılarla bu sefer. Başlatılıyor iken benim şablon sınıf protokol işleyicisi geçecek. Bu şekilde ben veritabanından şablon veri alma veya yerel bir değişken kullanarak benim kendi akışı korumalar oluşturabilirsiniz. Burada örnek olarak şunları verebiliriz:

$template = new Template('file://template_file.php');

stream_wrapper_register('database', 'My_Database_Stream');
$template = new Template('database://templates/3'); // templates table, row id 3

stream_wrapper_register('var', 'My_Var_Stream');
$myTemplate = '<?php print "Hello world!"; ?>';
$template = new Template('var://myTemplate');

Zaten yerel değişkenler için özel akışı sarıcı uygulamak var. İşte:

class My_Var
{
    protected $position;
    protected $variable;
    function stream_open($path, $mode, $options, &$openedPath) {
        $url = parse_url($path);
        global $$url['host'];
        $this->variable = $$url['host'];
        $this->position = 0;

        return true;
    }
    public function stream_read($count) {
        $ret = substr($this->variable, $this->position, $count);
        $this->position = strlen($ret);
        return $ret;
    }
    public function stream_eof() {
        return $this->position >= strlen($this->variable);
    }
}


stream_wrapper_register('var', 'My_Var');
$myvar = '<?php print "mert"; ?>';
include 'var://myvar';
exit;

4 Cevap

File_get_contents () ve bu tür kullanarak içeriklerini ileterek birden fazla şekillerde kötü yürütme için eval () kullanmak zorunda. Burada en uygun biri bir opcode önbellek sonra dosyayı önbelleğe edemezler. Bir ('template_file.php') içerir yapıyor; diyelim APC veya başkalarının derlenmiş komut önbelleğe.

Ben her zaman bu adam yaklaşımını sevdim:

http://www.massassi.com/php/articles/template_engines/

Bu yaklaşım PHP bir şablon motoru olarak başladığını aslında yararlanır. Gerçekten doğrudan cevap olmayabilir (yazarı da. Bunun aslında kendisi bir çiftleşmiş motoru olduğunda, PHP şişirilmiş bir şablon motoru yazmak için saçma olduğunu belirtiyor), ama belki size yardımcı olur.

Ne olursa olsun kullanan vs eval kötülüklerin bir soruyu cevaplamak için, ben senin çözümün I / O yönüyle saklanması için ayrı bir sınıf kabul ve kullanmak olurdu içerir.

Bu (çoğu durumda olacak gibi) overkill gibi görünebilir iken, bu muhtemelen sonra konum kontrolü / bağımlılık enjeksiyon izolasyonunu sağlamak için tek aklı başında yoludur.

Soru Ben başka bir sınıfa şablon dosyası da dahil olmak üzere temsilci gerekir?

Soru neden değil, değil mi?