Working towards PHP interoperability with .NET

After making an appearance on Microsoft’s “On .NET” live stream to discuss Peachpie, we have been busy working on the compiler itself. One of the aspects we have particularly been focusing on is the PHP interoperability with .NET, where we have been making massive strides.

Proof of Concept

It is imperative to mention that some of the features described below are not complete and final yet. We are focused on creating as many useful demonstrations of the potential of Peachpie as possible. You can look at the features as proof that the concept works, but please be aware that not all eventualities and behavioral exceptions are supported at this point.

Include/Require – PHP script inclusion from C#

We have been asked about the include/require function several times and we are pleased to announce that we have now “included” this functionality in Peachpie. In essence, script inclusion resolves the target full file name and lookup into a hashtable. Subsequently, an indirect call to the script’s global code is performed.

Peachpie, however, compiles the script unit global code into the static method “Main”and thereby provides two ways of invoking them:

  1. In compile time: if possible, the compiler emits a direct call to the Main method with no additional overhead.
  2. In runtime: it is possible to lookup in the available script units and call their Main method indirectly.

In order to demonstrate this, let’s look at a little example. In PHP, “include_once” is compiled as follows:

[csharp]
if (context.CheckIncludeOnce<test.php>()) test.php.<Main>(context, locals);
[/csharp]

Context is a variable managed by runtime, referring to the Pchp.Core.Context class instance, which contains all the information that the current thread needs. Locals is an array refrering to the array of local variables. Test.php is actually a class name containing the declaration from the script unit of the same name. Finally, <Main> is a special static method representing the script unit global code.

The exciting part of the demo is performing the inclusion from the C# code:

[csharp]
context.Include(null, "test.php");
[/csharp]

In case you are interested – the important part of PHP inclusions is the handling of already included script units, so that include_once will skip the process in case the script has already been included.

This is a tremendously important feature, which should have as little overhead as possible since it is used all the time.

Peachpie resolves this directly, without any lookup into hashtables. Using .NET generics, it assigns a unique ID to each script unit, which means that the inclusion check is reduced to a simple check in a bit array.

Accessing Global PHP Variables from C#

Although the use of global variables is usually not recommended, it is an important part of the PHP language. The collection of these globals is represented using a common PHP array.

Peachpie manages and provides global variables that can be programatically accessed and modified. This enables us to pass objects and values into PHP scripts as global variables if needed, and to read them back after calling a PHP stub.

Here is an example in C#, which adds/updates the global variable $g with an object instance:

[csharp]
context.Globals["g"] = new SomeClass();
[/csharp]

As you can see, we are consistently working towards a PHP interoperability with .NET and we have implemented several features that you have been asking us about. If there are any other tricky intricacies of PHP that you believe are important to integrate, feel free to let us know.

Posted on May 9, 2016, in category News, tags: , , , , , , ,