PHP 5 - nesneleri seri ve ilişkilerini saklamak

3 Cevap php

Ben tek bir kullanıcı eylem birçok diğer alt sistemlerde değişiklikleri tetikleyebilir oldukça karmaşık bir PHP uygulamalarını yazıyorum ve ben bir gözlemci desen kullanarak niyetindeyim. Ben dahil bütün nesneleri yeniden oluşturmak zorunda Ancak, ben merak ediyorum.

Onların ilişkilerini saklamak için nesneleri seri iken mümkün mü? Örneğin

$equipmentHandler = new EquipmentHandler();
$character = new Character();
$character->subscribeOnEquipmentChanged($equipmentHandler);

$_SESSION['character'] = serialize($character);
$_SESSION['subscriber'] = serialize($equipmentHandler);

Ilişki unserializing sonrasında korunacak mı? Ya da ben bir nesne içine hepsini götürü do var?

$cache['character'] = $character;
$cache['subscriber'] = $equipmentHandler;
$_SESSION['cache'] = serialize($cache);

Herhangi bir tavsiye mutluluk duyacağız.

(Ps. karakter veri oluşturmak için birçok DB isteklerini gerektirir ve yine tefrika olacak bu yüzden, önbellek ve DB için bir yazma yaparak saklayarak düşünüyordum, ama sadece önbellek politika okumak am)

3 Cevap

Bir ilişki tutulacak, ancak bu beklediğinizden daha farklı olacaktır. Eğer ikisi de aynı EquipmentHandler bakın Karakter iki örneğini serialize zaman, yerine beklendiği tek biri, bu EquipmentHandler iki ayrı örneğini almak için gidiyoruz. Bu örnekte gösterildiği gibi:

<?php

echo "BEFORE SERIALIZE:\n";
class A { }
class B { }

$a = new A;
$b = new B;
$a -> b = $b;

$a2 = new A;
$a2 -> b = $b;

var_dump($a->b);
var_dump($a2->b);

echo "AFTER SERIALIZE:\n";
$a3 = unserialize(serialize($a));
$a4 = unserialize(serialize($a2));

var_dump($a3->b);
var_dump($a4->b);

Bu çıktı:

BEFORE SERIALIZE:
object(B)#2 (0) {
}
object(B)#2 (0) {
}
AFTER SERIALIZE:
object(B)#5 (0) {
}
object(B)#7 (0) {
}

Kiloluk sonra numara arayın. Bu PHP içinde nesne kimliği ifade eder. Aynı örneği: serializing önce hem $ a-> b ve $ a2-b> nesne kimliği # 2 ile bir nesneye bakın. Farklı örnekleri: Ama serileştirme sonra onlar IDS # 5 ve # 7 nesne bakın.

Bu, ya da olmayabilir, sizin için bir sorun olabilir.

Tek B nesnesine bağlantıyı geri yüklemek için, biraz zor almak zorunda olacak. "Ben B'ye bir başvuru vardı:" Sen B sadece bir anılması için B örneğine gerçek referansı düzleştirmek için A __ sleep () işleyicisi kullanabilirsiniz. Sonra yeni bir B nesnesi tek bir örneğini elde etmek için A, B örneğinin söz kullanarak __ wakeup () işleyicisi uygulamak.

BTW. PHP oturum uzantısı zaten otomatik olarak bunu kendiniz önceden seri için gerek seri hale geliyor :)

Serialize fonksiyonu kılavuzuna göre:

Değer Serileştirilecek. serialize () kaynak türü hariç, her türlü işler. Hatta () kendisine başvurular içeren diziler serileştirebilirsiniz. Eğer seri hale dizi / nesnenin içinde dairesel referanslar da saklanacaktır. Herhangi bir diğer referans kaybolacaktır.

Nesneleri seri hale getirilirken, PHP önce serileştirme __ sleep üye işlevi çağırmak için çalışacaktır. Bu nesne önce tefrika edildikten için herhangi bir son dakika temiz-up, vb yapmak için izin vermektir. Aynı şekilde, nesne unserialize kullanılarak restore edildiğinde () __ wakeup üye işlev denir.

Bu yüzden _sleep ve _wakeup akıllı bir şey yapmak sürece bu mümkün değil sanırım

Sizin aslında söz çözüm var! Daha karmaşık durumlarda __sleep ve __wakeup faydalanmak gerekebilir ... ama sağlanan bilgi verilmedi, yapmanız gereken tüm - Eğer önermek gibi - "Onları götürü hepsi bir nesne içine ".

Explanation

an answer to a similar question, ben söyledi:

Serileştirme "göreli" başvurular devam edecektir. (Teknik olarak, PHP göreceli başvuru gibi bir şey, ama kavramsallaştırma onun iyi bir yolu yoktur.)

Eğer serializing bir diziye başvurulan ve referans değişkenleri, toplamak eğer dizi referans ilişkiyi kurtaracak. Bu orijinal referansını korumak değil, ama otomatik olarak unserialize tarafından döndürülen yeni dizinin bağlamında onu yeniden oluşturacaktır. ... Bu nesnelerin iç başvuruları için aynı şekilde çalışır.

Example

// example objects
class A {}
class B {}
$a    = new A();
$b    = new B();
$b->a = $a;
// collect referenced and referencing objects in array
$cache = array( 'a' => $a, 'b' => $b );
// flatten and recreate cache (represents data stored & retrieved from db)
$cached = unserialize( serialize( $cache ) );
// overwrite local variables from cache
extract( $cached, EXTR_OVERWRITE );

Belirtmiş '$a ve $b->a için nesne kimlikleri iki '3 nasıl aşağıdaki çıktı var_dump( $a ); var_dump( $b->a );, haber, eğer Sonra, ikisi bakın aynı örneği A.

object(A)#3 (0) {
}
object(A)#3 (0) {
}