Self-contained PHP app¶
PHP programs usually need a runtime installed on your target machine, appropriate version of PHP itself, a web server and some sort of configuration. This is no longer needed when you are compiling PHP code into .NET. The PHP web or console program can be distributed as a self-contained executable with no such dependencies.
Preqrequisites¶
The only initial prerequisite for the development environment is the .NET 8 SDK. However, this is only needed during development; after you create your self-contained executable, this is no longer required.
Simple PHP console program¶
Let’s start with the basics. Create a small console application (you can grab it from github.com/iolevel/peachpie-samples/console-application):
main.php
:
program.msbuildproj:
<Project Sdk="Peachpie.NET.Sdk/0.9.42">
<PropertyGroup>
<OutputType>exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<StartupObject>main.php</StartupObject>
</PropertyGroup>
<ItemGroup>
<Compile Include="**/*.php" />
</ItemGroup>
</Project>
PICTURE MISSING HERE
To just run it, try this command on your favorite shell: dotnet run
Simple PHP web site¶
A compiled web site is almost the same as the console program above. The most notable difference is that we include the lightweight ASP.NET Core web server in C# together with the PHP code. Grab the project at github.com/iolevel/peachpie-samples/web-application, or create the project as described on https://docs.peachpie.io/get-started/.
Note: the web server is now a part of the PHP web site. You don’t have any dependencies on Apache, IIS or anything else.
Creating the executable¶
Let’s start by typing the following command in your terminal:
dotnet publish -c release
This compiles the project(s) into binaries, using the release build configuration, and places the result of the compilation into the /bin/release/netcoreapp2.1/publish
folder. But this still has a dependency on the .NET runtime – it’s not a self-contained executable just yet!
Next, we have to know what system we are targeting. Take a look at Microsoft's documentation, where you can see different runtime identifiers (RIDs). By specifying the RID, you create the real self-executable that runs without any other dependency on the specified system. For example, let’s build the application for 64bit Windows:
dotnet publish -c release -r win-x64
Or for Linux:
dotnet publish -c release -r linux-x64
That’s it. This creates a native executable for the platform of your choice. For more information on the publishing process, check out Microsoft's docs.
Reducing the executable size¶
The most frequent question regarding self-executables is how to reduce the size of such an application. Since you are including the entire .NET runtime together with your executable, the size is unnecessarily big. There are, however, a few recommended approaches you can take advantage of in order to reduce the executable size:
- On Linux, you can get rid of culture-specific functionalities and keep just the “Invariant” culture features. This cuts about 26MB of data. Details here.
- Use
dotnet-warp
to merge DLL files and remove unnecessary IL and methods. Read more in Scott Hanselmann’s blog post. A little note: rename the project file so it has the.csproj
extension, it will work just fine.
Obfuscation¶
Another question we often get asked: can we obfuscate the compiled code? You can, but keep in mind that PHP strongly depends on reflection and function names, so although you can indeed use any .NET tool for the obfuscation, I would recommend not to rename method names, class names and class members. You can obfuscate the IL or metadata, however.
Conclusion¶
Taking full advantage of all the amazing .NET Core tooling, we can now create self-contained PHP applications, with a built-in the web server. It is pretty simple, source-less, and relatively small, and yet another interesting benefit of the bi-directional interoperability PeachPie compiler provides for PHP and .NET.
Resources¶
- RIDs: docs.microsoft.com/en-us/dotnet/core/rid-catalog
dotnet-warp
: hanselman.com/blog/BrainstormingCreatingASmallSingleSelfcontainedExecutableOutOfANETCoreApplication.aspx- PeachPie getting started: https://docs.peachpie.io/get-started
dotnet publish
: docs.microsoft.com/dotnet/core/tools/dotnet-publish- More samples: github.com/iolevel/peachpie-samples
- ASP.NET Core Web Server: docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/