In this article you will find out how to pinpoint all the potential issues in regular PHP code by taking advantage of fast compiler-based static program analysis, provided as a part of the PeachPie project.
Here’s our scenario: we have a folder with a complete PHP program and we’d like to perform analysis to reveal possible issues – maybe issues that other static analysis tools don’t recognize. And we are going to do that without actually running the code.
C:\Projects\MyAwesomePhpWeb>
1. Prerequisites
The tool requires the .NET Core SDK; currently, it is best to pick version 3.0 or newer.
2. Project file
Th project file describes where your PHP files are located, what diagnostics should be ignored, and much more. We’re only interested in these properties for now. Create an XML file named MyAwesomePhpWeb.msbuildproj
in your program folder with the following content:
<Project Sdk="Peachpie.NET.Sdk/0.9.600">
<PropertyGroup>
<OutputType>library</OutputType>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>7.4</LangVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="**/*.php" />
</ItemGroup>
</Project>
<Compile>
takes a semi-colon separated list of wildcards. In case your PHP files have several different file extensions, such as .php5
or .inc
, add them to the list:
<Compile Include="**/*.php;**/*.php5;**/*.inc" />
3. Diagnose the code!
Now you can run the diagnostics and see the results.
> dotnet build
\wp-admin\includes\class-pclzip.php(2742,19): warning PHP5007: Undefined variable: $v_file [MyAwesomePhpWeb.msbuildproj]
\wp-admin\includes\class-pclzip.php(1279,14): warning PHP5006: Call to undefined function: ‘PclErrorCode’ [MyAwesomePhpWeb.msbuildproj]
\wp-admin\press-this.php(26,24): warning PHP5008: Class ‘WP_Press_This_Plugin’ not found [MyAwesomePhpWeb.msbuildproj]
\wp-includes\compat.php(355,23): warning PHP5008: Class ‘ResourceBundle’ not found [MyAwesomePhpWeb.msbuildproj]
\wp-includes\deprecated.php(3933,24): warning PHP5008: Class ‘WP_Press_This_Plugin’ not found [MyAwesomePhpWeb.msbuildproj]
\wp-includes\deprecated.php(3950,24): warning PHP5008: Class ‘WP_Press_This_Plugin’ not found [MyAwesomePhpWeb.msbuildproj]
There are hundreds of various diagnostics. PeachPie performs an extensive type analysis, resolves the use of deprecated constructs, checks uses of NULL and much more. The most interesting diagnostics are described on the diagnostics documentation page.
Configuration
The entire configuration takes place within the project file. Take a look at all the properties that affect the analysis on
https://docs.peachpie.io/php/msbuild
<NoWarn>
Disables specific warning messages. The warnings are identified by their ID (e.g. PHP5006
) and can be separated by a comma or a space.
<NoWarn>PHP5006,PHP0125</NoWarn>
The sample above disables the reporting of a call of an undefined function and declaring a mandatory parameter behind an optional parameter.
<ShortOpenTag>
The short open tag syntax (<?
) is disabled by default. To enable it, set the ShortOpenTag
property to true
.
<ShortOpenTag>true</ShortOpenTag>
<CodePage>
Specifies the encoding to be used to parse source files. By default, the code page is UTF-8
.
<CodePage>iso-8859-1</CodePage>
Advantages
The analysis is very fast, has a simple setup, discovers more potential problems, and you may combine it with conventional solutions. The resulting list of problems conforms with standard Microsoft reports [filename(line, column): error code: message], which are readable by 3rd party tools and IDE’s. Also, the reporting is column-precise.
Limitations
Diagnostics are built for the world of static languages, which means they can tend to be too strict sometimes. Also, the set of known functions and classes is taken from the PeachPie platform, whose missing features can be found on
https://docs.peachpie.io/compatibility-status/. As a result, you might see ‘unimplemented’ exceptions simply because the given function or feature cannot be handled by PeachPie just yet.
Continuous Integration
It is very good practice to set up continuous testing of your projects. With every commit to your repository, your code will be tested and errors are reported. In case you’re running something like Azure DevOps, diagnostics will be seamlessly displayed in your project dashboard.
In such a case, commit the project file to your project repository. Ensure there is the .NET Core SDK on the server and just trigger dotnet build
on every commit.
Visual Studio Code Integration
If you want to see your diagnostics nicely highlighted in VS Code, grab the extension at https://marketplace.visualstudio.com/items?itemName=iolevel.peachpie-vscode.

Bonus!
If you analyze your code and you get rid of errors, you’ll actually get a standard .NET library file – an assembly – that can be used across the .NET platform just like a standard library or a NuGet package.
Conclusion
In three easy steps, you can check your existing program for errors and possible issues. Perfectly suited for continuous integration. Lightning fast.