Php global array null

Область видимости переменной

Область видимости переменной — это контекст, в котором эта переменная определена. В большинстве случаев все переменные PHP имеют только одну область видимости. Эта единая область видимости охватывает также включаемые (include) и требуемые (require) файлы. Например:

Здесь переменная $a будет доступна внутри включенного скрипта b.inc . Однако определение (тело) пользовательской функции задает локальную область видимости данной функции. Любая используемая внутри функции переменная по умолчанию ограничена локальной областью видимости функции. Например:

$a = 1 ; /* глобальная область видимости */

function test ()
<
echo $a ; /* ссылка на переменную локальной области видимости */
>

Этот скрипт не сгенерирует никакого вывода, поскольку выражение echo указывает на локальную версию переменной $a , а в пределах этой области видимости ей не было присвоено значение. Возможно вы заметили, что это немного отличается от языка C в том, что глобальные переменные в C автоматически доступны функциям, если только они не были перезаписаны локальным определением. Это может вызвать некоторые проблемы, поскольку люди могут нечаянно изменить глобальную переменную. В PHP, если глобальная переменная будет использоваться внутри функции, она должна быть объявлена глобальной внутри определения функции.

Ключевое слово global

Сначала пример использования global:

Пример #1 Использование global

function Sum ()
global $a , $b ;

Вышеприведенный скрипт выведет 3. После определения $a и $b внутри функции как global все ссылки на любую из этих переменных будут указывать на их глобальную версию. Не существует никаких ограничений на количество глобальных переменных, которые могут обрабатываться функцией.

Второй способ доступа к переменным глобальной области видимости — использование специального, определяемого PHP массива $GLOBALS . Предыдущий пример может быть переписан так:

Пример #2 Использование $GLOBALS вместо global

function Sum ()
$GLOBALS [ ‘b’ ] = $GLOBALS [ ‘a’ ] + $GLOBALS [ ‘b’ ];
>

$GLOBALS — это ассоциативный массив, ключом которого является имя, а значением — содержимое глобальной переменной. Обратите внимание, что $GLOBALS существует в любой области видимости, это объясняется тем, что $GLOBALS является суперглобальным. Ниже приведен пример, демонстрирующий возможности суперглобальных переменных:

Пример #3 Суперглобальные переменные и область видимости

function test_global ()
// Большинство предопределенных переменных не являются
// «супер», и чтобы быть доступными в локальной области
// видимости, функции требуют указания ‘global’.
global $HTTP_POST_VARS ;

echo $HTTP_POST_VARS [ ‘name’ ];

// Суперглобальные переменные доступны в любой области
// видимости и не требуют указания ‘global’.
// Суперглобальные переменные доступны, начиная с PHP 4.1.0, а
// использование HTTP_POST_VARS считается устаревшим.
echo $_POST [ ‘name’ ];
>
?>

Замечание:

Использование ключевого слова global вне функции не является ошибкой. Оно может быть использовано в файле, которые включается внутрь функции.

Использование статических (static) переменных

Другой важной особенностью области видимости переменной является статическая переменная. Статическая переменная существует только в локальной области видимости функции, но не теряет своего значения, когда выполнение программы выходит из этой области видимости. Рассмотрим следующий пример:

Читайте также:  What is popup window in javascript

Пример #4 Демонстрация необходимости статических переменных

Эта функция довольно бесполезна, поскольку при каждом вызове она устанавливает $a в 0 и выводит 0. Инкремент переменной $a ++ здесь не играет роли, так как при выходе из функции переменная $a исчезает. Чтобы написать полезную считающую функцию, которая не будет терять текущего значения счетчика, переменная $a объявляется как static:

Пример #5 Пример использования статических переменных

Теперь $a будет проинициализирована только при первом вызове функции, а каждый вызов функции test() будет выводить значение $a и инкрементировать его.

Статические переменные также дают возможность работать с рекурсивными функциями. Рекурсивной является функция, вызывающая саму себя. При написании рекурсивной функции нужно быть внимательным, поскольку есть вероятность сделать рекурсию бесконечной. Вы должны убедиться, что существует адекватный способ завершения рекурсии. Следующая простая функция рекурсивно считает до 10, используя для определения момента остановки статическую переменную $count :

Пример #6 Статические переменные и рекурсивные функции

Замечание:

