#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() ... }
, но вы не можете смешивать этот синтаксис с другим незашифрованным кодом пространства имен в одном файле. Я решил проблему, переместив функции в отдельный файл.