PHP: 'Nesneleri' $ _SESSION içinde depolama


188

Sadece $ _SESSION içinde nesneleri saklayabildiğimi anladım ve oldukça havalı buluyorum çünkü başka bir sayfaya atladığımda hala nesnem var. Şimdi bu yaklaşımı kullanmaya başlamadan önce bunun gerçekten iyi bir fikir olup olmadığını veya potansiyel tuzaklar olup olmadığını öğrenmek istiyorum .

Tek bir giriş noktam olsaydı bunu yapmam gerekmediğini biliyorum ama henüz orada değilim, bu yüzden tek bir giriş noktam yok ve gerçekten nesneyi korumak istiyorum çünkü ' Durumumu böyle kaybetme. (Şimdi vatansız siteleri de programlamam gerektiğini okudum ama henüz bu kavramı anlamıyorum.)

Yani kısacası : Bu oturumda mağaza nesnelere Tamam mı, onunla herhangi bir sorun olup?


Düzenle:

Geçici özet : Şimdiye kadar, veritabanını yeniden sorgulamayı içeriyor olsa bile, nesneyi yeniden oluşturmanın muhtemelen daha iyi olduğunu anlıyorum .

Başka cevaplar bu konuda biraz daha ayrıntılı olabilir !


13
2008'de nasıl 'aptal' oldum :-)
markus

49
'de bizim gibi aptallar için yararlı bir soru: D
Momin Al Aziz

3
Markus sorduğunuz çok güzel sorular .. :) Bugün okudum;)
gkd

1
Aptal değildin! Ne sormak üzere olduğumu sordun ve 10 yıl sonra bana sağlam bir şey yaptın!
toddmo

2019'da aptalca bir soru sormaktan beni kurtardığını tahmin ettim
Maxwell

Yanıtlar:


133

Bu konunun eski olduğunu biliyorum, ancak bu sorun ortaya çıkmaya devam ediyor ve memnuniyetime değinilmedi:

Nesneleri $ _SESSION içine kaydediyor ya da gizli form alanlarında saklanan verilere dayanarak tüm bezi yeniden yapılandırıyor ya da her seferinde DB'den yeniden sorgulıyor olsanız da, durumu kullanıyorsunuz. HTTP vatansızdır (az ya da çok; ancak GET'e karşı PUT'a bakın), ancak bir web uygulamasıyla herkesin umurunda olduğu hemen hemen her şey, devletin bir yerde tutulmasını gerektirir. Devleti köşe ve çatlaklara itmek gibi davranmak, bir çeşit teorik kazanım anlamına gelir. Devlet devlettir. Devlet kullanırsanız, vatansız olarak kazanılan çeşitli teknik avantajları kaybedersiniz. Bu önceden uyku kaybetmek gerektiğini bilmiyorsanız, uyku kaybetmek bir şey değildir.

Özellikle Hank Gay'in ortaya koyduğu "çifte vahşice" argümanların aldığı kutsamalarla doluyum. OP, dağıtılmış ve yük dengeli bir e-ticaret sistemi mi inşa ediyor? Benim tahminim hayır; ve ben de $ User sınıfının serileştirilmesi ya da her neyse, sunucusunu onarılamayacak şekilde sakat bırakmayacağım. Tavsiyem: uygulamanıza duyarlı teknikleri kullanın. $ _SESSION içindeki nesneler gayet iyi, sağduyu önlemlerine tabi. Uygulamanız aniden sunulan trafikte Amazon'a rakip bir şeye dönüşürse, yeniden uyum sağlamanız gerekir. Hayat bu.


16
Bunu okurken kendi düşüncelerimi bir araya getiren güzel cevap. Modern internetin devlete ihtiyacı var . Bazı uygulamaların durum bilgisi olmayan ve durumsuz bir şekilde yapılması mantıklı olmasa da, modern internet, vazgeçmek için devlete (AKA: Logins!) Dayalı çok fazla sisteme güveniyor! İnternetin Büyük Tanrıları bile bu temel kavramı yıllardır çerezler biçiminde birleştirmiş ve temel düzeyde bunu HTML'de yerel depolama biçiminde eklediler. Bazı uygulamalarda aşırı durum kullanımından kaçınmak mantıklı olabilir , ancak bazıları! = Hepsi!
Mart'ta RonLugge

Adamın ateşi icat etmesinden kısa bir süre sonra bu soruyu sorduğumda, bugün bildiğim pek çok şey bilmiyordum ... Bu arada birkaç iyi kullanım durumu olabileceğini söyleyebilirim, ancak genellikle önce başka çözümler ararım. Hala yeni kabul edilen cevap olarak işaretleniyor çünkü diğer cevap kategorik.
markus

Çok az cevap beni yüksek sesle güldürüyor. Bunu yaptı. Bravo +1
toddmo

114

