Область видимости переменной
Область видимости переменной — это контекст, в котором эта переменная определена. В большинстве случаев все переменные PHP имеют только одну область видимости. Эта единая область видимости охватывает также включаемые (include) и требуемые (require) файлы. Например:
Здесь переменная $a будет доступна внутри включенного скрипта b.inc . Однако определение (тело) пользовательской функции задает локальную область видимости данной функции. Любая используемая внутри функции переменная по умолчанию ограничена локальной областью видимости функции. Например:
$a = 1 ; /* глобальная область видимости */
?php
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 ;
?php
echo $HTTP_POST_VARS [ ‘name’ ];
// Суперглобальные переменные доступны в любой области
// видимости и не требуют указания ‘global’.
// Суперглобальные переменные доступны, начиная с PHP 4.1.0, а
// использование HTTP_POST_VARS считается устаревшим.
echo $_POST [ ‘name’ ];
>
?>
Замечание:
Использование ключевого слова global вне функции не является ошибкой. Оно может быть использовано в файле, которые включается внутрь функции.
Использование статических (static) переменных
Другой важной особенностью области видимости переменной является статическая переменная. Статическая переменная существует только в локальной области видимости функции, но не теряет своего значения, когда выполнение программы выходит из этой области видимости. Рассмотрим следующий пример:
Пример #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 ); // неверно (поскольку это тоже выражение)
?php
Замечание:
Статические объявления вычисляются во время компиляции скрипта.
Ссылки с глобальными (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 ();
?>
Результат выполнения данного примера:
Статический объект: NULL
Статический объект: NULL
Статический объект: NULL
Статический объект: object(stdClass)(1) [«property»]=>
int(1)
>
Этот пример демонстрирует, что при присвоении ссылки статической переменной она не запоминается, когда вы вызываете функцию &get_instance_ref() во второй раз.
$_POST
An associative array of variables passed to the current script via the HTTP POST method when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request.
Examples
Example #1 $_POST example
Assuming the user POSTed name=Hannes
The above example will output something similar to:
Notes
Note:
This is a ‘superglobal’, or automatic global, variable. This simply means that it is available in all scopes throughout a script. There is no need to do global $variable; to access it within functions or methods.
See Also
User Contributed Notes 6 notes
One feature of PHP’s processing of POST and GET variables is that it automatically decodes indexed form variable names.
I’ve seem innumerable projects that jump through extra & un-needed processing hoops to decode variables when PHP does it all for you:
With the first example you’d have to do string parsing / regexes to get the correct values out so they can be married with other data in your app. whereas with the second example.. you will end up with something like:
var_dump ( $_POST [ ‘person’ ]);
//will get you something like:
array (
0 => array( ‘first_name’ => ‘john’ , ‘last_name’ => ‘smith’ ),
1 => array( ‘first_name’ => ‘jane’ , ‘last_name’ => ‘jones’ ),
)
?>
This is invaluable when you want to link various posted form data to other hashes on the server side, when you need to store posted data in separate «compartment» arrays or when you want to link your POSTed data into different record handlers in various Frameworks.
Remember also that using [] as in index will cause a sequential numeric array to be created once the data is posted, so sometimes it’s better to define your indexes explicitly.
I know it’s a pretty basic thing but I had issues trying to access the $_POST variable on a form submission from my HTML page. It took me ages to work out and I couldn’t find the help I needed in google. Hence this post.
Make sure your input items have the NAME attribute. The id attribute is not enough! The name attribute on your input controls is what $_POST uses to index the data and therefore show the results.
If you want to receive application/json post data in your script you can not use $_POST. $_POST does only handle form data.
Read from php://input instead. You can use fopen or file_get_contents.
// Get the JSON contents
$json = file_get_contents ( ‘php://input’ );
// decode the json data
$data = json_decode ( $json );
?>
There’s an earlier note here about correctly referencing elements in $_POST which is accurate. $_POST is an associative array indexed by form element NAMES, not IDs. One way to think of it is like this: element «id=» is for CSS, while element «name text» name=»txtForm»>.
Note that $_POST is NOT set for all HTTP POST operations, but only for specific types of POST operations. I have not been able to find documentation, but here’s what I’ve found so far.
In other words, for standard web forms.
A type used for a generic HTTP POST operation.
For a page with multiple forms here is one way of processing the different POST values that you may receive. This code is good for when you have distinct forms on a page. Adding another form only requires an extra entry in the array and switch statements.
if (!empty( $_POST ))
// Array of post values for each different form on your page.
$postNameArr = array( ‘F1_Submit’ , ‘F2_Submit’ , ‘F3_Submit’ );
// Find all of the post identifiers within $_POST
$postIdentifierArr = array();
foreach ( $postNameArr as $postName )
if ( array_key_exists ( $postName , $_POST ))
$postIdentifierArr [] = $postName ;
>
>
// Only one form should be submitted at a time so we should have one
// post identifier. The die statements here are pretty harsh you may consider
// a warning rather than this.
if ( count ( $postIdentifierArr ) != 1 )
count ( $postIdentifierArr ) < 1 or
die( «\$_POST contained more than one post identifier: » .
implode ( » » , $postIdentifierArr ));
// We have not died yet so we must have less than one.
die( «\$_POST did not contain a known post identifier.» );
>
switch ( $postIdentifierArr [ 0 ])
case ‘F1_Submit’ :
echo «Perform actual code for F1_Submit.» ;
break;
case ‘Modify’ :
echo «Perform actual code for F2_Submit.» ;
break;
case ‘Delete’ :
echo «Perform actual code for F3_Submit.» ;
break;
>
>
else // $_POST is empty.
echo «Perform code for page without POST data. » ;
>
?>
Cannot re-assign auto-global variable _POST in?
Добрый день друзья, пишу систему тестирования, столкнулся с ошибкой: Fatal error: Cannot re-assign auto-global variable _POST in W:\domains\KKOLLEGE\Functions.php on line 78
Вот собственно содержимое файла Functions.php
' . print_r($arr, true) . '
'; > // Получение списка тестов function get_tests() < global $db; $query = "SELECT * FROM test WHERE enable = '1' "; $res = mysqli_query($db, $query); if(!$res) return false; $data = array(); while($row = mysqli_fetch_assoc($res))< $data[] = $row; >return $data; > // Получение данных теста function get_test_data($test_id) < if( !$test_id ) return; global $db; $query = "SELECT q.question, q.parent_test, a.id, a.answer, a.parent_question FROM questions q LEFT JOIN answers a ON q.id = a.parent_question LEFT JOIN test ON test.id = q.parent_test WHERE q.parent_test = $test_id AND test.enable = '1' "; $res = mysqli_query($db, $query); $data = null; while ($row = mysqli_fetch_assoc($res)) < if( !$row['parent_question'] ) return false; $data[$row['parent_question']][0]= $row['question']; $data[$row['parent_question']][$row['id']] = $row['answer']; >return $data; > // Получение id вопрос-ответы function get_correct_answers($test) < if( !$test ) return false; global $db; $query = "SELECT q.id AS question_id, a.id AS answer_id FROM questions q LEFT JOIN answers a ON q.id = a.parent_question LEFT JOIN test ON test.id = q.parent_test WHERE q.parent_test = $test AND a.correct_answer = '1' AND test.enable = '1'"; $res = mysqli_query($db, $query); $data = null; while($row = mysqli_fetch_assoc($res))< $data[$row['question_id']] = $row['answer_id']; >return $data; > // Строим пагинацию function pagination($count_questions, $test_data)< $keys = array_keys($test_data); $pagination = '
'; return $pagination; > // Итоги // 1- Массив Вопрос/ответы 2- Правильные ответы 3- Ответы пользователя function get_test_data_result($test_all_data, $result, $_POST) < // Заполняем массив $test_all_data правильными ответами и данными о неотвеченных вопросах foreach ($result as $q =>$a) < $test_all_data[$q]['correct_answer'] = $a; // Добавим в массив данные о неотвеченных вопросах if( !isset($_POST[$q]) )< $test_all_data[$q]['incorrect_answer'] = 0; >> // Добавим неверный ответ если таковой был foreach ($_POST as $q => $a) < // Удалим из $_POST "левые" значения вопросов if( !isset($test_all_data[$q]) )< unset($_POST[$q]); continue; >// Если есть "левые" значения ответов if( !isset($test_all_data[$q][$a]) ) < $test_all_data[$q]['incorrect_answer'] = 0; continue; >// Добавляем неверный ответ if( $test_all_data[$q]['correct_answer'] != $a ) < $test_all_data[$q]['incorrect_answer'] = $a; >> return $test_all_data; > // Печать результатов function print_result($test_all_data_result) < // Переменные результатов $all_count = count($test_all_data_result); // количество вопросов $correct_answer_count = 0; // количество верных ответов $incorrect_answer_count = 0; // количество неверных ответов $percent = 0; // процент верных ответов // Подсчёт результатов foreach ($test_all_data_result as $item) < if( isset($item['incorrect_answer']) ) $incorrect_answer_count++; >$correct_answer_count = $all_count - $incorrect_answer_count; $percent = round ( ($correct_answer_count / $all_count * 100), 2); // вывод результатов $print_res = '
Всего вопросов: "; $print_res .= "
Из них отвечено верно: "; $print_res .= "
Из них отвечено неверно: "; $print_res .= "
% верных ответов: "; $print_res .= '
'; $print_res .= '
'; return $print_res; > ?>
Вот содержимое файла Tests.php
?> > ?> Варианты тестов
">
Всего вопросов:
Вывод вопросов и ответов
$item): ?> $answer): // проходимся по массиву вопрос-ответы ?>
" value="">
Выберите тест
Нет тестов
Если я просто убираю $_POST то всё работает, однако POST собирает Ответы пользователя и в итоге если я закончу тест, то у меня не идёт подсчёт правильных ответов и процент верных ответов