Статические переменные могут быть объявлены так, как показано в предыдущем примере. Попытка присвоить этим переменным значения, являющиеся результатом выражений, вызовет ошибку обработки.

Пример #7 Объявление статических переменных

function foo () static $int = 0 ; // верно
static $int = 1 + 2 ; // неверно (поскольку это выражение)
static $int = sqrt ( 121 ); // неверно (поскольку это тоже выражение)

Замечание:

Статические объявления вычисляются во время компиляции скрипта.

Ссылки с глобальными (global) и статическими (static) переменными

Движок Zend Engine 1, лежащий в основе PHP 4, оперирует модификаторами переменных static и global как ссылками. Например, реальная глобальная переменная, внедренная в область видимости функции указанием ключевого слова global, в действительности создает ссылку на глобальную переменную. Это может привести к неожиданному поведению, как это показано в следующем примере:

function test_global_noref () global $obj ;
$obj = new stdclass ;
>

test_global_ref ();
var_dump ( $obj );
test_global_noref ();
var_dump ( $obj );
?>

Результат выполнения данного примера:

Аналогично ведет себя и выражение static. Ссылки не хранятся статично:

echo ‘Статический объект: ‘ ;
var_dump ( $obj );
if (!isset( $obj )) // Присвоить ссылку статической переменной
$obj = &new stdclass ;
>
$obj -> property ++;
return $obj ;
>

echo ‘Статический объект: ‘ ;
var_dump ( $obj );
if (!isset( $obj )) // Присвоить объект статической переменной
$obj = new stdclass ;
>
$obj -> property ++;
return $obj ;
>

$obj1 = get_instance_ref ();
$still_obj1 = get_instance_ref ();
echo «\n» ;
$obj2 = get_instance_noref ();
$still_obj2 = get_instance_noref ();
?>

Результат выполнения данного примера:

Читайте также:  Javascript swap two variables

Статический объект: NULL
Статический объект: NULL

Статический объект: NULL
Статический объект: object(stdClass)(1) [«property»]=>
int(1)
>

Этот пример демонстрирует, что при присвоении ссылки статической переменной она не запоминается, когда вы вызываете функцию &get_instance_ref() во второй раз.

Источник

Why this global array is returning NULL from a callback function

This drove me crazy for hours now. Please tell me why the $ppk_fields array is empty in the ppk_field_callback function? Note that it returns the correct values in the ppk_default_id function but that is not a callback function. Thank you! ppk.php

class Ppk < public function ini() < add_action( 'admin_menu', array( $this, 'add_ppk_p_menu' ) ); >public function add_ppk_p_menu() < add_submenu_page( 'tools.php', 'PPK PLUGIN', 'PPK PLUGIN', 'manage_options', 'ppk_p', array( $this, 'ppk_build_dashboard' ) ); >public function ppk_build_dashboard() < require_once plugin_dir_path( __FILE__ ) . 'ppk-builder.php'; >> if ( class_exists( 'Ppk' ) ) < $ppk = new Ppk(); $ppk->ini(); > 
$ppk_sections = [ 'section_1' => [ 'title' => 'Group One' ] ]; $ppk_fields = [ 'field 1' => [ 'title' => 'Fieald One', 'type' => 'text', 'section' => 'section_1', 'default' => 'default' ] ]; register_setting( 'ppk-builder', 'ppk-builder', 'ppk-builder_validate' ); foreach ($ppk_sections as $id => $value) < add_settings_section( $id, $value['title'], 'ppk_section_callback', 'ppk_p'); >foreach ($ppk_fields as $id => $value) < add_settings_field( $id, $value['title'], 'ppk_field_callback', 'ppk_p', $value['section'], $id ); >function ppk_section_callback() function ppk_default_id( $id ) < global $ppk_fields; return $ppk_fields[ $id ]['default']; >function ppk_field_callback($id) < global $ppk_fields; $option = get_option('ppk-builder'); $id_field = isset($option[$id]) ? $option[$id] : ppk_default_id($id); switch ($ppk_fields[$id]['type']) < case 'text': echo ''; break; > > settings_fields( 'ppk-builder' ); do_settings_sections( 'ppk_p' ); 

@TomJNowell inside the ppk_field_callback function, no where else. Why is it even when it’s set as global i can’t access the array values?

1 Answer 1

The problem here is that you never created $ppk_fields as a global variable.

