Run a PHP HTML editor on Windows IIS
Folder permissions, web.config and the settings that catch people out, from a real IIS install.

A lot of PHP runs on Windows and IIS, and many guides only cover Apache. This one is based on a real setup: this website runs on IIS with PHP 8.5, and uses the same package you download. Here is what matters, and what goes wrong.
Step 1: PHP on IIS
PHP runs on IIS through FastCGI. Check that these are enabled in php.ini:
extension=gd ; dom, libxml, SimpleXML and session are part of a standard PHP build
The GD extension processes images. The exif extension is not needed, since the package reads a photo's orientation itself. Our own server runs without exif or fileinfo.
Step 2: copy the folder and write the page
Copy richtexteditor to the root of your site, then add the editor to a page:
<?php
require_once __DIR__ . '/richtexteditor/phphtmleditor/autoload.php';
$editor = new PhpHtmlEditor\Editor('Article');
$editor->handleRequest(); // before any output
?>
<form method="post"><?php echo $editor->render(); ?><button>Save</button></form>
On IIS, DOCUMENT_ROOT can be empty under FastCGI, which breaks PHP scripts that use it to find folders. The package works out the web root itself when that happens, so there is nothing to set.
Step 3: give the upload folder write permission
This is the step that catches most people. The upload fails until the identity running PHP may write there. In File Explorer, open the Properties of uploads (create the folder first), go to the Security tab, and give Modify permission to your site's application pool identity, written as:
IIS AppPool\YourPoolName
Or from an administrator command prompt:
icacls "D:\wwwroot\yoursite\uploads" /grant "IIS AppPool\YourPoolName:(OI)(CI)M"
Give Modify on that folder only. PHP does not need to write anywhere else in your site. If permission is missing, the editor says "The server cannot write to the storage folder", so you know where to look.
Step 4: stop scripts from running in uploads
The package never stores server scripts, but it is worth having a second lock. Add a web.config inside uploads:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<fileExtensions allowUnlisted="true">
<add fileExtension=".php" allowed="false" />
<add fileExtension=".phtml" allowed="false" />
<add fileExtension=".asp" allowed="false" />
<add fileExtension=".aspx" allowed="false" />
<add fileExtension=".config" allowed="false" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
</configuration>
A good thing about IIS: it refuses to serve .config files by default, so your policy files in richtexteditor/config cannot be downloaded. We check that on our own site, where the request returns 404.
Step 5: large uploads
Three separate limits apply, and the smallest one wins:
| Where | Setting | Default |
|---|---|---|
php.ini | upload_max_filesize and post_max_size | 2 MB and 8 MB |
| IIS | maxAllowedContentLength in web.config | About 30 MB |
| Policy file | MaxFileSize, in KB | 4 MB for members, 20 MB for admins, 50 MB for video |
So a 50 MB video needs all three raised. To raise the IIS one:
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="104857600" />
</requestFiltering>
</security>
Other things to check
- A 404 for a
.webpor.svgfile: IIS only serves types it knows. Add amimeMaptostaticContentin yourweb.config. WebP and AVIF are the ones uploads may need. - "Your session has expired": PHP sessions need a writable
session.save_path, and the token that protects uploads lives in the session. - Windows file names: names such as
CONorNUL, and characters such as:, are refused for you, so a user's upload cannot trip over them.
Languages
Set $editor->language = 'zh-Hans'; and the editor, the file manager and the server's messages all follow, as in the picture at the top. The file manager and server messages come in 12 languages.