Правила доброго тону в роботі з глобальними даними в PHP

2 хв. читання

Глобальні змінні — змінні, які оголошуються після початку виконання скрипта. Робиться це за допомогою наступної конструкції:

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. Їхнє переписування порушить цілісність вхідних даних і збільшить ризик отримати непередбачувану ситуацію, яку потім складно виправити.

Нюанси

Будь-які глобальні дані — додаткове місце в оперативній пам'яті. Створення великої кількості статичних властивостей може привести до перенавантаження сервера. Тому логіку варто проектувати так, щоб не доводилося «кидатися» даними від об'єкта до об'єкта. Атомарні алгоритми — наше все.

Чистого коду і попутних завдань.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація