Php, правильно используя require_once()

У меня есть страница с переменной и функцией:

test.php

<?php
  $myVar = "myVar";
  
  function myFunc() {
    echo "myFunc()";
  }
?>

Первая страница, которая его включает, может увидеть значение переменной.

<?php
  echo "page1";
  require_once("include/test.php");
  print_r($myVar);

function GoTo2() {
  $urlSite = "page2.php";
  include($urlSite); 
  exit();
}

GoTo2();
?>

но вторая страница не видит переменную.

<?php
  echo "page2\n";
  require_once("include/test.php");
  print_r($myVar);
?>

он генерирует PHP. Предупреждение: Undefined variable $myVar in .../page2.php on line 4

Я не могу использовать require() на второй странице, потому что выдает ошибку - PHP Fatal error: Cannot redeclare myFunc() (previously declared in .../include/test.php) in .../include/test.php ...

Как правильно использовать PHP, чтобы обе страницы могли видеть переменную, а также использовать функцию?

Обновлено:

  • это упрощенная версия моих реальных страниц. Я только что обнаружил, что страница 2 не видит переменную, когда сайт был обновлен до php8, и получил все предупреждения «Неопределенная переменная».
  • page1 — это страница «диспетчера».
  • Предположим, я унаследовал этот код от другого разработчика, какое решение проблемы лучше всего подойдет?

Вы включаете одно в другое, так почему же вы с самого начала называете их обе «страницами»?

CBroe 23.07.2024 10:46

Именно поэтому в файле следует объявлять только глобальные имена, такие как функции и классы, а не переменные, и уж точно не оба вместе.

deceze 23.07.2024 10:47

Это проблема масштаба. Поскольку вы включили это в функцию GoTo2, у вас есть доступ только к переменным в области действия этой функции. $myVar не входит в область действия этой функции, поскольку test.php требовалось вне этой функции.

CBroe 23.07.2024 10:48

Да, речь идет об области действия и не имеет ничего общего с использованием require_once или include. Та же проблема возникла бы, если бы весь код внутри «page2.php» был написан непосредственно внутри function GoTo2(). Прочтите документацию

ADyson 23.07.2024 10:51

@ADyson Да, и нет. Область действия предотвращает наследование переменной, сочетание объявления переменной и функции предотвращает повторное включение объявляющего файла.

deceze 23.07.2024 10:53

@deceze правда. Смешение объявлений переменных и объявлений функций в «test.php» не помогает. Но в любом случае все это кажется излишне сложным и запутанным и требует переосмысления.

ADyson 23.07.2024 10:55

Какое «лучшее решение» является, зависит от того, что здесь разрешено давать. Рефакторинг того, где и как эта переменная объявляется и передается, был бы идеальным. Но может быть и много работы. Использование ключевого слова global здесь может быть простым решением, но только удлинит спагетти.

deceze 23.07.2024 10:55
I just discovered that page2 cannot see the variable when the site was upgraded to php8... в более ранних версиях его тоже не было видно, но раньше предупреждение было Уведомлением, и люди иногда его отключали. Так что это не новая проблема, просто PHP8 сделал ужасный код более очевидным.
ADyson 23.07.2024 10:56

Не лучше ли было бы перенаправить на другую страницу, а не включать ее?

Nico Haase 23.07.2024 13:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
9
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

Первое решение:

function GoTo2($myVar) {...

Второе решение:

funtion GoTo2() { global $myVar; ...

Ответ принят как подходящий

Поскольку ваш настоящий вопрос заключается не в том, «почему это происходит», а в том, «как правильно это сделать», то теоретически вся схема потребует переосмысления, как отметил @ADyson.

По сути, у вас есть page1.php, включающий test.php и page2.php, который затем снова включает test.php. Но логика includes в том, что файлы следует включать только один раз.

Нет ничего плохого в том, чтобы include определять переменные, как вы это делаете, например, в случае с файлом конфигурации. Но опять же: вы include конфигурируете только один раз; если это происходит дважды, скорее всего, это ошибка или заблуждение. То же самое относится и к библиотекам функций.

На самом деле не существует «единственно правильного способа сделать это». Это будет зависеть от того, что вам доступно и что вы намереваетесь. При этом идеальным вариантом было бы собрать все конфигурации в одном файле; функции, собранные в одном или нескольких файлах, в зависимости от их специфики; и у вас есть основной файл, содержащий include файлы, необходимые для конкретной операции. Например, такая структура:

  • /confs/display_config.php
  • /confs/parameters_config.php
  • /functions/encryption_routines.php
  • /functions/processing_routines.php
  • /функции/math_routines.php

Если вам нужно включить много файлов, вы можете создать файл конфигурации прокси:

конфигурация.php

<?php
require_once('/confs/display_config.php');
require_once('/confs/parameters_config.php');
require_once('/functions/encryption_routines.php');
require_once('/functions/processing_routines.php');
require_once('/functions/math_routines.php');
?>

Тогда ваш page1.php будет:

<?php
require_once('configuration.php');
// ... and other stuff
?>

Концепция «подстраниц» (например, page2.php, вызываемая внутри page1.php) также не обязательно неверна, хотя она может оказаться сложной: вам придется иметь в виду, что этот фрагмент кода предназначен для того, чтобы всегда вызываться другим странице и предполагают все настройки, которые были выполнены до вызова.

Итак, дело в том, что данная страница (в вашем случае page2.php) в идеале не должна вызываться как напрямую, так и с другой страницы (в вашем случае page1.php).

Либо page1.php и page2.php всегда вызываются напрямую и, таким образом, загружаются отдельно свои собственные конфигурации (page1.php включает test.php и page2.php включает test.php), либо page2.php всегда загружается page1.php, а затем использует его для своих собственных конфигураций (page1.php включает test.php, тогда page2.php: здесь page2.php будет иметь доступ к конфигурациям test.php, уже загруженным page1.php).

Другие вопросы по теме

Похожие вопросы