• This repository has been archived on 01/Nov/2022
  • Stars
    star
    158
  • Rank 237,131 (Top 5 %)
  • Language
    PHP
  • License
    MIT License
  • Created almost 8 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Function FQN Replacer

This utility provides a way to replace relative references of functions in function calls with absolute references.

Rationale

As explained in this twitter convo and this article, PHP is resolving relative function references at call time.

This is relatively normal, as PHP, by design, cannot make decisions on which file defines which functions, because all opcode caching is local to single scripts, and not to a project.

In addition to that, PHP can only apply optimizations about internal function calls when those calls happen either in the global namespace, or are fully qualified name (FQN) calls.

Here's an example of the opcodes generated for an call_user_func() call without and with FQN reference:

<?php

namespace Foo {
    call_user_func('foo');
}

Opcodes:

line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   4     0  E >   INIT_NS_FCALL_BY_NAME                                    
         1        SEND_VAL_EX                                              'foo'
         2        DO_FCALL                                      0          
   5     3      > RETURN                                                   1
<?php

namespace Foo {
    // this is a FQN reference:
    \call_user_func('foo');
}
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   4     0  E >   INIT_USER_CALL                                0          'call_user_func', 'foo'
         1        DO_FCALL                                      0          
   5     2      > RETURN                                                   1

As you can see, INIT_NS_FCALL_BY_NAME is gone. This is one of the many optimizations applied by PHP 7 and newer versions (see zend_compile.c for more examples).

Benchmark

All of the above sounds like a silly and pointless micro-optimization, but it makes a huge difference when it comes to commonly and widespread libraries.

In order to state the point more clearly, some benchmarks are provided with this package.

Simply run php -n ./vendor/bin/phpbench run --revs=1000 --iterations=10 --warmup=2 --report=aggregate from within this project:

$ php -n ./vendor/bin/phpbench run --revs=1000 --iterations=10 --warmup=2 --report=aggregate
PhpBench 0.13.0. Running benchmarks.
Using configuration file: FunctionFQNReplacer/phpbench.json

