Когда глобальная функция не является вызываемой?

#php #function #scope #phpunit

Вопрос:

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

Если я запущу это как отдельный скрипт, $a это true :

 function php()
{
    return false;
}

$a = is_callable('php');
 

Но если я выполню этот же код в тесте PHPUnit (который проверяет внедрение внешних функций), проверка на то же самое завершится неудачей в следующем порядке:

 class MyTest extends TestCase
{
    public function testThis()
    {
        function php()
        {
            return false;
        }

        self::assertTrue(is_callable('php'));
    }
}
 

Если он явно находится в глобальной области, он все равно выходит из строя таким же образом:

 class MyTest extends TestCase
{
    public function testThis()
    {
        self::assertTrue(is_callable('php'));
    }
}

function php()
{
    return false;
}
 

Согласно документам:

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

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

Делает ли PHPUnit что-то, чтобы заблокировать определение глобальных функций?

Комментарии:

1. Этот последний код случайно не находится в namespace …?

Ответ №1:

Наиболее разумным объяснением является то, что ваш код не находится в глобальном пространстве имен. Как показано ниже

 <?php
namespace App;

function php() {
}

var_dump(is_callable('App\php'));
 

Комментарии:

1. Черт, спасибо. Это пространства имен. Я не понимал, что они применимы к глобальным функциям. Как я могу отменить эти функции? use php наверху, похоже, это не помогает.

2. Я нашел , как это сделать: namespace { function php() ... } , но вы не можете смешивать этот синтаксис с другим незашифрованным кодом пространства имен в одном файле. Я решил проблему, переместив функции в отдельный файл.