WordPress on .NET 4.0


WordPress is an open-source content management system (CMS) built using PHP and MySQL. It’s one of the most frequently used solutions for blog publishing. In this article I describe how to compile this PHP application to .NET Framework 4.0 using Phalanger.

Contents

  1. Motivation
  2. Requirements
  3. Copy to publishing location
  4. Set-up IIS
  5. Configure ASP.NET using Web.config
  6. MySQL configuration
  7. Precompilation
  8. WordPress installation
  9. Settings permalinks (nice URLs)

Motivation

Why would you want to run WordPress as a .NET application? There are several good reasons:

  • If you are working for a customer who requires using the .NET platform, you can compile WordPress using Phalanger and it will run as a native .NET application.
  • Applications compiled using Phalanger are very efficient. They outperform standard PHP installation. We will write about performance comparison in some later article.
  • Thanks to Phalanger, it is easier to access .NET functionality from your PHP code. Therefore plugins using .NET functions are easily done. In some future article, we will look how to integrate WordPress with ASP.NET.
  • Extending WordPress can be done even in a .NET language like C#.
  • Syntactic and semantic errors may occur in PHP in run time, but compilation process in Phalanger discoveres them right away.

Now let’s look at the steps that are needed to compile and run WordPress using Phalanger.

Requirements

Before you can continue, you need to download and install the following software:

Copy to publishing location

First copy WordPress into its directory in wwwroot of IIS (or any other virtual directory). In this tutorial I will be using c:\inetpub\wwwroot\wordpress\ as a directory for WordPress. Set write and modify permissions for IIS_IUSRS on this folder. This is necessary since WordPress creates wp-config.php file during the installation. Also WordPress needs the write permission to allow auto update feature, downloading themes, plugins,… If you won’t allow this you can create the configuration file manually during the installation. WordPress recognizes that it doesn’t have permissions to create the file and gives you content for this file. Then you can create the file manually.

To set the permissions, open Command Prompt with the Administrator permissions  and run the following command:

1 icacls c:\inetpub\wwwroot\wordpress /grant BUILTIN\IIS_IUSRS:(OI)(CI)(M)

Set-up IIS

As any other ASP.NET application, WordPress compiled with Phalanger will have to run in some application pool. For our purposes we create application pool called Phalanger v2.1 and set it to .NET Framework v4.0. After creating the pool, you need to go to Advanced Settings and set “Enable 32-Bit Applications” to True (if you have 64bit operating system). This is necessary, because Phalanger uses native PHP extensions that are compiled as 32bit DLLs.

Advanced Settings of Application Pool

Then we create a web application from c:\inetpub\wwwroot\wordpress virtual directory and associate it with Phalanger v2.1 app pool. All of this can be done just by running following commands:

1 %systemroot%\system32\inetsrv\appcmd.exe add apppool /name:"Phalanger v2.1"
2 %systemroot%\system32\inetsrv\appcmd.exe set apppool "Phalanger v2.1" /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated /enable32BitAppOnWin64:"true"
3 %systemroot%\system32\inetsrv\appcmd.exe add app /site.name:"Default Web Site" /path:/wordpress /physicalpath:C:\inetpub\wwwroot\wordpress
4 %systemroot%\system32\inetsrv\appcmd.exe set app /app.name:"Default Web Site/wordpress" /applicationPool:"Phalanger v2.1"

This script uses Default Web Site for WordPress, but you can create Web Site just for WordPress or use any IIS Web Site you have configured in IIS.

Configure ASP.NET using Web.config

Create web.config file in the root directory of WordPress. In this tutorial the path will be c:\inetpub\wwwroot\wordpress\web.config. Copy the following content into your web.config. I will explain just some parts of this configuration, but for a complete explanation of all configuration elements look at http://wiki.phpcompiler.net/Configuration.

1 <?xml version="1.0" encoding="utf-8"?>
2 <configuration>
3   <system.webServer>
4     <handlers>
5       <add name="Phalanger" path="*.php" verb="*" type="PHP.Core.RequestHandler, PhpNetCore, Version=2.1.0.0, Culture=neutral, PublicKeyToken=0a8e8c4c76728c71" />
6     </handlers>
7     <defaultDocument>
8       <files>
9         <add value="index.php" />
10       </files>
11     </defaultDocument>
12     <httpErrors errorMode="Detailed">
13        <clear />
14     </httpErrors>
15   </system.webServer>
16   <system.web>
17     <globalization responseEncoding="utf-8" fileEncoding="utf-8" />
18     <httpRuntime requestPathInvalidCharacters="" requestValidationMode="2.0" />
19     <pages validateRequest="false" />
20   </system.web>
21   <phpNet>
22     <compiler>
23       <set name="EnableStaticInclusions" value="true" />
24     </compiler>
25     <classLibrary>
26       <add assembly="PhpNetMySql, Version=2.1.0.0,Culture=Neutral,PublicKeyToken=2771987119c16a03" section="mysql" />
27       <add assembly="php_xml.mng, Version=2.1.0.0, Culture=neutral, PublicKeyToken=4ef6ed87c53048a3" section="xml" />
28       <add assembly="php_image.mng, Version=2.1.0.0, Culture=neutral, PublicKeyToken=4ef6ed87c53048a3" section="image" />
29       <add assembly="php_zlib.mng, Version=2.1.0.0, Culture=neutral, PublicKeyToken=4ef6ed87c53048a3" section="zlib" />
30     </classLibrary>
31     <error-control>
32       <set name="DisplayErrors" value="false" phpName="display_errors" />
33     </error-control>
34     <globalization>
35       <set name="PageEncoding" value="utf-8" />
36     </globalization>
37     <bcl>
38       <mailer>
39         <!-- SMTP server name used for sending e-mails. -->
40         <set name="SmtpServer" value="127.0.0.1" phpName="SMTP" />
41         <!-- SMTP server port used for sending e-mails. -->
42         <set name="SmtpPort" value="25" phpName="smtp_port" />
43         <!-- The default value of "From" header. -->
44         <set name="DefaultFromHeader" value="[email protected]" phpName="sendmail_from" />
45       </mailer>
46     </bcl>
47   </phpNet>
48 </configuration>

