Skip to content

Conversation

Majkl578
Copy link
Contributor

@Majkl578 Majkl578 commented Jan 9, 2018

Motivation

As of PHP 5.3, function invocation in namespaced code is two-step operation. First, function is looked up in current namespace, if not found the fallback mode looks up the function in global scope. This effectively means that global function calls from namespaced code are slower and additionally kill further optimizations and/or inlining into special opcodes, done for some core functions. Granted, OPcache likely optimizes the two-step function lookups and further optimizes some other functions, but won't make them compile into specific opcode, and is also usually disabled in CLI.

Solution

There are two ways how to avoid fallback lookups:

  1. prepend function calls by backslash (\strlen()),
  2. add functions into imports (use function strlen).

Although approach 1) is more compact at first sight, it clutters code a lot with backslashes making it harder to read. Imports on the other hand don't - the code itself stays as simple as before and untouched. PHP optimizations do not differentiate between 1) and 2) or even import aliases so either is okay. With proper IDE support both are pretty easy to handle without much hassle.

Further reading

IDE support

PhpStorm supports autoimports of global functions and constants for a while already: https://blog.jetbrains.com/phpstorm/2017/01/phpstorm-2017-1-eap-171-2455/
obrazek

Based on discussion and implementation for doctrine/orm#6807.
ORM example (unsorted): Majkl578/doctrine-orm@78fc09c

I'd like to hear some feedback on this topic and proposed solution. Thanks.

@Majkl578 Majkl578 added the RFC label Jan 9, 2018
Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a test with a constant too

<property name="allowFullyQualifiedGlobalClasses" type="boolean" value="true"/>
<property name="allowFullyQualifiedGlobalFunctions" type="boolean" value="true"/>
<property name="allowFullyQualifiedGlobalConstants" type="boolean" value="true"/>
<property name="allowFullyQualifiedGlobalConstants" type="boolean" value="false"/>
Copy link
Member

@Ocramius Ocramius Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait... Constants too? There is no import syntax for them, no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dang, didn't remember use const 👍

Copy link
Member

@lcobucci lcobucci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@lcobucci
Copy link
Member

lcobucci commented Jan 9, 2018

@Ocramius has a point regarding tests though =)

@alcaeus
Copy link
Member

alcaeus commented Jan 9, 2018

I'm in favor of this. Do we have a sniff in place regarding sort order of use statements? I'm thinking of

use const BLAH;
use Foo\Bar;
use function strsomething;

vs.

use Foo\Bar;
use const BLAH;
use function bleh;

It boils down to either sorting all statements mixed or grouping the different use statements (use (with class being implied), use const and use function) together and sorting them as groups.

Quick addition: I'm in favor of sorting them separately FWIW.

@Ocramius
Copy link
Member

Ocramius commented Jan 9, 2018

sorting all statements mixed

Kinda ugly - would really be better to have 3 separate sections there

@lcobucci
Copy link
Member

lcobucci commented Jan 9, 2018

AFAIK the sniff will sort them separately just like phpstorm does (no line breaks), but that's another good thing to test

@Ocramius
Copy link
Member

Ocramius commented Jan 9, 2018

No need for any spacing, let's just not mix the various use statements together :-P

@alcaeus
Copy link
Member

alcaeus commented Jan 9, 2018

@lcobucci sounds good to me 👍

@kukulich
Copy link
Contributor

kukulich commented Jan 9, 2018

Yes, sorting provides this sniff: https://github.com/doctrine/coding-standard/blob/master/lib/Doctrine/ruleset.xml#L103

It sorts types in the same order as phpstorm (classes, fuctions, constants)

@Ocramius Ocramius added this to the 3.0.0 milestone Jan 9, 2018
@Ocramius Ocramius self-assigned this Jan 9, 2018
@Ocramius
Copy link
Member

Ocramius commented Jan 9, 2018

🚢

@Ocramius Ocramius merged commit 4eae508 into master Jan 9, 2018
@Ocramius Ocramius deleted the reference-global-fn-const-in-use-only branch January 9, 2018 07:21
@Majkl578
Copy link
Contributor Author

Majkl578 commented Jan 9, 2018

Do we have a sniff in place regarding sort order of use statements?

Sorry for confusion, there is a sniff for sorted uses (linked above), but I didn't apply it as it would change ton of other uses and diff would be less relevant.

I'll extend a test with some constants later and then we can ship this as 2.1. Glad to see agreement on this one. 👍

@Majkl578
Copy link
Contributor Author

Test provided in #16.

@nicwortel
Copy link

Since this repo has issues disabled, I'm asking this here: as shown in the screenshot, you recommend checking "Enable auto-import from the global space" in PhpStorm. This will also automatically import classes from the global namespace (such as DateTime, the SPL exceptions, etc.). Have you considered enforcing this in the coding standard as well for consistency? I.e. enforcing use DateTime instead of new \DateTime().

@Ocramius
Copy link
Member

Ocramius commented Feb 5, 2018

@nicwortel that would make a lot of sense, to be honest, as that's an open question. Open a PR with just a proposed test change.

@kukulich
Copy link
Contributor

kukulich commented Feb 5, 2018

It would be good for consistency because currently both new DateTime() and new \DateTime() are allowed, no version is required.

@Majkl578
Copy link
Contributor Author

FYI:

I.e. enforcing use DateTime instead of new \DateTime().

^ is done via #43 and will be in 5.0.0. 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants