Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

PHP on .NET With Peachpie Compiler

DZone's Guide to

PHP on .NET With Peachpie Compiler

PHP has a reputation as a performance bottleneck. The Peachpie compiler improves performance while adding cross-platform functionality.

· Performance Zone ·
Free Resource

Container Monitoring and Management eBook: Read about the new realities of containerization.

Following Gunnar Peipman's article about running PHP applications on .NET Core, and the official inclusion of the Peachpie project into the .NET Foundation, it seems like a good idea to dissect this strange-sounding technology and look into its history, as well as why it exists. 

Disclaimer: I am a member of the core development team of Peachpie. This article is neither an endorsement of the project nor an advertisement for any products related to it. It has merely been written for informative purposes.

PHP on .NET - What a Crazy Idea

PHP has been one of the most popular and widespread programming languages in the world for a long time, powering some of the web's biggest sites, such as Facebook, Yahoo, Wikipedia or WordPress. The open-source PHP language excels through its intuitive and efficient syntax, ease of configuration and particularly thanks to the plethora of available resources and vibrant community. For newly founded companies only some five years ago, it seemed like the ideal technology to get started: it was free and took a mere couple of minutes to get set up. 

However, if you so much as Google the language a little, it rapidly becomes clear that the PHP language doesn't exactly have the most stellar reputation among software developers. Programmers particularly tend to lament the language's inner workings and the fact that PHP developers often don't exactly follow conventional programming best practice, but the implications of this can have a negative impact on business as well if not properly handled. PHP is known to be somewhat of a performance bottleneck, often unable to handle large amounts of concurrent traffic, and its blatant security shortcomings have even made it into the news. Remember the infamous Panama Papers scandal, in which 11.5 million documents containing sensitive data were leaked from the website of Panama-based law firm Mossack Fonseca, unveiling the financial dealings of hundreds of celebrities? Well, it just so happens that this scandal was made possible by a leak in the popular "Revolution Slider" plugin for WordPress, the Content Management System the law firm's website was built in. Both the plugin and WordPress are written in - you guessed it - PHP; not exactly helpful for the language that is struggling to maintain its popularity. 

And yet, despite these mishaps and the downpouring of criticism from the programming community, PHP continues to be the most widely used language in the world and chances are that it will always remain number one. So rather than choosing other technologies, software developers have often been turning to attempts at connecting PHP with platforms that will cushion the disadvantages of PHP. This is where .NET comes into play.

Enter Phalanger

While PHP is a dynamic language interpreted as it is being executed, the .NET Framework is a set of languages that are compiled ahead of being run into MSIL bytecode and therefore distributed in .dll format without having to reveal the source code. Unlike the open-source PHP, .NET is backed by the software giant Microsoft and therefore constantly being developed and optimized. Not very surprisingly, .NET is thus significantly faster and more secure than PHP. 

And this is exactly why a university research project was started in 2005 at the prestigious Charles University in Prague, Czech Republic: to see if it would be possible to connect these two seemingly distant worlds. The research project dubbed Phalanger (a portmanteau of PHP Language Compiler) was first and foremost a proof of concept that it is actually possible to compile a dynamic language such as PHP into the intermediate bytecode of a statically-typed language such as .NET. Once it became clear that it is, in fact, possible, the group of talented students had to write millions of lines of code, re-implementing every PHP construct and function to be executed in the .NET runtime. They succeeded.

Phalanger was capable of running entire real-world PHP applications (up to PHP 5.4 at the time) on .NET with significant performance benefits. Several companies, such as the UK-based Jadu, used Phalanger in production. Eventually, however, the original team moved on to Microsoft or Facebook, and the development of the project slowly stopped until it was only maintained sporadically. 

Peachpie, the Modern PHP Compiler to .NET

Years went by until, in early 2016, a new project emerged, claiming to be the successor to the popular Phalanger compiler - Peachpie. Best of all, the team developing it has remained the same. So why develop a new compiler?

