Глобальні змінні — змінні, які оголошуються після початку виконання скрипта. Робиться це за допомогою наступної конструкції:
global $my_var;
Суперглобальні змінні — змінні, які на момент початку роботи скрипта вже оголошені й можуть містити якесь значення. Про них дуже добре розписано в документації PHP
Проблематика
Глобальні змінні важко відстежуються і можуть бути легко перезаписані в іншому місці — виявити це інколи дуже складно. \ Наприклад: Недавно залетів до мене тікет по якому у шаблон (view) не передавався тимчасовий токен підтвердження пошти користувача. Без нього користувач не міг перейти на 2 крок верифікації. Витративши зо дві години, вияснилося, що хтось у проміжних скриптах реалізував новий алгоритм входу в систему і переписав токен верифікації токеном логіна.
Чому там використовуються глобальні змінні — інше питання. Пропоную зосередитися на тому, що краще використовувати замість них.
Збереження глобальних даних
Особисто я використовую OOP підхід: якщо мені потрібно зберегти дані на глобальному рівні, я їх зберігаю у статичну приватну властивість класу і реалізовую в ньому гетери/сетери, якщо є така необхідність. Виглядає це приблизно так:
class user
{
static private $current_user;
static public function define_by_token($token)
{
if (!is_string($token) || empty($token)) {
throw new InvalidArgumentException('Invalid user token');
}
//Якщо дані про користувача ще не отримані
if (empty(self::$current_user)) {
$user_data = db::query('#Query string');
if (!$user_data) {
throw new RuntimeException('User was not found');
}
self::$current_user = $user_data;
}
}
static public function get_current()
{
if (empty(self::$current_user)) {
throw new InvalidArgumentException('User is not defined yet. Please, call method `user::define_by_token($token)`');
}
return self::$current_user;
}
}
//Тепер ми можемо отримувати доступ до даних про користувача і не переживати за їхню цілісність
user::define_by_token('348yv2834yn0vt8'); //визначаємо дані користувача
function getUserName()
{
return user::get_current()->name; //Використовуємо в іншій зоні видимості змінних
}
echo getUserName(); //тут виведеться ім'я користувача, яке було отримано з бази даних і збережене у статичну властивість
Сподіваюсь читач пробачить мене за не надто вдалий інтерфейс класу. Моїм завданням було показати взаємодію з глобальними даними, а не як проектувати класи.
Думаю принцип зрозумілий. Як щодо суперглобальних змінних!?
Робота з суперглобальними змінними
Дані, які приходять зверху в суперглобальних змінних, ніколи, ні за яких обставин, не потрібно переписувати. Єдиним винятком тут є $\\_SESSION і $\\_COOKIE
.
Іншими словами, більшість суперглобальних змінних варто використовувати лише в режимі read-only. Їхнє переписування порушить цілісність вхідних даних і збільшить ризик отримати непередбачувану ситуацію, яку потім складно виправити.
Нюанси
Будь-які глобальні дані — додаткове місце в оперативній пам'яті. Створення великої кількості статичних властивостей може привести до перенавантаження сервера. Тому логіку варто проектувати так, щоб не доводилося «кидатися» даними від об'єкта до об'єкта. Атомарні алгоритми — наше все.
Чистого коду і попутних завдань.
Ще немає коментарів