2009-08-05 13 views
6

Mam klasy bazy danych, której wystąpienie jest zadeklarowany w głównym index.php jakCzy mogę utworzyć zmienną globalnie widoczną bez konieczności deklarowania jej globalnie w każdym konstruktorze klasy PHP?

$db = new Database(); 

Czy istnieje sposób dla zmiennej $db być globalnie uznawane we wszystkich innych klas bez konieczności zadeklarować

global $db; 

w konstruktorze każdej klasy?

+0

Czy naprawdę potrzebujesz go dostępny dla WSZYSTKICH innych klas? –

+0

Nie wszystkie, ale znaczna ilość. –

Odpowiedz

16

Nie. Musisz zadeklarować Global $ db w konstruktorze każdej klasy.

lub możesz użyć globalnej tablicy: $ _GLOBALS ['vars'];

Jedynym sposobem obejścia tego problemu jest użycie klasy statycznej do zawinięcia, o nazwie Singleton Method (Aby uzyskać wyjaśnienie, patrz Here). Ale to bardzo zła praktyka.

class myClass 
    { 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     else 
     { 
      return self::$class; 
     } 
    } 
    // Then create regular class functions. 
    } 

Metoda singleton została stworzona, aby upewnić się, że istnieje tylko jedno wystąpienie dowolnej klasy. Ale ponieważ ludzie używają go jako sposobu na skróty do globalizacji, staje się znany jako leniwe/złe programowanie.

StackOverflow Knowledge
How to Avoid Using PHP Global Objects
Share Variables Between Functions in PHP Without Using Globals
Making a Global Variable Accessible For Every Function inside a Class
Global or Singleton for Database Connection

+0

Dlaczego upadek? –

+0

Jaja powiedziałem, że metoda Singletona nie była właściwą odpowiedzią. Ale zawarłem to, ponieważ można go użyć "technicznie". –

+0

Nie byłem głosowaniem w dół, dziękuję za poinformowanie mnie - chcę uniknąć złych praktyk. –

1

można użyć

$GLOBALS['db']->doStuff(); 

lub alternatywnie przy użyciu pewnego rodzaju metody Singleton dostępu

Database::getInstance()->doStuff(); 
+0

Czy jedną z tych metod są złe praktyki? Czy najlepszą praktyką jest zadeklarowanie klasy bazy danych jako globalnej w obrębie każdej klasy? –

0

Można użyć klasy Registry do przechowywania i pobierania instancji Database.

class Registry 
{ 
    protected static $_data = array(); 

    public static function set($key, $value) 
    { 
     self::$_data[$key] = $value; 
    } 

    public static function get($key, $default = null) 
    { 
     if (array_key_exists($key, self::$_data)) { 
      return self::$_data[$key]; 
     } 

     return $default; 
    } 
} 

Registry::set('db', new Database()); 
$db = Registry::get('db'); 
+0

To jest w zasadzie klasa singleton dla danych ... –

+0

, więc jest $ GLOBALS ... –

+0

Z wyjątkiem słów '$ GLOBALS' i' global' są wbudowane w ten język i dlatego są szybkie i znane wszystkim. Twoja klasa rejestru nie jest i nie dodaje żadnych dodatkowych funkcji. Pewna klasa 'Opcji' może być przydatna do przechowywania opcji aplikacji, ale nawet to może prawdopodobnie zastąpione tablicą asocjacyjną. –

1

Dlaczego nie utworzyć klasę, która zawiera global $db; w jego konstruktora, a następnie rozszerzyć wszystkich innych klas z tego?

2

Robię to trochę inaczej. Zazwyczaj mam globalny obiekt aplikacji (aplikację). W ciągu tego obiektu zrobić podstawowe inicjalizacji jak tworzenie moje obiekty DB, buforowanie obiektów, itd

Mam też globalną funkcję zwracającą obiekt App .... zatem definicję obiektu aplikacji (nie pokazany):

define('APPLICATION_ID', 'myApplication'); 

${APPLICATION_ID} = new App; 

function app() { 
    return $GLOBALS[APPLICATION_ID]; 
} 

Więc mogę używać coś takiego do dowolnego miejsca w dowolnym kodzie odwoływać obiektów w obrębie globalnego obiektu:

app()->db->read($statement); 
app()->cache->get($cacheKey); 
app()->debug->set($message); 
app()->user->getInfo(); 

to nie jest idealne, ale uważam, że aby ułatwić w wielu okolicznościach.

Powiązane problemy