In short, Microsoft's development of late. Back in 2012, .NET was entirely closed-source and paid. This all changed as Microsoft under Satya Nadella embraced open-source. The software giant from Redmond, in fact, developed a stripped-down, modular, and lightning fast version of .NET called .NET Core, which is entirely open-source. This new framework works on any operating system and device, making it suitable for tablets, phones, or IoT devices. What Phalanger could do only with significant efforts by hacking around a way to compile PHP for Mono, Peachpie can do by default. Furthermore, Microsoft has devoted years worth of development to its so called Roslyn Compiler Platform, on top of which Peachpie has been built, which offers further performance enhancements and many other benefits.

Cross-Platform and Lightning Fast

While .NET has come a long way since 2012, PHP has by no means stagnated either. All existing benchmarks clearly depict the most impressive performance enhancement the PHP development team has been able to achieve from version 5.4 to 7.1. So much so that the first measurements conducted on sample applications with Peachpie showed that the performance of PHP 7 compared to the compiled version were often on par. The project website does show a multitude of benchmarks conducted on individual constructs that point to large performance improvements thanks to Peachpie, and third parties have also presented very promising results, but the fact that Peachpie-compiled applications (albeit not optimized) are just as fast as regular PHP 7 is mighty impressive. 

What's the Point If It Isn't Faster Yet?

First and foremost, as a member of the core development team of the project, I can say that performance has absolutely not been our main concern up to now. The focus is solely on getting to version 1.0, i.e. making sure that we achieve a full compatibility with the PHP language so that entire real-world applications can be run. Only then are we going to start optimizing and attempting to outperform PHP 7. 

Peachpie features

But that doesn't mean Peachpie isn't useful until then. In fact, performance is only a side effect and the real benefits are a bit more subtle. As Scott Hanselman recently described, probably the most mind-boggling feature of Peachpie is the ability to seamlessly interoperate between PHP and .NET. Check out the small code snippet below:

using Peachpie.Web;

namespace peachweb.Server
{
    class Program
    {
        static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseUrls("http://*:5004/")
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }

    class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // Adds a default in-memory implementation of IDistributedCache.
            services.AddDistributedMemoryCache();

            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(30);
                options.CookieHttpOnly = true;
            });
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseSession();

            app.UsePhp(new PhpRequestOptions(scriptAssemblyName: "peachweb"));
            app.UseDefaultFiles();
            app.UseStaticFiles();
        }
    }
}

Did you notice? In line 37:  app.UsePHP(new PhpRequestOptions(scriptAssemblyName: "peachweb")) . Just like that, injecting PHP into a C# project.

The implications of this are obviously vast; extending WordPress, Symfony or Drupal sites with C# plugins, running popular e-commerce solutions written in PHP on a .NET stack, seamlessly using PHP libraries in .NET projects or vice versa and distributing or consuming entire PHP applications as NuGet package dependencies. Anything is possible. 

Not to mention the previously described cross-platformity feature of Peachpie thanks to .NET Core, which allows PHP developers to explore previously unchartered territory, such as app development or IoT. 

Here to Stay

Unlike Phalanger, which eventually slowed down and stopped altogether, Peachpie will be around for a while. It was recently inducted into the .NET Foundation, the independent organization backed by Microsoft that fosters and supports open-source development. Therefore, individuals and companies who are interested in using Peachpie in production can rest assured that there will always be someone developing and maintaining the project.

Best of all, you can be a part of the development. If you are interested in including a PHP library in your .NET project, you can simply implement the necessary functionalities in a pull request to the project. 

Resources:

  1. Project source code

  2. Project website

  3. Benchmarks

  4. Getting started

  5. Roslyn source code

  6. Ben Adams' benchmarks

Take the Chaos Out of Container Monitoring. View the webcast on-demand!

Topics:
php ,.net ,compiler ,performance ,jit ,.net core

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}