session_start () çağrısı yapıldığında, sınıf bildirimi / tanımına PHP tarafından zaten rastlanmışsa veya önceden yüklenmiş bir otomatik yükleyici tarafından bulunabilir. aksi takdirde, nesnenin oturum deposundan serisini kaldıramaz.


12
Teşekkürler! Bu benim için bir hata düzeltti: D
Matt Ellen

Uygun bir __autoload()işleve sahipseniz bu sorunun önlenebileceğini varsayıyorum .
Langel

Serileştirilmiş bir nesnenin serileştirilmesinde sınıf tanımını eklemeliyiz ??? Nesnenin serileştirilmesi sırasında, kabul ettiğim sınıf tanımına ihtiyacı var, ama ben de serileştirilmiş nesnenin serileştirilmesi gereken dosyaya sınıf tanımını eklemek zorunda mıyım ???
Rajesh Paul

35

HTTP, bir nedenle vatansız bir protokoldür. Oturumların durumu HTTP'ye kaynaklanır. Genel bir kural olarak, oturum durumunu kullanmaktan kaçının.

GÜNCELLEME: HTTP düzeyinde bir oturum kavramı yoktur; sunucular bunu istemciye benzersiz bir kimlik vererek ve istemciye her istekte yeniden göndermesini söyleyerek sağlar. Daha sonra sunucu bu kimliği, Session nesnelerinin büyük bir hashtable'ının anahtarı olarak kullanır. Sunucu her istek aldığında, oturum bilgisini istemcinin istekle birlikte gönderdiği kimliğe dayalı olarak oturum nesnelerine hashtable'tan arar. Tüm bu ekstra işler ölçeklenebilirlik konusunda çift yönlü bir iştir (HTTP'nin vatansız olmasının büyük bir nedeni).

  • Whammy One: Tek bir sunucunun yapabileceği işi azaltır.
  • Whammy Two: Ölçeklendirmeyi zorlaştırıyor çünkü artık herhangi bir eski sunucuya bir istek yönlendiremezsiniz - hepsinin aynı oturumu yoktur. Belirli bir oturum kimliğine sahip tüm istekleri aynı sunucuya sabitleyebilirsiniz. Bu kolay değil ve tek bir hata noktası (bir bütün olarak sistem için değil, kullanıcılarınızın büyük parçaları için). Ya da oturum depolamasını kümedeki tüm sunucular arasında paylaşabilirsiniz, ancak artık daha karmaşık bir duruma sahipsiniz: ağa bağlı bellek, bağımsız bir oturum sunucusu vb.

Tüm bunlar göz önüne alındığında, oturuma ne kadar çok bilgi koyarsanız, performans üzerindeki etkisi o kadar büyük olur (Vinko'nun işaret ettiği gibi). Ayrıca Vinko'nun belirttiği gibi, nesneniz serileştirilemezse, oturum yanlış davranacaktır. Bu nedenle, genel bir kural olarak, oturumda kesinlikle gerekli olandan daha fazlasını koymaktan kaçının.

@Vinko Genellikle izlediğiniz verileri geri gönderdiğiniz yanıta gömerek ve istemcinin yeniden göndermesini sağlayarak, örneğin verileri gizli bir girişe göndererek sunucu deposu durumuna sahip olmak için çalışabilirsiniz. Gerçekten sunucu tarafı durum izlemeye ihtiyacınız varsa , muhtemelen destek veri deponuzda olmalıdır.

(Vinko ekler: PHP, oturum bilgilerini depolamak için bir veritabanı kullanabilir ve istemcinin verileri her seferinde yeniden göndermesi olası ölçeklenebilirlik sorunlarını çözebilir, ancak müşterinin tümünü kontrol ettiği için dikkat etmeniz gereken büyük bir güvenlik sorunu kutusu açar eyaletiniz)


1
HTTP düzeyinde bir oturum kavramı yoktur; sunucular bunu istemciye benzersiz bir kimlik vererek ve istemciye her istekte yeniden göndermesini söyleyerek sağlar. Daha sonra sunucu bu kimliği, Session nesnelerinin büyük bir hashtable'ının anahtarı olarak kullanır. Devam edecek…
Hank Gay

1
Sunucu her istek aldığında, oturum bilgisini istemcinin istekle birlikte gönderdiği kimliğe dayalı olarak oturum nesneleri hashtable'ından arar. Tüm bu ekstra işler ölçeklenebilirlik konusunda çift yönlü bir iştir (HTTP'nin vatansız olmasının büyük bir nedeni). Devam edecek…
Hank Gay

1
Bir şekilde kaynak durumu olmadan karmaşık uygulamaları HTTP üzerinden nasıl uygulayacağınızı merak ediyorum
Vinko Vrsalovic 25:08

3
lütfen tüm bu yorumları içerecek şekilde yanıtınızı düzenleyin. wiki için okumak daha kolay ve daha iyi ve yine de önemli olan her şey yorumlarda ise, cevabınızı kabul edilen olarak seçemiyorum. Teşekkürler!
markus

6
"whammy one" Keşke bunu daha aşağı indirebilseydim. Zamanlamanızı bilin. Bellek referansı 100 nano saniye veya 0.0001 ms'dir. Bu nedenle, ana bellekte saklanan bir hashtable üzerinde arama yapmak tam anlamıyla zaman gerektirmez. Sana bir O(1)şey söylüyor mu ? @whammy two: tüm istekleri rasgele sunuculara rastgele yönlendirmiyor musunuz? robin yapın ve aynı kullanıcıdan aynı sunucuya yönlendirmeye devam edin. Bu harika, çok açık. Tüm 30+ upvotes ile birlikte kitaplarınıza geri dönmelisiniz
Toskan

19
  • Serileştirilemeyen (veya serileştirilemeyen üyeler içeren) nesneler beklediğiniz gibi $ _SESSION öğesinden çıkmayacak
  • Büyük oturumlar sunucuya bir yük getirir (her seferinde durum megazının serileştirilmesi ve serileştirilmesi pahalıdır)

Bunun dışında hiçbir sorun görmedim.


9

Deneyimlerime göre, genellikle bazı özelliklere sahip bir StdClass'tan daha karmaşık bir şey için buna değmez. Serileştirmenin maliyeti, oturumda depolanan bir Tanımlayıcı göz önüne alındığında her zaman bir veritabanından yeniden oluşturulmaktan daha fazla olmuştur. Havalı görünüyor, ancak (her zaman olduğu gibi) profilleme anahtardır.


Her istekte 5x2'lik bir veri tablosunun sorgulanması ile sonuçların oturumda önbelleğe alınması ile kullanılması arasındaki performanslar hakkında herhangi bir yorumunuz var mı?
musicliftsme

6

Kesinlikle ihtiyacınız olmadığı sürece devlet kullanmamanızı öneririm. Nesneyi oturum kullanmadan yeniden oluşturabiliyorsanız bunu yapın. Web uygulamanızda durumlara sahip olmak, uygulamayı oluşturmak için daha karmaşık hale getirir, her istek için kullanıcının hangi durumda olduğunu görmeniz gerekir. web uygulaması). Son olarak, büyük nesnelerin serileştirilmesi ve serileştirilmesi için performansı etkilediği için oturum nesnenizi olabildiğince küçük tutmanızı öneririm.


