【问题标题】:PHP | What does 'use function function_name;' (where function is a PHP built-in function) do?PHP | 'use function function_name;' 是什么意思? (其中function是PHP内置函数)怎么办?
【发布时间】:2022-01-05 20:41:48
【问题描述】:

我遇到了一些使用use 关键字的PHP 代码,这与我之前看到的略有不同。 我其实是在Slim框架源码中看到的。

use function array_pop;    // --> confusion :/
use function dirname;      // --> confusion :/
use function file_exists;  // --> confusion :/
use function sprintf;      // --> confusion :/
use function is_readable;  // --> confusion :/
use function is_writable;  // --> confusion :/

source code 是从2429 的行。

我知道关键字use 用于包括类

use Psr\Container\ContainerInterface; // --> class
use Psr\Http\Message\ResponseFactoryInterface; // --> class

或用于在函数的闭包中添加外部范围变量

$array = array('foo', 'bar', 'baz');
$prefix = uniqid();

$array = array_map(function ($elem) use ($prefix) {  // -> here the use keyword is clear
    return $prefix . $elem;
}, $array);

但是这种情况下use关键字声明在脚本顶部和函数前面真的很奇怪,而且它们都是内置函数?!。

问题

  • 什么是使用函数[内置函数名];用 PHP 做 (PHP "^7.4 || ^8.0")?

【问题讨论】:

  • 查看PHP Manual中的命名空间
  • 这是为了表明您使用内置函数,而不是例如\MyVendor\Project\dirname
  • 啊我明白了,基本上是为了避免名字冲突?但是如果我有\MyVendor\Project\dirnameuse function dirname; 会发生什么?
  • 用别名导入一个
  • @PeterM 把它作为答案怎么样?

标签: php function methods require keyword


【解决方案1】:

好吧其实很简单,主要问题是,我没有正确阅读文档或者我只是错过了部分,尽管use 关键字在 PHP 中被广泛使用,但除了具有不同的功能之外,这是真的. 无论哪种方式,感谢谁帮助我在评论部分找到了问题[(@riggsfolly@peterm@eis@david,经过良好的阅读和测试,我' d 决定发布我自己的答案。


快速解答

use function [some_function] 是一个 namespace,它为特定位置定义/导入该函数,该位置是命名空间部分,可以从不同命名空间甚至 modifying the name with alias 具有相同命名函数,用于函数和命名空间一起来。

可以是用户定义的命名空间,也可以是全局命名空间

在这种情况下,以这种方式调用内置函数仅仅是为了样式/清晰,但也可能PHP Performance Tip: Use fully-qualified function calls when working with namespaces


详细解答

所以use关键字散布着这些功能:

  • 命名空间导入/包含:模块(作为包)、类、特征、接口、函数、常量
  • 闭包函数中使用变量的外部作用域
  • 在类中注入特征。

所以我的问题是指第一点导入/包含(函数)。

命名空间在使用类时更加明显,只要在脚本上声明命名空间,该脚本就变得相对于该命名空间,而不是全局。因此,如果您在没有指定命名空间的情况下调用任何未在同一脚本中定义的类,将导致错误,example:

<?php    

    namespace A\B\C;
    class Exception extends \Exception
    {
    }
    
    $a = new Exception('hi'); // $a is an object of class A\B\C\Exception
    $b = new \Exception('hi'); // $b is an object of class Exception
    
    $c = new ArrayObject; // fatal error, class A\B\C\ArrayObject not found

?>

但更清楚的例子是:

<?php
namespace A\B\C;
$b = new Exception('hi'); // Uncaught Error: Class "A\B\C\Exception"

通过移除命名空间,它会回到全局上下文

<?php
$b = new Exception('hi'); // no errors..

但是,constfunctions 不会发生这种情况,这就是为什么不那么明显,如果找不到,会默默地退回到外部范围。

对于函数和常量,如果命名空间函数或常量不存在,PHP 将回退到全局函数或常量。

<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // prints "45"
echo INI_ALL, "\n"; // prints "7" - falls back to global INI_ALL

echo strlen('hi'), "\n"; // prints "1"
if (is_array('hi')) { // prints "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}
?>

最后,举一些关于我的问题的例子: 文件functions.php

namespace MyApp\Package;

//use function var_dump;
function var_dump($var)
{
    echo '[', __NAMESPACE__, '] don\'t wnat to do that...<br/>';
}
function explode($separator, $some_string)
{
    echo '[', __NAMESPACE__, '] opps, bomb failed :(...<br/>';
}

文件 index.php

<?php

namespace MyApp;
require_once 'functions.php';

use MyApp\Package; // Demostrate that we can 'import' the entire package namespace
use function MyApp\Package\var_dump; // Import the function only

class A
{
    public static function say() {
        $a = "a";
        $b = "b";
        $data = ['a' => $a, 'b' => $b];
        echo var_dump($data); // --> Calling the namespaced function
    }
    public static function sayReal()
    {
        $a = "a";
        $b = "b";
        $data = ['a' => $a, 'b' => $b];
        echo \var_dump($data); // -> with \ we make the lookup fully-qualified and falls back to global
    }
    public static function explodeBadBomb($bomb="something to explode")
    {
        Package\explode(" ",$bomb); // -> demostrate that we can namespaced in withing blocks and statements
    }
    public static function explodeGooodBomb($bomb="something to explode")
    {
        echo print_r(\explode(" ", $bomb)); // again calling the built-in
    }
}
A::say();               // [MyApp\Package] don't wnat to do that...
A::sayReal();           // array(2) { ["a"]=> string(1) "a" ["b"]=> string(1) "b" }
A::explodeBadBomb();    // MyApp\Package] opps, bomb failed :(...
A::explodeGooodBomb();  // Array ( [0] => something [1] => to [2] => explode ) 

文档

更多关于性能改进的信息

相关 StackOverflow 问题/解答

【讨论】:

    猜你喜欢
    • 2016-11-12
    • 2011-02-25
    • 2020-04-29
    • 2017-02-27
    • 2013-08-25
    • 2012-07-04
    • 2016-02-14
    • 2020-04-20
    • 1970-01-01
    相关资源
    最近更新 更多