Согласно правилам области видимости большинства языков программирования, я могу получить доступ к переменным, которые определены вне функций внутри них, но почему этот код не работает?
<?php
$data = 'My data';
function menugen() {
echo "[" . $data . "]";
}
menugen();
?>
Выход есть []
.
Ответы:
Это не работает, потому что вам нужно объявить, к каким глобальным переменным вы будете обращаться:
$data = 'My data'; function menugen() { global $data; // <-- Add this line echo "[" . $data . "]"; } menugen();
В противном случае вы можете получить к нему доступ как
$GLOBALS['data']
. См. Область действия переменной .Даже если это немного не по теме, я бы посоветовал вам вообще избегать использования глобальных переменных и предпочитать передачу в качестве параметров.
источник
This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope.
Вы можете сделать одно из следующего:
<?php $data = 'My data'; function menugen() { global $data; echo "[" . $data . "]"; } menugen();
Или же
<?php $data = 'My data'; function menugen() { echo "[" . $GLOBALS['data'] . "]"; } menugen();
При этом чрезмерное использование глобальных переменных может привести к плохому коду. Обычно лучше передать то, что вам нужно. Например, вместо ссылки на глобальный объект базы данных вы должны передать дескриптор базы данных и действовать в соответствии с ним. Это называется внедрением зависимостей . Когда вы внедряете автоматическое тестирование (а вам следует это делать), это делает вашу жизнь намного проще.
источник
Это вопрос объема. Короче говоря, следует избегать глобальных переменных, поэтому :
Вам либо нужно передать его как параметр:
$data = 'My data'; function menugen($data) { echo $data; }
Или получите его в классе и получите к нему доступ
class MyClass { private $data = ""; function menugen() { echo this->data; } }
См. Также ответ @MatteoTassinari, так как вы можете пометить его как глобальный для доступа к нему, но глобальные переменные обычно не требуются, поэтому было бы разумно переосмыслить свое кодирование.
источник
menugen()
это означает, что будет больше, чем просто создание меню. Например, как насчет расширения этого меню, чтобы добавить больше элементов из другого источника, как насчет выбора текущей выбранной страницы, которая находится в меню. Наличие случайных глобальных переменных и логики повсюду требует дизайна ООП. Тот факт, что PHP / JS не нуждается в структурировании, является одной из основных причин, по которой вы обнаруживаете много беспорядочного неуклюжего кода. Это может быть сделано очень хорошо, но позволяет людям не думать о ремонтопригодности в будущем.Другой способ сделать это:
<?php $data = 'My data'; $menugen = function() use ($data) { echo "[".$data."]"; }; $menugen();
ОБНОВЛЕНИЕ 2020-01-13: по запросу Питера Мортенсена
Начиная с PHP 5.3.0 у нас есть поддержка анонимных функций, которые могут создавать закрытие. Замыкание может получить доступ к переменной, которая создается вне его области видимости.
В этом примере закрытие может получить доступ
$data
потому что оно было объявлено вuse
предложении.источник
На протяжении многих лет я всегда использовал такой формат:
<?php $data = "Hello"; function sayHello(){ echo $GLOBALS["data"]; } sayHello(); ?>
Я считаю это простым и понятным. $ GLOBALS - это то, как PHP позволяет вам ссылаться на глобальную переменную. Если вы использовали такие вещи, как $ _SERVER, $ _POST и т. Д., То вы ссылаетесь на глобальную переменную, не зная об этом.
источник
$GLOBAL
(текст) или$GLOBALS
(образец кода)? (Пожалуйста, ответьте, отредактировав свой ответ , а не здесь, в комментариях (при необходимости).)Вам нужно передать переменную в функцию:
$data = 'My data'; function menugen($data) { echo $data; }
источник
<?php $data = 'My data'; $menugen = function() use ($data) { echo "[ $data ]"; }; $menugen(); ?>
Вы также можете упростить
echo "[" . $data . "]"
к
echo "[$data]"
источник
echo "[" . $data . "]"
иecho "[ $data ]"
не совпадают (два лишних пробела в выводе для последнего).По этой причине PHP может раздражать. Ответы выше с использованием
global
не сработали для меня, и мне потребовалось некоторое время, чтобы понять, как правильно использоватьuse
.Это верно:
$functionName = function($stuff) use ($globalVar) { //do stuff } $output = $functionName($stuff); $otherOutput = $functionName($otherStuff);
Это неверно:
function functionName($stuff) use ($globalVar) { //do stuff } $output = functionName($stuff); $otherOutput = functionName($otherStuff);
Используя ваш конкретный пример:
$data = 'My data'; $menugen = function() use ($data) { echo "[" . $data . "]"; } $menugen();
источник
Если хотите, вы можете использовать функцию «определить», но эта функция создает константу, которую нельзя изменить после определения.
<?php define("GREETING", "Welcome to W3Schools.com!"); function myTest() { echo GREETING; } myTest(); ?>
Константы PHP
источник