A Practical Demonstration of C#/PHP Interoperability

The Peachpie project is finally at a point where it can be used for real world purposes and applications. This article will show some more advanced interoperability options that are now available for you to try.

What you can expect in this article

As you know, Peachpie is a PHP compiler and runtime for .NET and .NET Core, built on top of the Microsoft Roslyn compiler platform. We have our own Visual Studio Code extension, which simplifies working with Peachpie and allows you to do so in a very comfortable IDE.

In this article we will cover:

1. Compiling PHP to .NET Core
2. Debugging PHP functions
3. Using PHP functions in C# and vice versa
4. Inheriting a PHP class in C#

Compiling PHP to .NET Core

Let’s get started. If you haven’t already, please install the Peachpie for VSCode extension. We will open our sample app, which you can find on our samples GitHub repo, and load everything into VSCode. You should restore the NuGet packages by typing the command dotnet restore, to get ready. Don’t worry if you skip this step, the next steps will perform restore anyways.

PS \csharp-php-hybrid> dotnet restore
  Determining projects to restore...
  Restored \csharp-php-hybrid\phplib\phplib.msbuildproj (in 450 ms).
  Restored \csharp-php-hybrid\csharpapp\csharpapp.csproj (in 450 ms).

What’s interesting here is, you didn’t have to download any PeachPie compiler nor interpreter. It is specified as a regular NuGet package dependency in the phplib/phplib.msbuildproj project file. DotNet downloads it for you; and it works anywhere including Windows, Linux, macOS, your build server, or your CI platform on cloud or inside a docker container.

The following command fires up the PeachPie/PHP compiler, C# compiler and produces binary files:

dotnet build

Debugging PHP functions

Our entering script is index.php, which includes two files, creates an object, and calls a method. Take note of the fact that we are not running PHP; we are running PHP code compiled to .DLL. We can now debug the project by pressing F5:

The program stops at the first breakpoint, and this is where the fun begins. Thanks to Peachpie, we now have all the power of .NET – debugging, inspecting variables, the call stack, and if we were to use the full Visual Studio, we can even move the yellow marker to another statement. Naturally, we can also step through the code.

Regular expressions

As we step through the code, we can of course inspect variables, parameters, and properties of objects and arrays. For example, if we execute the function for matching regular expressions, it returns an array:

As we continue executing the program, notice how debugger displays the value of object “User” in curly brackets. In fact, what you see here is the result of the magic __tostring function:

Interoperating between PHP & C#

Let’s call the PHP method “authenticate” by stepping into. What if we were to use this whole PHP library in C#? What if we wanted to use or re-implement some of its PHP functions in C#? Or how about if we’d like to extend the PHP class with a C# derivative? Since Peachpie compiles the whole PHP code to standard .NET, we can do all of this quite straightforwardly.

To demonstrate these interoperability features, there is prepared a small C# app csharpapp, which actually is the main executable program here.

Moreover, this works both ways. Let’s inject the C# lambda function through the Peachpie API into the so-called PHP context:

Instead of the regular expression, we just make sure the .NET Uri object can be created and gets an absolute URL. At the same time, comment out the "is_valid_url()" function in functions.php.

We just replaced a PHP function with a C# function.

Inheriting a PHP class in C#

Another curiosity is the option of having a C# class inherit a PHP class. This is possible because the PHP class looks like any other .NET type to the C# compiler:

PHP classes have generated a CLR constructor, whose signature has a special first parameter as an addition. In order to override it, we have to know the signature. Since the PHP project is compiled, we can take advantage of ILSpy, which decompiles the compiled .DLL file back to C#. We’ll use it to see the C# representation of compiled PHP code and get the constructor signature:

We can browse through the .NET types and functions built from PHP code, our User class, and its fields and methods. We can directly instantiate our C# class, which inherits the one defined in PHP. We just need to pass the first additional parameter, which binds the object to the context.

The implication here is that we can now use a much more advanced .NET user authentication, for example.


Hopefully you enjoyed this tutorial on some of the more advanced interoperability options available with Peachpie. In this article we showed how to compile PHP to .NET Core with VSCode, how to debug PHP, how the both-way interoperability between C# and PHP looks like, and the possibility of C# inheriting a PHP class.

You can also watch the corresponding video tutorial and please make sure to subscribe and follow us on Twitter or GitHub for more interesting material in the coming months.

Posted on January 31, 2017, in category Information, Samples, Tutorial, tags: , , , , ,