PHP referans sayım

4 Cevap php

Ben başvuru sayıları üzerinde PHP tabanlı veritabanı önbelleğe alma işlevselliğini uygulamak istiyorum. Örneğin, foo 1 bir kimliği ile tablo kayıt erişmek için kod gibi görünebilir:

$fooRecord = $fooTable->getRecord(1);

Bu denir ilk kez, $ FOOTABLE, veritabanından uygun kaydını getirir bir iç önbelleğe bunu saklar ve onu döndürür. GetRecord Herhangi sonraki çağrılar (1) bellekteki aynı nesneye başka referans dönecektir. It destructs zaman $ fooRecord $ FOOTABLE sinyal verir ve hiçbir kalan referanslar varsa, bu geri veritabanına herhangi bir değişiklik depolayan ve önbellekten kaldırır.

Sorun PHP'nin bellek yönetimi referans sayıları hakkında ayrıntılı uzakta soyutlayan olmasıdır. Ben bunu bir uzantısı için PECL'de ve Google arandı, ancak bir sonuç yok buldum. Yani soru # 1: Böyle bir eklenti mevcut mu?

Alternatif bir yaklaşım olarak, $ FOOTABLE bir süper-gizli sahte nesnesi döndürür. Bu __ () çağrısı, __ set () ileterek kayıt gibi davrandığı ve __ get () ve onun yapıcı ve yıkıcı referans sayma amaçlı uygun kanca sağlar. Testler, bu tip ipuçlarını sonları dışında, harika çalışıyor. Ben yok ki, every one of my tables için Sneaky boş bir alt sınıf oluşturma gibi hissediyorum eğer bir FooRecord nesneyi bekliyorduk tüm yöntemleri artık Sinsi bir nesne olsun, ya da belki bir FooSneaky. Ayrıca, ben (benim gibi) bakım programcılar karıştırmayın korkuyorum.

Soru 2: Ben kaçırdım başka bir yaklaşım var mı?

4 Cevap

PHP5 için, sadece kayıt sınıfta yıkıcı faydalanmak.

class Table {
    /* [...] */
    protected $record_cache = array();
    public function getRecord($id) {
        if(isset($this->record_cache[$id]) return $this->record_cache[$id];

        $r = $db->getRecord($id);
        if($r instanceof Record) {
            $this->record_cache[$id] = $r;
        }
        return $r;
    }

    public function _unregister($id) {
        unset($this->record_cache[$id]);
    }
}

class Record {
    /* [...] */
    function __destruct() {
        this->table->_unregister($this->id);
    }
}

Eğer Tablo bunun için bir ortak yöntem olmasını istemiyorsanız, muhtemelen bazı geri hile ya da diğer bazı zeki kesmek kullanabilirsiniz :)

PHP basit önbellek uygulamaları bakmak mı? Örneğin, gibi bir şey kullanarak Zend_Cache:

public function getRecord($id) {
     $cache = $this -> getCache(); //Retrieves an instanced Zend_Cache object or creates one
     $key = $this -> _name . $id; //_name is the table name and with the ID create a unique key

     if(!$result = $cache->load($key)) { 
         //Cache miss, query database
         $result = $this -> query(...);
         $cache->save($result, $key);
     }
     return $result;
}

Kolayca bu önbelleğe alma fonksiyonelliğini kendiniz uygulamak, ya da Zend adlı gibi hazır bileşenini kullanabilirsiniz.

Standart İnternet Yardım Forumu İhtar: Ben tam olarak yapmak için çalışıyoruz anlamak olmayabilir.

Ben senin fikrin PHPs istek / yanıt döngüsü ile uyuyor emin değilim. Geleneksel (CGI, mod_php), bir PHP isteğin yaşam döngüsü gibi bir şey görünüyor

  1. Kullanıcı bir PHP sayfası için bir HTTP isteği yapar
  2. PHP sayfası (ve tüm dahil dosyaları) opt-koduna dönüşüyor
  3. Opt-kodu yürütüldüğünde
  4. Döngüsü tamamlandıktan sonra, everything is thrown away

Bu PHP az deneyimli programcıları ile pazarda çok iyi yaptı nedenlerinden biriydi. Hatta en horrendously kodlu uygulama yalnızca bir isteğin yaşam döngüsü için bir sunucu askıda kalabilir. HTTP ile bazı paralellikler vardır; PHP (çeşit) her isteği başka bir istek hakkında hiçbir şey biliyor gibi inşa edilmiştir.

Ben (örneğin, Zend Platformu kullanılır) hızlı-cgi dağıtım teknikleri ile aşina diye değilim, ama anladığım kadarıyla birden çok PHP süreçler isteklerini işlemek için bellekte takılmak edecek, ve sonra öldürecek bazı sihirli voodoo o gidiş var kapalı ve yeniden yumurtlamaya süreçleri gerektiği gibi.

Tüm bu büyük nokta PHP nesneleri başvuru sayısı ile bellekte nerede takip etme fikri çok orada bulamadığınız neden PHPs isteği modeli ile mantıklı değil, olduğunu. PHP kullanıcı adasında Önbelleklenen sizin için bellek yönetimi ayrıntıları işlemek için memcached çizgisinde ayrı programlanabilir sistemi ya APC kullanarak anlamına gelir. Önbelleğe alma, basit bir anahtar / değer çifti depolama sistemi içine abstracted.

Eğer yaklaşım ile ileri basarsanız söyledi, ben sonuna sonuçlarını görme ilgi duyarım :)

Bu sizin bir çerçeve veya API ile bazı ORM isteyen gibi bana geliyor. Ben kullandım ama ADOdb yapar farkında değilim var. Alternatif CakePHP ORM kullanır ve gitmek için iyi bir yol olabilir.