Calling a PHP function defined in another namespace without the prefix

前端 未结 3 2008
别跟我提以往
别跟我提以往 2021-01-01 09:02

When you define a function in a namespace,

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

you must specif

相关标签:
3条回答
  • 2021-01-01 09:36

    PHP 5.6 will allow to import functions with the use keyword:

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

    See the RFC for more information: https://wiki.php.net/rfc/use_function

    0 讨论(0)
  • 2021-01-01 09:47

    By adding the helper hacks mentioned below, you can import everything from Hamcrest namespace to current namespace by calling:

    import_namespace('Hamcrest', __NAMESPACE__);
    

    Here are the hacks, function_alias works like http://www.php.net/manual/en/function.class-alias.php except if works on functions:

    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());
          }
        }
      ");
    
    }
    

    In combination with namespace importer:

    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 . '\\')));
    }
    
    0 讨论(0)
  • 2021-01-01 09:56

    I don't know an elegant solution, but...

    You can create wrapper functions that encapsulate the functions in the external namespace. This will let you keep your code readability...

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

    0 讨论(0)
提交回复
热议问题