从类中导入静态方法并为其添加别名

时间:2018-09-29 16:28:23

标签: php import alias

我正在尝试从实用程序/帮助程序类中为静态方法添加别名,documentation没有提供任何有关静态方法的信息,并且使用那里定义的静态方法对静态方法不起作用(看起来如此)。

所以说我有这个课程:

namespace App\Helpers;

class HTTP {

    public static function extract_path_from_url( string $url ) {
        $parsed_url = wp_parse_url( $url );
        if ( ! isset( $parsed_url['path'] ) ) {
            return false;
        }
        return (string) $parsed_url['path'];

    }

}

然后尝试在其他文件上使用它:

<?php

echo \App\Helpers\HTTP::extract_path_from_url( 'http://example.com/test' );

以上一项有效

但尝试为其别名:

<?php

use \App\Helpers\HTTP\extract_path_from_url as extract_path;

echo extract_path( 'http://example.com/test' );

将输出

Fatal error: Uncaught Error: Call to undefined function App\Helpers\HTTP\extract_path_from_url()

偶:

<?php

use \App\Helpers\HTTP::extract_path_from_url as extract_path;

echo extract_path( 'http://example.com/test' );

显示此奇怪的错误:

Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

这可能吗?

此致

3 个答案:

答案 0 :(得分:2)

别名不会神奇地将方法转换为函数,请尝试

<?php
    use \App\Helpers\HTTP as extract_path;
    echo extract_path::extract_path_from_url( 'http://example.com/test' );

另外(不用说)当您使用别名时,这只会影响名称空间和类名,而不会影响类的方法。这些通常用于2件物品中的1件。解决命名冲突

 use NamespaceOne\Someclass;
 use NamespaceTwo\Someclass as SecondClass;

如果它们都没有别名,则使用

 Someclass::method()

会模棱两可。

它们可用于的第二件事是,如果您需要从一个名称空间导入很多类。像这样:

use App\Exceptions\NoFile;
use App\Exceptions\FileSize;
use App\Exceptions\FileType;

throw new NoFile();
throw new FileSize();
throw new FileType();

可以通过以下方式完成:

use App\Exceptions as E;

throw new E\NoFile();
throw new E\FileSize();
throw new E\FileType();

这不仅更短,而且如果更改名称空间,则更易于维护,您只需要为别名更改它,那么一切都很好。简而言之,它并不是您想要使用的真正目的。

包裹

您随时可以为其包装:

if(!function_exists('extract_path_from_url')){
     function extract_path_from_url($url){
        return \App\Helpers\HTTP::extract_path_from_url($url);
     }
}

然后将其称为您的内心满足。在性能方面,确实可以通过包装来进行额外的调用,但是通常包装器使维护起来更加容易。例如,如果您重命名该方法或类,则可以在包装器中对其进行更改,一切都很好。因此,对于任何一个选项都需要一个参数。

您不必检查该功能是否存在,但是取决于整个系统的工作方式,这可能不是一个坏主意,因此,出于完整性考虑,我将其包含在示例中。就个人而言,在这种情况下,我看不到将其与类放在同一文件中的任何问题,只记得加载它即可。如果您使用的是自动加载功能,则除非您手动加载文件或以其他方式强制其自动加载,否则将不包含该功能。当然,假设没有其他东西首先使用该类。

我过去真正喜欢的一种方法是制作一个名为http_functions(类名+ _functions)的文件,然后向注册该函数的类中添加一个静态方法:

  class HTTP {
      public static function regester_fuctions(){
          require 'http_functions.php'
      }
  }

然后,当您调用HTTP::regester_fuctions()时,它将自动加载HTTP类并包含所有功能包装。实际上,我在我的超棒调试打印类(队列无耻插件)https://github.com/ArtisticPhoenix/Debug

中做到了这一点。

有些想法,尽情享受吧!

答案 1 :(得分:0)

如手册所述,您可以通过use类,函数和常量进行导入。类的方法(即使是静态方法)也是不是函数

例如,您有:

namespace My\Super\NameSpace;

const MY_CONST = 42;

class MyClass { 

    public function do() { /* code */ }  // this is NOT a function
    public static function doStatic() { /* code */ }  // this is NOT a function too

}

function my_function() { /* code */ }  // this is function 

在其他文件中,您可以编写:

namespace YaNamespace;

use const My\Super\NameSpace\MY_CONST;
use My\Super\NameSpace\MyClass;
use function My\Super\NameSpace\my_function as func_alias;

这就是您可以通过use导入的所有项目。

答案 2 :(得分:0)

一种解决方法是使用命名空间的 helpers.php 文件并在其中定义“简单”函数,这些函数仅传递参数。

// lib/My/Deeply/Nested/Namespace/MyClass.php

<?php

namespace My\Deeply\Nested\Namespace;

class MyClass
{
    public static function aVeryUsefulFunction(string $var): string
    {
        // ...Do some stuff

        return $magic;
    }
}
// lib/helpers.php

namespace App;

use My\Deeply\Nested\Namespace\MyClass;

function doMagic(...$args)
{
    return MyClass::aVeryUsefulFunction(...$args);
}

// templates/my-view.php

<?php use function App\doMagic; ?>

<div>I am doing <?= doMagic('magic') ?>!</div>

请注意,通过在我的“传递”函数中使用扩展运算符 ...$args,我可以更改“目标”函数的要求,而无需在两个地方更新它。

这会破坏 IDE 完成,因为它只会知道建议 ...$args 而不是 string $var。我不知道有什么方法可以阻止一个函数来告诉它从另一个函数中读取参数。