Skip to content

PeachPie 1.0.9

It’s been a while since our last update, but the project is still well alive and under active development. Let’s take a look at some of the improvements to the PeachPie compiler platform; we’re continuously working on it to make PeachPie fast and stable for everyday use.

We have been a little more quiet, as we’ve been busy working on our commercial clients’ projects, but the good news is that through our work, we found dozens of bugs and little tweaks the whole community can benefit from. Let’s see what sort of bugs we squashed and what improvements we made.

Improved C# interoperability

PeachPie takes advantage of the .NET platform wherever possible, which means it doesn’t need any buffer overflow fixes. With PHP code compiled with PeachPie, you get access to the whole .NET ecosystem; however, there are a lot of C#/.NET constructs that are not present in PHP just like that – and PeachPie has to deal with it, ideally seamlessly.

More details can be found on

Explicit interface declarations

The first example is properties declared explicitly; on the MSIL level, they look like a private property with a weird name.

interface I {
  int Value { get; }
class X : I {
  int I.Value => 123;

The class X above compiled looks like this:

.class public auto ansi serializable beforefieldinit X
  extends System.Object
  implements I
  .property instance int I.Value() { ... }
  .method private final hidebysig specialname newslot virtual 
    instance int I.get_Value() cil managed
    .override method instance int I::get_Value()

PeachPie did not handle explicitly declared properties, so the following code in PHP failed with an unknown property use error.

echo (new X)->Value; //

This code works now, and PeachPie treats explicitly declared properties as public properties (it grabs the property declaration from the base interface and calls the property getter virtually).

.NET method ref/out parameters

PHP has the concept of passing values by reference (using the &-operator taken from the C languages). Even though .NET uses something similar, the parameters are strongly typed.

PeachPie now handles the .NET ByRef semantic when calling .NET methods.

$dictionary->TryGetValue( 0, $value );
Assuming $dictionary is an instance of System.Collections.Generic.Dictionary<K,V>,

  1. PeachPie compiler implicitly creates a temporary variable of type V, and either it converts $value to V if the semantic is ref (which it isn’t in this case), or it passes default(v) in there.
  2. It calls TryGetValue() with ref semantic.
  3. It implicitly converts back the value of the temporary variable to $value. This is important because this implicit conversion might fail dynamically at runtime. Otherwise, $value is properly initialized with a PHP-like value taken from the C# world.


The last improvement is the implicit support for the System.Collections.Generic.Dictionary generic type. Whenever using the value of type Dictionary<,> in PHP code, it is treated as a regular PHP array, and vice versa. Passing the PHP array to a C# method’s parameter of type Dictionary<,> results in an implicit cast. Note, if array key/value cannot be converted to Dictionary’s K/V, a runtime exception is thrown.

Fixed library functions

There have been a lot of fixes to the existing implementation of PHP functions:

  • curl_exec() maintain cookies during subsequent execs
  • chr() does not corrupt non-printable ASCII characters
  • rawurlencode() to comply with RFC 3986
  • fixes PDO’s commit() and rollback() – pending data need to be disposed
  • fixes stream_socket_accept() and $timeout: previous unfinished accept was not ended, socket server was unusable
  • stream_socket_server() handles the stream context “socket” options

Improved compiler & runtime

Lastly, we’re improving the compiler itself.


The release v1.0.9 brings important fixes and new features to the .NET interoperability. Feel free to grab it, update, or try PeachPie for the first time using our Get Started guide!