Veritabanı bağlantısı için genel veya Singleton?

8 Cevap php

PHP veritabanı bağlantıları için tekiz yerine kullanarak küresel yararı nedir? Ben tekiz kullanarak yerine küresel kod gereksiz yere karmaşık hale getirir hissediyorum.

Code with Global

$conn = new PDO(...);

function getSomething()
{
    global $conn;
    .
    .
    .
}

Code with Singleton

class DB_Instance
{
    private static $db;

    public static function getDBO()
    {
    	if (!self::$db)
    		self::$db = new PDO(...);

    	return self::$db;
    }
}

function getSomething()
{
    $conn = DB_Instance::getDBO();
    .
    .
    .
}

Küresel veya tekil dışında bir veritabanı bağlantısı başlatılıyor daha iyi bir yolu varsa, bu söz ve küresel ya da tekiz üzerinde buna sahip avantajları açıklayınız.

8 Cevap

Ben bu eski olduğunu biliyorum, ama Dr8k cevabı almost vardı.

Eğer bir parça kodu yazarken dikkate alındığında, bunu değiştirmek için gidiyor varsayalım. Yani bunu gelecekte bir noktada bunun üzerine çekildi olacak değişikliklerin türlü varsayarak, daha ziyade değişim çeşit yapılmış olacağı konum anlamına gelmez.

Bir amaç gelecekte değişiklik yapma acısını hafifletmek olun: bu tek bir noktada yönetmek zor çünkü global tehlikelidir. Ne ben gelecekte bu veritabanı bağlantı bağlam farkında yapmak istiyorsanız? Ne o kullanılan her 5 defa kapatıp kendini yeniden istiyorsanız. Ne benim app ölçekleme çıkarına ben 10 bağlantıları havuzu kullanmak istediğiniz karar verirseniz? Veya bağlantıları yapılandırılabilir bir numara?

A singleton factory Bunu esneklik verir. Ben çok az karmaşıklık ile kurmak ve aynı bağlantı için sadece erişim daha fazla kazanç; Ben bu bağlantı basit bir şekilde daha sonra bana iletilen nasıl değiştirme yeteneği kazanmak.

Ben sadece singleton karşı singleton factory olarak söylemek unutmayın. Singleton ve küresel bir gerçek arasındaki kıymetli çok az fark var. Ve çünkü, bir tek bağlantısı olması için hiçbir neden yok: neden yerine normal bir küresel yaratabileceği zaman o kurma vakit geçirmek istiyorsunuz?

Ne bir fabrika sensin alır bir bağlantı almak ve almak için gidiyoruz ne bağlantıları (veya bağlantı) karar vermek ayrı bir nokta için neden.

Example

class ConnectionFactory
{
    private static $factory;
    public static function getFactory()
    {
        if (!self::$factory)
            self::$factory = new ConnectionFactory(...);
        return self::$factory;
    }

    private $db;

    public function getConnection() {
        if (!$db)
            $db = new PDO(...);
        return $db;
    }
}

function getSomething()
{
    $conn = ConnectionFactory::getFactory()->getConnection();
    .
    .
    .
}