Peki, tüm veritabanı sorgularını tekrar yapmak da dahil olmak üzere nesneyi yeniden oluşturmak daha mı iyi? Çünkü bunu yapmak için düşüncelerimden biri yine aynı şeyler için db sorgulamak zorunda değildi oldu.
markus

3
Sizin için önemliyse, veritabanını tekrar oturum açmamak yerine önbellekleme kullanarak sorgulamayacaktır. Ama bina önbelleğe alma gibi bir şey yapmadan önce gerçekten bir performans isabet olup olmadığını kontrol edin.
Johnny

Teşekkürler, aslında olmadığını düşünüyorum. Sadece tekrar sorgulamalıyım.
markus

4

Kaynak yüklerinin (db bağlantıları veya dosya işaretçileri gibi) sayfa yüklemeleri arasında kalmayacağını ve bunları görünmez bir şekilde yeniden oluşturmanız gerektiğini hatırlamanız gerekir.

Ayrıca oturumun boyutunu, nasıl depolandığına bağlı olarak, boyut kısıtlamaları veya gecikme sorunları yaşayabilirsiniz.


0

Yazılım kitaplıklarını yükseltirken de yükselirdim - yazılımımızı yükselttik ve eski sürümde V1 yazılımının sınıf adları ile oturumda nesneler vardı, yeni yazılım oturumda olan nesneleri oluşturmaya çalıştığında çöküyordu - V2 gibi yazılım artık aynı sınıfları kullanmadı, bulamadı. Oturum nesnelerini algılamak, bulunursa oturumu silmek, sayfayı yeniden yüklemek için bazı düzeltme kodları koymak zorunda kaldık. Başlangıçta en büyük acı, ilk kez bildirildiğinde bu hatayı yeniden yarattığınızı düşünüyor (hepsi çok tanıdık, "iyi, benim için çalışıyor" :) çünkü sadece eski ve yeni sistemlere giren ve çıkan insanları etkiledi - ancak, iyi Tüm kullanıcılarımız oturumlarında eski oturum değişkenlerine sahip olacağından ve potansiyel olarak herkes için çökeceğinden, lansmandan önce bulduğumuz işi,

Her neyse, değişikliğinizde önerdiğiniz gibi, nesneyi yeniden oluşturmanın daha iyi olduğunu düşünüyorum. Yani belki sadece kimliğini saklamak ve sonra her istek üzerine nesneyi veritabanından çekerek, daha iyi / daha güvenli.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.