PHP7 Adding a slash to all standard php functions php-cs-fixer rule
Asked Answered
P

6

9

Inherited a PHP7 project. The previous developer added a slash to all standard PHP functions even for \true. Is there any reason for doing this?

Some examples:

\array_push($tags, 'master');

if ($result === \true) {}

$year = \date('Y');

What is the php-cs-fixer rule to toggle this option?

Peag answered 29/3, 2019 at 14:32 Comment(1)
Ok. I understand the reason for doing it. Which rule in php-cs-fixer for this?Peag
S
8

As other answers have pointed out, prefixing global or built in functions and constants with \ makes sure they are not over-ridden by declarations within the current namespace. An alternative with the same effect is to add use function foo; and use constant foo; lines at the top of your file.

In most cases, this is unnecessary, as PHP will fall back to the global / built in version where no namespace-local version exists, but there are a few cases where there is a performance advantage if PHP knows in advance which is being used (see issue 3048 and issue 2739 in PHP-CS-Fixer).

The option to control this in PHP-CS-Fixer is native_function_invocation.

Solan answered 29/3, 2019 at 14:42 Comment(0)
P
9

You can use the slash to make sure you are using the native PHP function or constant and not the function / constant with the same name defined in a namespace of the project.

namespace test;

function array_push($arr, $str) {
    return $str;
 }

$arr = [];

var_dump(array_push($arr, 'Hello World'));   // array_push defined in namespace test
var_dump(\array_push($arr, 'Hello World'));  // native array_push function

demo: https://ideone.com/3xoFhm

Another case why you can use the \ slash is to speed up the resolving (as mentioned on the PHP-CS-Fixer documentation). PHP doesn't need to use the autoloader to find the function or constant declaration. So with leading \ PHP can use native function without additional checks.


You can toggle this option on the PHP-CS-Fixer with the native_function_invocation (for functions) and native_constant_invocation (for constants) option. You can find an explanation of the options on the following page: https://github.com/FriendsOfPHP/PHP-CS-Fixer

Procne answered 29/3, 2019 at 14:34 Comment(3)
Thanks. it makes sense. It is possible to override \true?Peag
@Peag - As I know it is not possible (couldn't find a way). But perhaps with some extensions or special settings.Procne
@Peag It's not possible in PHP 7, but earlier versions allowed you to do so using define(), like this: namespace MyNamespace; define('MyNamespace\true', false); var_dump(true);Solan
S
8

As other answers have pointed out, prefixing global or built in functions and constants with \ makes sure they are not over-ridden by declarations within the current namespace. An alternative with the same effect is to add use function foo; and use constant foo; lines at the top of your file.

In most cases, this is unnecessary, as PHP will fall back to the global / built in version where no namespace-local version exists, but there are a few cases where there is a performance advantage if PHP knows in advance which is being used (see issue 3048 and issue 2739 in PHP-CS-Fixer).

The option to control this in PHP-CS-Fixer is native_function_invocation.

Solan answered 29/3, 2019 at 14:42 Comment(0)
G
4

It could also have been because of performance. When calling it directly from the root namespace performance is considerably faster.

<?php

namespace App;

class Test 
{
    public function test()
    {
        $first = microtime(true);
        for ($i = 0; $i <= 5000; $i++) {
            echo number_format($i).PHP_EOL;
        }
        echo microtime(true) - $first;
    }
    
    public function testNative()
    {
        $first = microtime(true);
        for ($i = 0; $i <= 5000; $i++) {
             echo \number_format($i).PHP_EOL;
        }
        echo microtime(true) - $first;
    }
}



$t = new Test();
$t->test();
//0.03601598739624

$t->testNative();
//0.025378942489624
Gertrudegertrudis answered 29/3, 2019 at 14:43 Comment(2)
Thanks for sharing. That's a sizeable ~30% improvement.Peag
Not since PHP 7.4. Native function call with or without leading `\` is the same for execution time and memory usage.Boone
C
2

The above answer answers your first part, as for cs-fixer the options are:

native_function_invocation

and

native_constant_invocation
Camisado answered 29/3, 2019 at 14:36 Comment(0)
T
2

Because of namespace.

Add \ will find name from global space.

Here is a example:

<?php

namespace Foo;

function time() {
    return "my-time";
}

echo time(), " vs", \time();

You will get result like this:

my-time vs 1553870392
Tauromachy answered 29/3, 2019 at 14:41 Comment(0)
S
2

Prefixing a native PHP function with \ will specify that it is required from the global namespace.

As of PHP 7, some native functions are replaced by opcodes if they are called using the FQDN. OpCache is the hot topic when it comes to PHP 7 anyway.

By no means do all native PHP functions need this though.

For those who use PHPStorm, I recommend the Php Inspections (EA Extended) plugin which can inspect your entire project and find these optimizations for you.

Scouring answered 5/4, 2019 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.