从类导入静态方法并为其设置别名



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

所以说我有这个类:

namespace AppHelpers;
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 AppHelpersHTTP::extract_path_from_url( 'http://example.com/test' );

上面的那个有效

但试图为其别名:

<?php
use AppHelpersHTTPextract_path_from_url as extract_path;
echo extract_path( 'http://example.com/test' );

将输出

Fatal error: Uncaught Error: Call to undefined function AppHelpersHTTPextract_path_from_url()

甚至:

<?php
use AppHelpersHTTP::extract_path_from_url as extract_path;
echo extract_path( 'http://example.com/test' );

显示这个奇怪的错误:

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

这可能吗?

问候

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

<?php
use AppHelpersHTTP as extract_path;
echo extract_path::extract_path_from_url( 'http://example.com/test' );

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

use NamespaceOneSomeclass;
use NamespaceTwoSomeclass as SecondClass;

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

Someclass::method()

会模棱两可。

它们可以用于的第二件事是,如果您需要从一个命名空间导入大量类。 比如这样:

use AppExceptionsNoFile;
use AppExceptionsFileSize;
use AppExceptionsFileType;
throw new NoFile();
throw new FileSize();
throw new FileType();

可以这样完成:

use AppExceptions as E;
throw new ENoFile();
throw new EFileSize();
throw new EFileType();

这不仅更短,而且更容易维护,如果您更改命名空间,您只需更改别名,然后一切都很好。 因此,简而言之,它并不是真正用于您想要使用它的目的。

包装它

您可以随时为其制作包装器:

if(!function_exists('extract_path_from_url')){
function extract_path_from_url($url){
return AppHelpersHTTP::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 中做了这件事

只是一些想法,享受!

解决方法是使用命名空间的helpers.php文件并在其中定义"简单"函数,这些函数只是通过参数传递。

// lib/My/Deeply/Nested/Namespace/MyClass.php
<?php
namespace MyDeeplyNestedNamespace;
class MyClass
{
public static function aVeryUsefulFunction(string $var): string
{
// ...Do some stuff
return $magic;
}
}
// lib/helpers.php
namespace App;
use MyDeeplyNestedNamespaceMyClass;
function doMagic(...$args)
{
return MyClass::aVeryUsefulFunction(...$args);
}
// templates/my-view.php
<?php use function AppdoMagic; ?>
<div>I am doing <?= doMagic('magic') ?>!</div>

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

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

正如手册所说,您可以通过use类、函数和常量导入。类的方法(甚至是静态类(不是函数

因此,例如,您有:

namespace MySuperNameSpace;
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 MySuperNameSpaceMY_CONST;
use MySuperNameSpaceMyClass;
use function MySuperNameSpacemy_function as func_alias;

这就是您可以使用use导入的所有项目。

最新更新