Могу ли я сделать переменную видимой глобально, не объявляя ее глобальной в каждом конструкторе класса PHP? - PullRequest
6 голосов
/ 05 августа 2009

У меня есть класс базы данных, экземпляр которого объявлен в основном index.php как

$db = new Database();

Есть ли способ, чтобы переменная $db была глобально распознана во всех других классах без объявления

global $db;

в конструкторе каждого класса?

Ответы [ 5 ]

16 голосов
/ 05 августа 2009

Нет. Вы должны объявить Global $ db в конструкторе каждого класса.

или вы можете использовать глобальный массив: $ _GLOBALS ['vars'];

Единственный способ обойти это - использовать статический класс, чтобы обернуть его, называемый Метод Singleton (объяснение см. Здесь ) Но это очень плохая практика.

  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.
   }

Метод singleton был создан для того, чтобы убедиться, что существует только один экземпляр любого класса. Но из-за того, что люди используют его как способ сокращения шара, он становится известен как ленивое / плохое программирование.

StackOverflow Knowledge
Как избежать использования глобальных объектов PHP
Обмен переменными между функциями в PHP без использования глобальных переменных
Обеспечение доступности глобальной переменной для каждой функции внутри класса
Global или Singleton для подключения к базе данных

2 голосов
/ 06 августа 2009

Я делаю это немного по-другому. У меня обычно есть глобальный объект приложения (App). Внутри этого объекта я делаю некоторую базовую инициализацию, например, создаю свои объекты БД, кеширую объекты и т. Д.

У меня также есть глобальная функция, которая возвращает объект App .... таким образом (определение объекта приложения не показано):

define('APPLICATION_ID', 'myApplication');

${APPLICATION_ID} = new App;

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

Итак, я могу использовать что-то вроде следующего в любом месте кода для ссылки на объекты в глобальном объекте:

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

Это не идеально, но я считаю, что это облегчает ситуацию во многих обстоятельствах.

1 голос
/ 05 августа 2009

Почему бы не создать класс, содержащий global $db; в своем конструкторе, а затем расширить все остальные классы из этого?

1 голос
/ 05 августа 2009

вы можете использовать

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

или, альтернативно, с использованием какого-либо метода одноэлементного доступа

Database::getInstance()->doStuff();
0 голосов
/ 05 августа 2009

Вы можете использовать класс Registry для хранения и извлечения экземпляра 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...