function foo () {
global $var;
// rest of code
}
В своих небольших PHP-проектах я обычно использую процедурный путь. Обычно у меня есть переменная, содержащая конфигурацию системы, и когда мне нужно получить доступ к этой переменной в функции, я делаю это global $var;
.
Это плохая практика?
php
global-variables
global
KRTac
источник
источник
Ответы:
Когда люди говорят о глобальных переменных на других языках, это означает нечто иное, чем то, что они делают в PHP. Это потому, что переменные в PHP не являются глобальными. Объем типичной программы PHP - один HTTP-запрос. Переменные сеанса на самом деле имеют более широкую область действия, чем «глобальные» переменные PHP, потому что они обычно охватывают множество HTTP-запросов.
Часто (всегда?) Вы можете вызывать функции-члены в таких методах,
preg_replace_callback()
как этот:preg_replace_callback('!pattern!', array($obj, 'method'), $str);
См. Обратные вызовы для получения дополнительной информации.
Дело в том, что объекты привязаны к PHP и в некотором смысле приводят к некоторой неловкости.
Не беспокойтесь чрезмерно о применении стандартов или конструкций из разных языков к PHP. Еще одна распространенная ошибка - это попытка превратить PHP в чистый ООП-язык, наклеивая объектные модели поверх всего.
Как и все остальное, используйте «глобальные» переменные, процедурный код, конкретную структуру и ООП, потому что это имеет смысл, решает проблему, уменьшает объем кода, который вам нужно написать, или делает его более удобным в обслуживании и легким для понимания, а не потому, что вы думаете вам следует.
источник
array ($obj, 'callbackMethod')
при обращении кpreg_replace_callback()
? (Я знаю, я стал жертвой этой ловушки ООП ...)При неправильном использовании глобальные переменные могут затруднить поиск проблем. Допустим, вы запрашиваете скрипт php и получаете предупреждение о том, что вы пытаетесь получить доступ к индексу массива, который не существует в какой-либо функции.
Если массив, к которому вы пытаетесь получить доступ, является локальным для функции, вы проверяете функцию, чтобы увидеть, не допустили ли вы там ошибки. Это может быть проблема с вводом в функцию, поэтому вы проверяете места, где функция вызывается.
Но если этот массив является глобальным, вам нужно проверить все места, где вы используете эту глобальную переменную, и не только это, вы должны выяснить, в каком порядке осуществляется доступ к этим ссылкам на глобальную переменную.
Если у вас есть глобальная переменная в фрагменте кода, это затрудняет изолирование функциональности этого кода. Почему вы хотите изолировать функциональность? Так что вы можете протестировать его и повторно использовать в другом месте. Если у вас есть код, который не нужно тестировать и не нужно повторно использовать, тогда можно использовать глобальные переменные.
источник
я согласен с cletus. я бы добавил две вещи:
С уважением, Дон
источник
$DB = 'foo';
Кто может спорить с опытом, высшим образованием и разработкой программного обеспечения? Не я. Я бы только сказал, что при разработке объектно-ориентированных одностраничных PHP-приложений мне больше нравится, когда я знаю, что могу построить все с нуля, не беспокоясь о конфликтах пространств имен. Строить с нуля многие люди больше не делают. У них есть работа, дедлайн, бонусы или репутация, о которых нужно заботиться. Эти типы склонны использовать так много заранее созданного кода с высокими ставками, что они вообще не могут рисковать использованием глобальных переменных.
Может быть плохо использовать глобальные переменные, даже если они используются только в глобальной области программы, но давайте не будем забывать о тех, кто просто хочет развлечься и заставить что-то работать .
Если это означает использование нескольких переменных (<10) в глобальном пространстве имен, которые используются только в глобальной области программы, пусть будет так. Да, да, MVC, внедрение зависимостей, внешний код, бла, бла, бла, бла. Но если вы поместили 99,99% вашего кода в пространства имен и классы, а внешний код изолирован, мир не закончится (я повторяю, мир не закончится), если вы используете глобальную переменную.
В общем, я бы не сказал, что использование глобальных переменных - плохая практика . Я бы сказал, что использование глобальных переменных (флагов и т. Д.) Вне глобальной области программы вызывает проблемы и (в конечном итоге) нецелесообразно, потому что вы можете довольно легко потерять их состояние. Кроме того, я бы сказал, что чем больше вы узнаете, тем меньше вы будете полагаться на глобальные переменные, потому что вы испытаете «радость» от отслеживания ошибок, связанных с их использованием. Уже одно это побудит вас найти другой способ решения той же проблемы. По совпадению, это подталкивает PHP-людей к изучению того, как использовать пространства имен и классы (статические члены и т. Д.).
Область информатики обширна. Если мы отпугнуть всех от делать что - то , потому что мы называем это плохо , то они теряют на удовольствие от истинного понимания рассуждения позади метки.
При необходимости используйте глобальные переменные, но затем посмотрите, сможете ли вы решить проблему без них. Коллизии, тестирование и отладка значат больше, когда вы хорошо понимаете истинную природу проблемы, а не просто описание проблемы.
источник
Мы можем проиллюстрировать эту проблему с помощью следующего псевдокода
function foo() { global $bob; $bob->doSomething(); }
Ваш первый вопрос здесь очевиден
Вы растеряны? Хороший. Вы только что узнали, почему глобальные переменные сбивают с толку и считаются плохой практикой. Если бы это была настоящая программа, ваше следующее развлечение - отследить все ее экземпляры
$bob
и надеяться, что вы найдете нужную программу (становится еще хуже, если$bob
ее использовать повсюду). Хуже того, если кто-то другой придет и определит$bob
(или вы забыли и повторно использовали эту переменную), ваш код может сломаться (в приведенном выше примере кода неправильный объект или отсутствие объекта вообще вызовут фатальную ошибку). Поскольку практически все программы PHP используют код, подобныйinclude('file.php');
вашей работе, поддержание такого кода становится экспоненциально сложнее, чем больше файлов вы добавляете.Как нам избежать глобалов?
Лучший способ избежать глобальных переменных - это философия под названием Dependency Injection . Здесь мы передаем необходимые нам инструменты в функцию или класс.
function foo(\Bar $bob) { $bob->doSomething(); }
Это намного проще понять и поддерживать. Невозможно угадать, где это
$bob
было настроено, потому что вызывающий несет ответственность за это (он передает нам то, что нам нужно знать). Более того, мы можем использовать объявления типов, чтобы ограничить то, что передается. Итак, мы знаем, что$bob
это либо экземплярBar
класса, либо экземпляр дочернего элементаBar
, то есть мы знаем, что можем использовать методы этого класса. В сочетании со стандартным автозагрузчиком (доступным с PHP 5.3) теперь мы можем отслеживать, гдеBar
это определено. PHP 7.0 или новее включает объявления расширенного типа, где вы также можете использовать скалярные типы (например,int
илиstring
).источник
$bob = Bar::instance();
когда вам это нужно.В качестве:
global $my_global; $my_global = 'Transport me between functions'; Equals $GLOBALS['my_global']
это плохая практика (как Wordpress
$pagenow
) ... хмммПодумайте об этом:
$my-global = 'Transport me between functions';
это ошибка PHP Но:
$GLOBALS['my-global'] = 'Transport me between functions';
НЕ является ошибкой, hypens не будут конфликтовать с "общими" пользовательскими переменными, например
$pagenow
. И использование ВЕРХНЕГО регистра указывает на использование суперглобала, который легко обнаружить в коде или отследить с помощью поиска в файлах.Я использую дефисы, если мне лень создавать классы всего для одного решения, например:
$GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';
Но в случаях более широкого использования я использую ОДИН глобал как массив:
$GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... '; $GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';
Последнее для меня является хорошей практикой в отношении целей или использования «колы-лайта» вместо беспорядка с одноэлементными классами каждый раз для «кэширования» некоторых данных. Пожалуйста, прокомментируйте, если я ошибаюсь или упускаю что-то глупое ...
источник