App süper ünlü ve dugg ve slashdotted alma ve karar verirken daha sonra, 6 ay içinde tek bir bağlantı daha fazlasına ihtiyacımız var, yapmanız gereken bütün) yöntemi (GetConnection bazı havuzu uygulamak olduğunu. Eğer SQL günlüğü uygulayan bir sarıcı istediğiniz karar verirseniz ya da, bir PDO alt sınıfı iletebilirsiniz. Yoksa her çağırma üzerinde yeni bir bağlantı istediğinize karar verirseniz, yapabilirsiniz bunu. Bunun yerine rijit, esnek.

Satır aşağı ürkütücü benzer bir şey için size saatlerce ve üstlenmeden saat kurtaracak parantez dahil olmak üzere kod 16 satır.

Ben ilk go turda herhangi bir özellik uygulama yapıyor değilim, çünkü ben bu "Özelliği Creep" düşünün unutmayın. Bu sınır çizgisi "Gelecek Creep", ama bir noktada, "Bugün yarın için kodlama" olduğu fikri always kötü bir şey benim için gevezelik değil.

Ben özel soruya cevap olabilir emin değilim, ama tekiz / küresel bağlantı nesneleri iyi bir fikir olmayabilir önermek istedim bu web tabanlı bir sistem için eğer. DBMSs genel olarak etkin bir şekilde tek bağlantıların çok sayıda yönetmek için tasarlanmıştır. Eğer global bir bağlantı nesnesi kullanıyorsanız, o zaman bir kaç şey yapıyoruz:

  1. Forcing you pages to do all database connections sequentially and killing any attempts at asyncronous page loads.

  2. Potentially holding open locks on database elements longer than necessary, slowing down overall database performance.

  3. Maxing out the total number of simultaneous connections your database can support and blocking new users from accessing the resources.

Ben diğer potansiyel sonuçları da vardır eminim. Bu yöntem, siteye erişim her kullanıcı için bir veritabanı bağlantısı sürdürmek için çalışacaktır, unutmayın. Yalnızca bir veya iki kullanıcıları, bir sorun varsa. Bu bir kamu web sitesi ve trafik istiyorsanız o ölçeklenebilirlik bir sorun haline gelecektir.

[EDIT]

Daha büyük ölçekli durumlarda, yeni bağlantılar oluşturarak her şey size datase kötü olabilir çarptı. Ancak, cevabı küresel bir bağlantı oluşturmak ve her şey için yeniden değildir. Cevap bağlantı havuzu olduğunu.

Bağlantı havuzu ile, farklı bağlantıların sayısı korunur. Bir bağlantı uygulama tarafından gerekli olduğunda havuzundan ilk kullanılabilir bağlantı alınır ve iş yapılır bir kez daha sonra havuza döndü. Bir bağlantı isteği ve hiçbiri iki şeyden biri olur mevcuttur ise: izin bağlantı sayısı aşılsa değilse bir), yeni bir bağlantı açılır, veya b) uygulama kullanılabilir hale bir bağlantı için beklemek zorunda kalır .

Note: de. Net dilleri, bağlantı havuzu (bağlantı dizesi tüm gerekli bilgileri ayarlar) varsayılan ADO.Net nesneler tarafından işlenir.

Bu yorum için crad teşekkürler.

Tekiz yöntemi emin herhangi bir sınıfın tek bir örneği vardı yapmak için oluşturuldu. Insanlar küreselleşen kısayol için bir yol olarak kullanın çünkü Ama, tembel ve / veya kötü programlama olarak bilinir.

Bu nedenle, her iki yana küresel ve Singleton gerçekten OOP değildir görmezden.

Ne arıyorlardı olan dependency injection.

Sen http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection de (örneklerle) bağımlılık enjeksiyon ile ilgili PHP tabanlı bilgileri okumak kolay kontrol edebilirsiniz

Her iki desenleri veritabanı aramaları için tek bir erişim noktası sağlayarak, aynı net etkiyi elde.

Belirli bir uygulama açısından, tek adet diğer yöntemlerin en az bir istekte bir veritabanı bağlantısını başlatma olmayan küçük bir avantajı vardır. Ben yazdım çoğu uygulamada, pratikte bu kadar fark yapmaz, ancak, herhangi bir veritabanı tüm çağrıları yapmayın bazı sayfalar / çalıştırma yolunuz varsa potansiyel bir avantaj bu sayfalar olmaz beri Hiç veritabanına bağlantısı istemek.

Bir diğer küçük fark, küresel uygulama istemeden uygulamasındaki diğer değişken isimleri üzerinde çiğnemek olabilir olmasıdır. Bu size (diyelim ki, eğer ($ db = null) yazmak yanlışlıkla üzerine yazabilirsiniz mümkün olsa hiç yanlışlıkla, başka global $ db başvurusunu ilan edeceğiz düşüktür size yazmak istedim zaman if ($ db == null). tek nesne önler.

Eğer kalıcı bir bağlantı kullanmak için gitmiyorsun, ve bunu yapmayan durumlar varsa, ben bir tek kavramsal daha lezzetli OO tasarımında dünya daha olabilir bulabilirsiniz.

Gerçek bir OO mimaride, bir tek nesne, her zaman yeni bir örneğini oluşturarak daha etkilidir.

Verilen örnekte, ben singletons kullanmak için hiçbir neden göremiyorum. Dil izin veriyorsa, benim tek endişem bir nesnenin tek bir örneğini izin için ise kural olarak, ben küresellerle kullanmayı tercih

Genel olarak bir veritabanı bağlantısı için bir Singleton kullanmak istiyorsunuz ... Eğer veritabanına etkileşime gerek yeni bir bağlantı her şey yaratmak istemiyorum ... Bu perfomance ve ağınızın bant genişliği zarar olabilir ... Neden oluşturmak yeni bir tane, bir tane mevcut ... Sadece benim 2 sent ...

RWendi

Bu oldukça basit. Küresel VEYA Singleton asla kullanmayın.