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.
The only initial prerequisite for the development environment is the .NET Core 2 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):
<?php echo "Hello world!";
<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>
And that’s actually it. Now you can do everything you are used to doing with a regular .NET Core application, including building, running, or publishing as a self-contained package (as shown below).
To just run it, try this command on your favorite shell:
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 peachpie.io/getstarted.
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 the following page, where you can see different runtime identifiers (RIDs): docs.microsoft.com/dotnet/core/rid-catalog. 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 docs.microsoft.com/dotnet/core/tools/dotnet-publish.
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.
dotnet-warpto merge DLL files and remove unnecessary IL and methods. Read more in Scott Hanselmann’s blog post
hanselman.com/blog/BrainstormingCreatingASmallSingleSelfcontainedExecutableOutOfANETCoreApplication.aspx. A little note: rename the project file so it has the
.csprojextension, it will work just fine.
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.
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.
- RIDs: docs.microsoft.com/en-us/dotnet/core/rid-catalog
- PeachPie getting started: peachpie.io/getstarted
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/