Хорошо, я не уверен, что правильно понимаю эту концепцию (я изучаю PHP). Если я правильно понимаю: глобальные переменные можно ссылаться где угодно в одном документе или в документах, связанных с «include». Локальные переменные могут ссылаться только на функцию, где они есть.
Хорошо, если я правильно понимаю (что составляет половину причины, по которой я отправляю сообщения, чтобы убедиться, что у меня есть это право), действительно ли существует потребность в локальных переменных? Я имею в виду, если каждый пользователь определил свои собственные переменные, и они должны были быть спасены, я вижу, что это полезно … вроде? Но использовать базу данных для этого было бы намного проще, я бы подумал. В каких ситуациях я бы хотел использовать локальные переменные?
Вы сомневаетесь в том, что делаете правильный выбор до того момента, когда вы просите о необходимости локальных переменных . В целом вы должны избегать глобальных переменных столько, сколько сможете.
Для меня не редкость написать какой-либо инструмент / webapp и иметь только две или три из моих собственных глобальных переменных, которые я использую для установки фактического приложения в движении.
Учти это:
$db = new PDO($conn, $usr, $pass); function select(array $fields, $tbl, $where = '') { global $db;//use the global variable return $db->query('SELECT '.implode(', ', $fields).' FROM '.$tbl.' WHERE '.$where); }
Сам по себе вы можете утверждать, что этот код будет работать нормально все время. Понятно, что такое $db
, и поэтому здесь нет очевидной ошибки.
Однако предположим, что вы включили пару других файлов, которые используют один и тот же $db
var, и есть ошибка в одном из этих файлов, что приводит к переназначению $db
:
$db = 'I used to be a PDO instnace'; select(array('*'), 'tbl');
Это покажет ошибку, которая укажет вам на строку, которая читает return $db->query();
и он скажет что-то вроде «пытается вызвать метод не-объекта» .
Удачи отладки! Где было переназначено $db
? нет никакого способа узнать, кроме как просеивать ваш код шаг за шагом.
Возможно, все равно, когда вы в последний раз оставили его, но вероятность того, что его состояние (или значение) было изменено (значительно) каким-либо другим сущностью / сущностями (людьми или кодом), которые могли бы использовать ваш кошелек (или переменную) как свои собственные , blissfuly не подозревая, что вы оставили его там для дальнейшего использования. При написании классов или функций вы обращаетесь к своим коллегам, которые будут использовать этот код в качестве пользователя . Поэтому, даже если они не навредили, глобальный случай – это несчастный случай, ожидающий своего служения.
Кстати, аргументы функции – это локальные переменные, поэтому я уверен, что вы их уже используете, не зная об этом.
Было бы гораздо лучше определить функцию select
следующим образом:
function select(PDO $connection, array $fields, $tbl = 'tbl', $where = null) { $query = 'SELECT '.implode(', ', $fields).' FROM '.$tbl; $query .= $where !== null ? ' WHERE '.$where : ''; return $connection->query($query); }
В этом funciton я создал локальную переменную, чтобы сделать код более удобочитаемым / поддерживаемым. Как я уже сказал, все аргументы также являются локальными переменными, поэтому после возвращения этой функции любая память, которая была распределена для размещения значений, которые они удерживали, может быть освобождена. Когда вы используете глобальные переменные, сборщик мусора не может выполнять свою работу, потому что переменные остаются в области видимости и могут использоваться дальше по коду. Память освобождается только после завершения работы скрипта .
Глобалы (vars в глобальном масштабе) создают беспорядочный код, поскольку вы пытаетесь избежать конфликтов имен, вы обнаружите, что объявляете vars как $i_for_looping_over_array1 = 0;
Хорошо, что это может быть немного экстремально, но в конечном итоге вы будете псевдоименовать ваши варны, так почему бы не использовать правильные пространства имен, области, классы и т. Д.?
global
медленное Всякий раз, когда вы используете global
ключевое слово внутри функции, вы эффективно говорите: ищите переменную с именем $someName
, которая может быть где угодно. Передавая ту же переменную, что и аргумент, говорит, что функция использует это .
При передаче объекта вы фактически передаете ссылку на этот объект (т. Е. Его адрес), поэтому поиск не требуется. Примитивы копируются, поэтому нет никакого поиска.
Думайте о себе как бармен. Где бы вы предпочли работать? Паб AllIsGlobalHere, где в свой первый день ваш босс сказал: «Если клиент попросит что-нибудь, бутылка может быть где угодно, подвал, пол или верхний правый шкаф» или «Паб CheckTheArguments». Последний – это место, где вы прыгаете прямо, и когда клиент просит пива, ваш босс и / или клиент с удовольствием укажут, какой проект вы должны сослаться.
Для инкапсуляции необходимы локальные переменные, что является хорошей практикой в программировании.
Глобальные переменные на самом деле являются плохой практикой, потому что переменная может быть изменена в любом месте приложения и, верьте мне, трудно отлаживать, почему значение переменной не является ожидаемым, если у вас есть мультипликаторы с мультипликаторами …
Если вам нужно использовать глобальную переменную, возможно, вам стоит подумать об использовании singleton или передать переменную в качестве параметра функции, которая в ней нуждается.
В программировании существует много случаев, когда вам нужна переменная только в изолированном контексте. Счетчики, аргументы функций и переменные для хранения промежуточных результатов вычислений и т. Д., Они не представляют интереса для всего приложения. Кроме того, существует специальный случай рекурсивных функций. Локальные переменные получат свои собственные разные адреса для каждого экземпляра рекурсивной функции, что необходимо для правильной работы рекурсии. Однако в PHP-приложениях рекомендуется избегать использования глобальных переменных, где бы вы ни находились.
Всего несколько причин, чтобы предпочесть местный over gobal:
Переменные занимают память. Если каждая переменная находится в глобальном масштабе, это занимает много памяти. Локальные переменные существуют только тогда, когда они находятся в области видимости, поэтому они временно используют память, а затем снова освобождается память. Поэтому лучше использовать память – хороший аргумент.
Если все переменные глобальны, то функция A и функция B могут обновлять переменную, но никто не знает, что другой ее изменил, поэтому это может привести к ситуациям, когда вы не осознаете, что значение было изменено одной функцией, и предположим, что он все еще действует в другом.
В каких ситуациях я бы хотел использовать локальные переменные?
Локальными переменными являются те, которые определены внутри локальной области (функции), эти переменные доступны только в этой области, но не снаружи, например:
$foo = 'foo'; function bar(){ $foo = 'bar'; } echo $foo; //prints foo
например, вы можете видеть, что такое же имя переменной можно использовать внутри локальной области без какого-либо влияния.
Если вы используете только глобальные вары, вам нужно будет дать новое имя каждому новому счетчику, ха-ха.
Видимость vars необходима для инкапсуляции: переменной может влиять только объект, к которому вы хотите получить доступ. Например:
class Person{ private $_money; public function rob(){ return $this->_money; } }
Только объект класса Person может управлять своими деньгами, поэтому, если вы хотите их, вы должны получить маску и пистолет.