\RoaveBench\FunctionFQNReplacer\AbsoluteFunctionReferenceBench

    benchCallUserFuncWithRelativeReferenceI2 P0 	[μ Mo]/r: 2.603 2.586 (μs) [μSD μRSD]/r: 0.034μs 1.31%
    benchCallUserFuncWithAbsoluteReferenceI2 P0 	[μ Mo]/r: 1.767 1.635 (μs) [    benchCallUserFuncWithAbsoluteReferenceR3 I2 P0 	[μ Mo]/r: 1.793 1.799 (μs) [μSD μRSD]/r: 0.009μs 0.53%

2 subjects, 6 iterations, 200 revs, 0 rejects
(best [mean mode] worst) = 1.780 [2.198 2.192] 1.800 (μs)
⅀T: 13.190μs μSD/r 0.022μs μRSD/r: 0.916%
suite: 133a2c6cc9c7a295d7b89ff84b2cfff4f39d8935, date: 2016-12-22, stime: 23:10:51
+----------------------------------------+---------+---------+---------+---------+---------+--------+---------+
| subject                                | best    | mean    | mode    | worst   | stdev   | rstdev | diff    |
+----------------------------------------+---------+---------+---------+---------+---------+--------+---------+
| benchCallUserFuncWithRelativeReference | 2.642μs | 2.729μs | 2.694μs | 2.839μs | 0.062μs | 2.28%  | +68.78% |
| benchCallUserFuncWithAbsoluteReference | 1.577μs | 1.617μs | 1.610μs | 1.688μs | 0.029μs | 1.77%  | 0.00%   |
+----------------------------------------+---------+---------+---------+---------+---------+--------+---------+

As you can see, call_user_func() vs \call_user_func() is a sensible difference.

Feel free to add benchmarks to the benchmark/ directory.

Installation

This project is not meant to be run as a dependency: please install it as standalone.

composer create-project roave/function-fqn-replacer

Usage

Please beware that this project uses the internal code generator of nikic/php-parser. This means that it will break your coding style when recreating the sources of your PHP files. This is a known and unresolved issue.

./function-fqn-replacer path/to/project/files path/to/existing/functions another/path/to/existing/functions

The first argument is the path to the directory where you want the FQN references to be replaced.

Additional parameters are the paths where function definitions can be found. The tool needs to know these in order to avoid replacing functions that may not be internal.

Alternatives

This tool was built in a rush, but is quite well tested and based on solid background foundations. Still, it will modify whitespace alignment in your source files due to technical limitations of the current PHP AST parser.

If you don't like these consequences, consider using nilportugues/php-backslasher instead, which has been around for more time, and uses a lower level implementation of token replacement which preserves whitespace alignment

More Repositories

1

SecurityAdvisories

🔐 Security advisories as a simple composer exclusion list, updated daily
2,694
star
2

BetterReflection

🔮 Better Reflection is a reflection API that aims to improve and provide more features than PHP's built-in reflection API.
PHP
1,176
star
3

BackwardCompatibilityCheck

🆎 Tool to compare two revisions of a class API to check for BC breaks
PHP
568
star
4

no-leaks

🚰 PHPUnit Plugin for detecting Memory Leaks in code and tests
PHP
496
star
5

Dont

🚫 Small set of defensive programming utilities/traits for PHP
PHP
400
star
6

StrictPhp

🚫 ✨ ❗ AOP-based strict type checks for PHP
PHP
261
star
7

you-are-using-it-wrong

🚔 Type check enforcement for library authors: enforces type-safety downstream
PHP
237
star
8

no-floaters

🔎 static analysis rules to prevent IEEE-754 floating point errors
PHP
207
star
9

infection-static-analysis-plugin

✅ 🐲 Static analysis on top of mutation testing - prevents escaped mutants from being invalid according to static analysis
PHP
121
star
10

psr-container-doctrine

Doctrine Factories for PSR-11 Containers
PHP
95
star
11

shorty

An asynchronous SMPP client and server built on Node.js. Shorty is sponsored and maintained by SMS Cloud, a subsidiary of Roave
JavaScript
92
star
12

DoctrineSimpleCache

Doctrine Cache adapter for PSR-16 Simple Cache
PHP
57
star
13

DocbookTool

📚 Docbook Tool for static documentation generation from Markdown files
PHP
53
star
14

Signature

✒️ Generate and verify basic signature for classes
PHP
43
star
15

behat-psr11extension

PSR-11 Container extension for Behat
PHP
40
star
16

composer-gpg-verify

🔐 📦 composer plugin to enforce GPG signatures on downloaded GIT composer packages
PHP
39
star
17

zf2-for-1

Enables using Zend Framework 2 features in a Zend Framework 1 application.
PHP
34
star
18

RoaveDeveloperTools

A PHP application visualization/debugging tool for ZendFramework/Symfony
PHP
29
star
19

psalm-html-output

Psalm HTML output format
XSLT
21
star
20

issues

Dead simple issue tracker (think standalone Github issues clone)
PHP
19
star
21

billing

open source php billing and invoicing
PHP
16
star
22

EmailTemplates

PHP
14
star
23

SecurityAdvisoriesBuilder

🔨 Build tools responsible for assembling https://github.com/Roave/SecurityAdvisories/blob/master/composer.json
PHP
10
star
24

RoaveDbCriteria

Use Doctrine Collections expressions with Zend\Db\Sql for smart criteria / filtering / query building.
PHP
6
star
25

NonceUtility

PHP
5
star
26

Assistant

Browser-based virtual assistant framework.
JavaScript
5
star
27

LaravelInfinidash

AWS Infinidash integration for Laravel applications
4
star
28

MtdTimeTracker

Simple time tracker
PHP
4
star
29

zf1-migration

Enables using newer Zend Framework features in a Zend Framework 1 application for easier migration.
PHP
3
star
30

tickets

Ticket thingy
PHP
2
star
31

roave.github.io

The Roave website.
JavaScript
2
star
32

roave.com

Roave.com website
CSS
2
star
33

DPC-Tutorial

ZF2 DPC Tutorial
PHP
2
star
34

Phlam

PHP Lambda runnner for running functions as a service on AWS
2
star
35

RoaveBot

Out little IRC campanion for #roave on Freenode.
CoffeeScript
2
star
36

RoaveTrack

This repository will somehow solve all of Roave's operational needs one day.
1
star
37

Realpath

Realpath, yo!
PHP
1
star
38

smscloud-shorty

Shorty implementation used by SMS Cloud in production.
JavaScript
1
star
39

roave.com-gh

New design for Roave.com
1
star
40

RoaveCast

Experiment(s) in real-time video/audio broadcasting to browsers.
1
star
41

demo-automatic-releases

Nothing to see here: we're just playing with github hooks
1
star