Как использовать include внутри функции?

У меня есть большая функция, которую я хочу загрузить только тогда, когда это необходимо. Поэтому я предполагаю, что использование include - это путь. Но мне нужно несколько функций поддержки, а также - только в go_do_it().

Если они находятся в включенном файле, я получаю ошибку повторного использования. См. Пример A

Если я помещаю вспомогательные функции в include_once, он отлично работает, см. пример B.

Если я использую include_once для кода func_1, второй вызов терпит неудачу.

Я смущен, почему include_once заставляет функцию терпеть неудачу при втором вызове, кажется, что он не "видит" код второй раз, но если вложенные функции присутствуют, он "видит" их.

Пример A:

<?php
/*  main.php    */
go_do_it();
go_do_it();
function go_do_it(){
    include 'func_1.php';
}
?>

<?php
/*  func_1.php  */
echo '<br>Doing it';
nested_func()

function nested_func(){
    echo ' in nest';
}
?>

Пример B:

<?php
/*  main.php    */
go_do_it();
go_do_it();
function go_do_it(){
    include_once 'func_2.php';
    include 'func_1.php';
}
?>

<?php
/*  func_1.php  */
echo '<br> - doing it';
nested_func();
?>

<?php
/*  func_2.php  */
function nested_func(){
    echo ' in nest';
}
?>

Ответ 1

Проблема с использованием include() внутри функции заключается в следующем:

include 'file1.php';

function include2() {
  include 'file2.php';
}

file1.php будет иметь глобальный охват. Область file2.php локальна для функции include2.

Теперь все функции являются глобальными по объему, но переменные - нет. Я не удивляюсь этому беспорядку с помощью include_once. Если вы действительно хотите пойти этим путем, и, честно говоря, я бы этого не сделал, вам может понадобиться заимствовать старый препроцессор C/С++:

if (!defined(FILE1_PHP)) {
  define(FILE1_PHP, true);

  // code here
}

Если вы хотите идти по пути ленивой загрузки (кстати, может возникнуть проблема с кешем opcode), вместо этого используйте автозагрузку.

Ответ 2

У меня есть большая функция, которую я хочу загрузить только тогда, когда это необходимо. Поэтому я предполагаю, что использование include - это путь.

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

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

Пример:

file1.php

function test() {

}

index.php

require_once('file1.php');

include('table_of_contents.php');
test();