$ppk_fields = [ 'field 1' => [ 'title' => 'Fieald One', 'type' => 'text', 'section' => 'section_1', 'default' => 'default' ] ]; 

Here we have a variable that is created normally, and obeys normal scoping rules. It isn’t a global variable, and nobody has stated it’s a global variable.

Further down the file we have:

function ppk_field_callback($id) < global $ppk_fields; 

But, the global variable $ppk_fields is undefined, nobody defined it. You have to declare the variable as a global every time you use it, and that includes creation and destruction. No exceptions.

Doing it Wrong

But there's an even bigger problem. The biggest problem is that you used global variables at all. Global variables are a great way to avoid structuring your program, break unit tests, and introduce unnecessary complexity

For example, the global variables would be unnecessary if you'd placed all of the above code inside a class. Then, $this->fields would be what you'd use.

ppk_settings.php:

class PPK_Settings < private $sections; private $fields; function __construct() < $this->sections = [ 'section_1' => [ 'title' => 'Group One' ] ]; $this->fields = [ 'field 1' => [ 'title' => 'Fieald One', 'type' => 'text', 'section' => 'section_1', 'default' => 'default' ] ]; > function register() < register_setting( 'ppk-builder', 'ppk-builder', 'ppk-builder_validate' ); foreach ($this->sections as $id => $value) < add_settings_section( $id, $value['title'], array( $this, 'section_callback' ), 'ppk_p'); >foreach ($this->fields as $id => $value) < add_settings_field( $id, $value['title'], array( $this, 'ppk_field_callback' ), 'ppk_p', $value['section'], $id ); >> // etc. other methods go here > 
require_once( 'ppk_settings.php' ); $settings = new PPK_Settings(); $settings->register(); 

You could instead go the OO way, and have PPK_Field and PPK_Section objects, so that you can define your fields, then loop over the array creating objects, with no problems or troubles accessing them, and no need for globals or member variables

Читайте также:  Thread sleep 1000 java

Источник

$GLOBALS

Ассоциативный массив ( array ), содержащий ссылки на все переменные, определённые в данный момент в глобальной области видимости скрипта. Имена переменных являются ключами массива.

Примеры

Пример #1 Пример использования $GLOBALS

function test () $foo = "локальная переменная" ;

echo '$foo в глобальной области видимости: ' . $GLOBALS [ "foo" ] . "\n" ;
echo '$foo в текущей области видимости: ' . $foo . "\n" ;
>

$foo = "Пример содержимого" ;
test ();
?>

Результатом выполнения данного примера будет что-то подобное:

$foo в глобальной области видимости: Пример содержимого $foo в текущей области видимости: локальная переменная

Начиная с PHP 8.1.0, доступ на запись ко всему массиву $GLOBALS больше не поддерживается:

Пример #2 запись всего $GLOBALS приведёт к ошибке

// Генерирует ошибку во время компиляции:
$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x ;
$x =& $GLOBALS ;
unset( $GLOBALS );
array_pop ( $GLOBALS );
// . и любые другие операции записи/чтения-записи в $GLOBALS
?>

Примечания

Замечание:

Это 'суперглобальная' или автоматическая глобальная переменная. Это просто означает, что она доступна во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ней внутри метода или функции.

Замечание: Доступность переменной

В отличие от всех остальных суперглобальных переменных, $GLOBALS всегда доступна в PHP.

Замечание:

Начиная с PHP 8.1.0, массив $GLOBALS теперь является доступной только для чтения копией глобальной таблицы символов. То есть глобальные переменные не могут быть изменены с помощью его копии. Ранее массив $GLOBALS исключался из обычного поведения массивов PHP по значению и глобальные переменные можно было изменить с помощью его копии.

// До PHP 8.1.0
$a = 1 ;
$globals = $GLOBALS ; // Как будто бы по значению копии
$globals [ 'a' ] = 2 ;
var_dump ( $a ); // int(2)

// Начиная с PHP 8.1.0
// больше не изменяет значение $a. Предыдущее поведение нарушало семантику по значению
$globals = $GLOBALS ;
$globals [ 'a' ] = 1 ;

// Чтобы восстановить предыдущее поведение, повторите его копию и присвойте каждому свойству значение $ GLOBALS.
foreach ( $globals as $key => $value ) $GLOBALS [ $key ] = $value ;
>
?>

Источник

Оцените статью