Intereting Posts
PHP-скрипт для выполнения сценария bash Невозможно вставить данные в базу данных с помощью опции (textarea) Можно ли читать PHP-сессию с помощью Javascript? Получить форму значения ссылки <a href>, используя php Можно ли комментировать комментарии PHPMailer использовать Gmail как SMTP-сервер. Не удалось подключиться к узлу SMTP. Ошибка Mailer: ошибка SMTP: не удалось подключиться к SMTP-хосту Как читать и эхо-размер файла загружаемого файла, написанного на сервере в реальном времени, без блокировки на сервере и на клиенте? Как использовать php для извлечения всего имени файла в определенной папке Facebook PHP SDK 5 :: API 2.4 :: Ошибка проверки подделки на основе межсайтового запроса. Обязательное состояние «состояние» отсутствует Как включить уведомления на моем сервере разработки PHP: дата «вчера», «сегодня», Невозможно вставить данные в несколько таблиц WordPress Загрузка Safari PHP-формы Как использовать имена столбцов в PHP PDO без обязательных столбцов как загрузить doc и docx в php?

Вызов функции PHP, определенной в другом пространстве имен без префикса

Когда вы определяете функцию в пространстве имен,

namespace foo { function bar() { echo "foo!\n"; } class MyClass { } } 

вы должны указать пространство имен при вызове из другого (или глобального) пространства имен:

 bar(); // call to undefined function \bar() foo\bar(); // ok 

С помощью классов вы можете использовать инструкцию «use», чтобы эффективно импортировать класс в текущее пространство имен [Edit: Я думал, что вы можете «использовать foo» для получения классов, но, по-видимому, нет.]

 use foo\MyClass as MyClass; new MyClass(); // ok, instantiates foo\MyClass 

но это не работает с функциями [и будет громоздким, учитывая, сколько есть]:

 use foo\bar as bar; bar(); // call to undefined function \bar() 

Вы можете псевдоним пространства имен, чтобы префикс был короче,

 use foo as f; // more useful if "foo" were much longer or nested f\bar(); // ok 

но есть ли способ полностью удалить префикс?

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

 assertThat($names, is(anArray( equalTo('Alice'), startsWith('Bob'), anything(), hasLength(atLeast(12)) ))); по assertThat($names, is(anArray( equalTo('Alice'), startsWith('Bob'), anything(), hasLength(atLeast(12)) ))); 

в

 use Hamcrest as h; h\assertThat($names, h\is(h\anArray( h\equalTo('Alice'), h\startsWith('Bob'), h\anything(), h\hasLength(h\atLeast(12)) ))); - use Hamcrest as h; h\assertThat($names, h\is(h\anArray( h\equalTo('Alice'), h\startsWith('Bob'), h\anything(), h\hasLength(h\atLeast(12)) ))); 

PHP 5.6 позволит импортировать функции с use ключевого слова use :

 namespace foo\bar { function baz() { echo 'foo.bar.baz'; } } namespace { use function foo\bar\baz; baz(); } 

См. RFC для получения дополнительной информации: https://wiki.php.net/rfc/use_function

Добавив вспомогательные хаки, упомянутые ниже, вы можете импортировать все из пространства имен Hamcrest в текущее пространство имен, вызывая:

 import_namespace('Hamcrest', __NAMESPACE__); 

Вот хаки, function_alias работает как http://www.php.net/manual/en/function.class-alias.php, кроме случаев, когда работает над функциями:

 function function_alias ($original, $alias) { $args = func_get_args(); assert('count($args) == 2', 'function_alias(): requires exactly two arguments'); assert('is_string($original) && is_string($alias)', 'function_alias(): requires string arguments'); // valid function name - http://php.net/manual/en/functions.user-defined.php assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $original) > 0', "function_alias(): '$original' is not a valid function name"); assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*$/\', $alias) > 0', "function_alias(): '$alias' is not a valid function name"); $aliasNamespace = substr($alias, 0, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') : 0); $aliasName = substr($alias, strrpos($alias, '\\') !== false ? strrpos($alias, '\\') + 1 : 0); $serializedOriginal = var_export($original, true); eval(" namespace $aliasNamespace { function $aliasName () { return call_user_func_array($serializedOriginal, func_get_args()); } } "); } 

В сочетании с импортером пространства имён:

 function import_namespace ($source, $destination) { $args = func_get_args(); assert('count($args) == 2', 'import_namespace(): requires exactly two arguments'); assert('is_string($source) && is_string($destination)', 'import_namespace(): requires string arguments'); // valid function name - http://php.net/manual/en/functions.user-defined.php assert('preg_match(\'/^([a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*)?$/\', $source) > 0', "import_namespace(): '$destination' is not a valid namespace name"); assert('preg_match(\'/^([a-zA-Z_\x7f-\xff][\\\\\\\\a-zA-Z0-9_\x7f-\xff]*)?$/\', $destination) > 0', "import_namespace(): '$source' is not a valid namespace name"); foreach(get_declared_classes() as $class) if (strpos($class, $source . '\\') === 0) class_alias($class, $destination . ($destination ? '\\' : '') . substr($class, strlen($source . '\\'))); $functions = get_defined_functions(); foreach(array_merge($functions['internal'], $functions['user']) as $function) if (strpos($function, $source . '\\') === 0) function_alias($function, $destination . ($destination ? '\\' : '') . substr($function, strlen($source . '\\'))); } 

Я не знаю элегантного решения, но …

Вы можете создавать функции-оболочки, которые инкапсулируют функции во внешнем пространстве имен. Это позволит вам сохранить читаемость кода …

function assertThat($x, $y) { return h\assertThat($x, $y); }