First we have to set IIS to recognize *.php files and send all the requests for these files to Phalangers request handler. This is done in system.webServer/handlers section.

In system.web section we have to turn off default ASP.NET request validation. Usually this prevents script injection attacks, but also prevents sending html during posts and pages editing. We have to leave these controls for WordPress to handle.

All the other Phalanger related configurations are child elements of phpnet element. Class library section defines what PHP extensions WordPress needs (Phalanger installer already adds some of them into machine.config, but you can list them again, to have a track of all the extensions that application needs). The extensions we have in this sample configuration file are basic extensions that WordPress needs. If you install some plugin make sure to add necessary PHP extensions to this configuration.

We set DisplayErrors to false because this web.config is not intended for development, but for production. We don’t want to show warnings (potentially containing sensitive information) to our users. If you enable errors, you can see that Phalanger does more checks than normal PHP. Many possible run-time errors are prevented just by looking at the warnings given during the compilation so you can fix them immediately.

MySQL configuration

The web.config file we discussed uses managed MySql extension (available at http://phalangermysql.codeplex.com), which we strongly recommend to use. It provides around 30% performance benefit over native PHP extension (taken from PHP distribution). However if you decide to use native PHP extension you will have to set password through OLD_PASSWORD not PASSWORD function. To initialize the WordPress database and create a user, you need to run the following command from MySQL Command Line Client as root:

1 CREATE DATABASE wp;
2 CREATE USER 'wp_user'@'localhost';
3 SET PASSWORD FOR 'wp_user'@'localhost'= PASSWORD('password');
4 GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON wp.* TO 'wp_user'@'localhost';
5 FLUSH PRIVILEGES;

Precompilation

Phalanger compiles the source code to a .NET assembly that is then compiled to native code by the .NET runtime and executed.  It is not necessary to precompile the web page; sigle scripts will be compiled during first requests subsequently. However it is recommended to precompile the application to make sure the application is errors free and to lower response time during first request. Create build.bat in the wordpress directory with the following content:

1 C:\Program Files\Phalanger 2.1\Bin\phpc /target:web /root:. /recurse:. /out:Bin /static+ /debug-
This batch file runs the Phalanger compiler to perform the pre-compilation. Detailed documentation for each of phpc option can be found at http://wiki.phpcompiler.net/Phpc.exe (Don’t worry, it is not link to a virus :-) ) Just to briefly explain the options we used:
  • /target:web Phalanger compiles whole page into WebPages.dll module
  • /recurse:. Phalanger will precompile recursively whole directory and its subdirectories
  • /static+ means to use static includes optimization
  • /debug- tells the compiler to generate more optimized code and not to generate debugging information (pdb files) WordPress installation

WordPress Installation

Type http://localhost/wordpress and follow the installation. After installation of WordPress (when wp-config.php file is created) we recommend to recompile it again (using the batch file we created). The same applies if you download new theme or a new plugin. Generally, re-compiling the source code is useful when some files are changed or added (for same reasons as explained in precompilation section). Then type the URL again, wait a moment (during the first request JIT compiles the application to native code and Phalanger loads all the extensions, so it takes some time) and here is your “Just another WordPress site” on .NET 4.0.

WordPress screen

Settings permalinks (nice  URLs)

Permalinks allow you to use a nice URL such as http://www.php-compiler.net/blog/2011/wordpress-on-net-4-0 instead of http://www.php-compiler.net/?p=113. To get nice URLs in WordPress (http://codex.wordpress.org/Using_Permalinks)  it is necessary to install Microsoft URL Rewrite Module (http://learn.iis.net/page.aspx/460/using-url-rewrite-module/). The module is available for x64 and x86 systems. When installed add the following rule to system.webServer element of your web.config:

1 <rewrite>
2   <rules>
3     <rule name="Main Rule" stopProcessing="true">
4       <match url=".*" />
5       <conditions logicalGrouping="MatchAll">
6         <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
7         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
8       </conditions>
9       <action type="Rewrite" url="index.php/{R:0}" />
10     </rule>
11   </rules>
12 </rewrite>

After this is done go to Dashboard of administration section of WordPress, section Settings – Permalinks, and set the URL you want, e.g. “/

,

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

验证码 * Time limit is exhausted. Please reload CAPTCHA.