|
|
|
| Приветствую!
Есть код:
<?
$m =opros();
echo $m;
function opros ()
{ $a = 7 +3;
return $a;
}
?>
|
Все работает - отображается на экране число 10. Но если саму функцию перенести в отдельный файл - "1.php'
//1.php
function opros ()
{ $a = 7 +3;
return $a;
}
|
ТО при исполнении кода
<?
$m =opros();
echo $m;
require"1.php";
?>
|
выводит "Fatal error: Call to undefined function opros() in V:\home\localhost\www\index.php on line 2" | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 11:23)
| | И не догадываетесь почему? | |
|
|
|
|
|
|
|
для: confirm
(21.07.2013 в 11:37)
| | Нет :) Если бы это был include то было бы понятно, но require вставляет код до трансляции? | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 12:00)
| | Это где вы такую чушь прочли? Читаем http://www.php.net/manual/ru/function.require.php
PHP это интерпретатор, и обрабатывает он строки кода последовательно, теперь после прочтения ответьте почему так происходит? | |
|
|
|
|
|
|
|
для: confirm
(21.07.2013 в 12:04)
| | Прочитал здесь http://www.php.su/functions/?include . -
PHP преобразует сценарий во внутреннее представление, анализируя строки сценария по очереди, пока не доходит до конструкции include. Дойдя до include, PHP прекращает транслировать сценарий и переключается на указанный в include файл. Таким образом из-за подобного поведения транслятора, быстродействие сценария снижается, особенно при большом колличестве включаемых с помощью include файлов. С require таких проблем нет, поскольку файлы с помощью require включаются до выполнения сценария, то есть на момент трансляции файл уже включен в сценарий.
Из Вашей ссылки
Когда файл включается, парсинг в режиме PHP кода прекращается и переключается в режим HTML в начале указанного файла и продолжается снова в конце. По этой причине любой код внутри включаемого файла, который должен быть выполнен как PHP код, должен быть заключен в верные теги начала и конца PHP кода.
Если вы имели ввиду отсутствие "<? ?>" ? в файле 1.php , то это картину не меняет . | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 12:26)
| | а кто вас заставляет писать через жопу, даже если технически это возможно?
подключите необходимые функции и библиотеки в начале файла, а затем используйте их
это более логично и менее геморно в поддержке кода | |
|
|
|
|
|
|
|
для: Valick
(21.07.2013 в 12:35)
| | :) Просто хотца понять возможности. Но по ходу ни какой разницы в плане включения в скрипт толком нет что include что require. И там там идет " переход" файл, а так как вызов функции прошел раньше ,а подключение было позже :( | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 12:40)
| | вообще-то есть разница. неужели уже по самому названию конструкции вы ее не понимаете? | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 12:26)
| | Вот что написано по указанной мной ссылке:
require идентично include за исключением того, что при ошибке оно также выдаст фатальную ошибку уровня E_COMPILE_ERROR. Другими словами, она остановит выполнение скрипта, тогда как include только выдала бы предупреждение E_WARNING, которое позволило бы скрипту продолжить выполнение.
Где вы прочли, что данная функция производит подключение кода в начало текущего независимо от места подключения?
Замените в своем коде require на include. Работает? А почему?
Добавьте перед строкой подключения следующее:
<?
echo '<pre>';
print_r(get_defined_functions());
include "1.php";
| Теперь понятна причина? | |
|
|
|
|
|
|
|
для: confirm
(21.07.2013 в 12:36)
| | http://www.php.su/functions/?include там и прочел, может не правильно трактовал :). Получается разницы между ними во включении нет, только в формировании ошибки? но как тогда понимать вот эту строчку
С require таких проблем нет, поскольку файлы с помощью require включаются до выполнения сценария, то есть на момент трансляции файл уже включен в сценарий.
А Ваш код ни чего не изменил - та же ошибка | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 12:48)
| | Я вам не код предлагаю, а разобраться почему, а ошибка и будет возникать, и ошибка гласит - что вы обращаетесь к неопределенной функции. Заремировать надо строку $m =opros();, затем выполнить. Вы видите в списке свою функцию? А после подключения она есть?
Каким образом в первой строке вашего кода, а тем более до обращения парсером к этой строке, ваш файл может быть уже подключен, если его подключение только в третье строке происходит? Интерпретатор выполняет каждую строку сразу, а не готовит выполняемый файл из всех строк кода, и только потом запускает код на выполнение.
А то что вы прочли, трактуется совсем не так, перечитайте еще раз.
PS. Между прочим, даже если ваш код запускать не под интерпретатором, а скомпилиравать (будем считать, что компилятор компилирует как есть) и запустить, то он тоже бы не работал, была бы ошибка. | |
|
|
|
|
|
|
|
для: confirm
(21.07.2013 в 13:24)
| | тогда почему когда все в одном файле, то допускается вызов функции до ее создания? Это особенность интерпретатора? | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 14:51)
| | Из руководства:
Функции не обязаны быть определены до их использования, исключая тот случай, когда функции определяются условно, как это показано в двух последующих примерах.
В случае, когда функция определяется в зависимости от какого-либо условия, например, как это показано в двух приведенных ниже примерах, обработка описания функции должна предшествовать ее вызову.
**********
Потому, что во втором случае до 3-й строки вашего кода, парсер даже представления не имеет о вашей функции, так как ее еще только предстоит подключить (объявить).
Просто возьмите за правило объявлять свои функции (и блоки данных, которые будут использоваться неоднократно в коде) в начале кода. Это облегчит отладку (по сравнению, если вы будете втыкать свои функции по всему коду), исключит ошибки связанные с объявлением, да и читать код с четко выделенными блоками (объявления, обработчик, конструкции) гораздо легче, нежели разбираться в дебрях. Это же правило, уже как обязательное, при подключении данных/функций - подключение должно быть до использования/обращения. | |
|
|
|
|
|
|
|
для: confirm
(21.07.2013 в 15:15)
| | confirm спасибо большое, впредь буду руководствоваться официальными сайтами и документами по php. | |
|
|
|
|
|
|
|
для: mikado3333
(21.07.2013 в 20:19)
| | Надо, но кроме этого надо еще и понимать обычные вещи. Имя функции, это такой же адрес как и ваш, по которому вы проживаете - неважно на каком отрезке пути (не доходя до вашего дома или пройдя его) почтальон достанет из сумки письмо ваше, главное чтобы ваш дом был именно на этой улице этого города. Если же ваше письмо оказалось в этом городе случайно, и вы проживаете в другом, тогда увы, если не заставить почтальона бежать к вам, письмо вы не получите.
Вот эта же самая ситуация и с функцией - не важно где она объявлена, в начале или конце страницы, до или после обращения к ней. Наткнувшись на ее обращение, парсер будет искать эту функцию на странице по ее имени, и найдя ее, компилирует. Но если ссылка на функцию из внешнего подключаемого файла, и подключать его вы еще не обязывали интерпретатор (во втором вашем случае), то интерпретатор просто не найдет ее. | |
|
|
|