Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to automatically determine which PHP extensions are used by a project?

Tags:

php

Is there a way to automatically find out which PHP extensions are used by a particular project you have the source code of?

When migrating a website from a one server to another, I often find myself wondering what PHP extensions should I enable for the website to function normally. Yes, this use case would probably be irrelevant if the project used Docker or had an exhaustive install guide, but it's not always the case.

I was thinking of a script that went through all of the .php files and looked for specific function calls or classes, for exeample:

  • new mysqli( or mysqli_connect(: mysqli
  • imagecreate( or imagepng or imagejpeg or ... : gd
  • curl_init( : curl

Does a similar script already exist? If not, would it make sense to write it?

like image 291
Dario Spagnolo Avatar asked Dec 02 '15 11:12

Dario Spagnolo


People also ask

How do you find out what php extensions are installed?

If your server only has a single PHP version installed, you can run this PHP command anywhere, and it will give you the same list of modules. The general command we will be using is php -m. This command will give you the full list of installed PHP modules/extensions.

How are php extensions defined in the php preprocessor?

php file extension refers to the name of a file with a PHP script or source code that has a ". PHP" extension at the end of it. It's similar to a Word file with a . doc file extension.


2 Answers

I can suggest 2 different approaches: Composer and PHP CompatInfo.

Composer

For a Composer project with dependencies installed, you can check the requirements using the command

composer check-platform-reqs

Note that it does not analyse the code, it only checks information from composer.lock file OR files in vendor directory, whichever exists.
Example of result:

composer-plugin-api  1.1.0                                                    success
ext-ctype            7.2.24                                                   success
ext-curl             7.2.24                                                   success
ext-dom              20031129                                                 success
ext-zip              n/a       phpoffice/phpspreadsheet requires ext-zip (*)  missing
php                  7.2.24                                                   success

Developers of packages should include information about required PHP extensions in require section of composer.json, e.g. "ext-curl": "*".
Obviously, the effectiveness of this method highly depends on the punctuality of developers but this check is fast and easy to use.

PHP CompatInfo

The latest version and development documentation can be found here.
The end-user documentation can be found here, also you can download a PHAR file from there, but it may be outdated (currently it hosts version 5.0.12 while GitHub and Packagist has 5.4.2).
The recommended way to install this library is through Composer.
I suggest installing it separately, not in project which you want to test because:

  • PHP CompatInfo also requires some PHP extensions and you want to test your own project without addition of extra dependencies.
  • PHP CompatInfo may require versions of packages which conflict with your project, e.g. version 5.4.2 requires symfony/config: ^4.4|^5.0, if your project already requires symfony/config: ^3.0 then you unable to install the latest version of PHP CompatInfo as part of this project, even though your system may allow it.

Run outside of the project which you want to test:

  1. composer create-project bartlett/php-compatinfo - this command will install PHP CompatInfo and all its dependencies including development dependencies and then build a PHAR file. If you have problems with installation of development dependencies you may omit them composer create-project --no-dev --no-scripts bartlett/php-compatinfo, in this case the PHAR file also will not be built, but it is not required anyway.

  2. cd php-compatinfo
    composer run post-install-cmd - this command will build the SQLite database which PHP CompatInfo requires. This operation should not be executed in a production environment! If you want to run PHP CompatInfo in a production environment, then you should check its documentation.

  3. ./bin/phpcompatinfo analyser:run --progress ../path/to/project - this command will analyse the code and may produce a huge report, but there should be something like this at the beginning:

    Extensions Analysis
    
        Extension REF      EXT min/Max PHP min/Max
        Core      Core     5.1.0       5.1.0
        json      json     5.2.0       5.2.0
     C  mongo     mongo    0.9.0       5.0.0
        pcre      pcre     4.0.0       4.0.0
        session   session  4.0.0       4.0.0
        standard  standard 5.2.3       5.2.3
        Total [6]                      5.2.3
    

For details see the aforementioned documentation and built-in help:

  • Help message

    ./php-compatinfo/bin/phpcompatinfo --help
    
  • List available commands

    ./php-compatinfo/bin/phpcompatinfo list
    
  • Help message about command

    ./php-compatinfo/bin/phpcompatinfo analyser:run --help
    

Troubleshooting

PHP CompatInfo is unable to parse invalid PHP code, so if you got a Fatal error during analysis then that may be the reason. Some packages may include testing files with incorrect PHP code which are never executed but used for testing, example of such a package is squizlabs/php_codesniffer. I suggest to temporarily remove the entire package or only its tests to avoid errors during analysis.

Interpretation of results

PHP CompatInfo may produce false-positive and false-negative results.

Example of false-negative: the library can detect that your project uses PDO, but unable to detect whether it is used with pdo_mysql or pdo_pgsql driver or something else. Although I bet you know which database you are using.

Example of false-positive: some PHP frameworks and libraries may contain classes to work with numerous services intended to the same purpose. For example Yii 2 framework has classes to work with APC, APCu, memcache, memcached and XCache. PHP CompatInfo will list all these extensions but this does not mean that they are really used in the project, you have to figure out yourself. The same situation is possible for image processing PHP extensions GD, Gmagick and Imagick and other extensions.

like image 70
kdmitry Avatar answered Nov 15 '22 17:11

kdmitry


Writing as answer as requested by OP in their comment

glenscott/php-dependencies

Although not a complete solution, this will lessen the manual work you'll have to do: https://github.com/glenscott/php-dependencies

A few caveats are;

  • Your source code and its dependencies must lie under one directory -- included/required files outside this directory are not scanned
  • As it stands, only function dependencies are found. This means that class dependencies are not checked.

You can read the blog post by the author here: http://www.glenscott.co.uk/blog/finding-function-dependencies-in-your-php-applications/

To run

You can do these via the command line or through a web browser.

  • Step 1) Getting PHP environment details: php get-env-functions.php

  • Step 2) Find dependencies: php scan-dependencies.php

like image 20
ʰᵈˑ Avatar answered Nov 15 '22 18:11

ʰᵈˑ