NES for PHP on Windows
Download, verify and install the NES for PHP zip on Windows Server (x64).
NES for PHP for Windows is PHP 7.4.33, 7.2.34 and 5.6.40 with HeroDevs security fixes, as a zip you unpack and run: a drop-in replacement for the PHP zip of the same version you use today.
Supported Platforms
| Component | PHP 7.4 | PHP 7.2 | PHP 5.6 |
|---|---|---|---|
| Platform | Windows Server 2022 | Windows Server 2022 | Windows Server 2016, 2019, 2022 and 2025 |
| Architecture | x64 | x64 | x64 |
| Build | Thread-safe (TS) | Thread-safe (TS) | Thread-safe (TS) |
| NES release | v7.4.33-nes-7.4.4 | v7.2.34-nes-7.2.2 | v5.6.40-nes-5.6.2 |
| File | php-v7.4.33-nes-7.4.4.windows.x64.ts.zip | php-v7.2.34-nes-7.2.2.windows.x64.ts.zip | php-v5.6.40-nes-5.6.2.windows.x64.ts.zip |
| OpenSSL | 3.5.9 | 3.5.9 | 3.5.9 |
| Extension build | API20190902,TS,VC15 | API20170718,TS,VC15 | API20131226,TS,VC11 |
The zip is the thread-safe (TS) build. It runs PHP from the command line, from IIS through FastCGI and from Apache. Extensions built for the same PHP version, thread-safe and x64 (VC15 for PHP 7, VC11 for PHP 5.6), such as PECL extensions, load in it as they do in any other PHP build of that kind.
PHP 5.6: the zip is made with Visual C++ 2012 (VC11), as PHP 5.6's own Windows builds are. Each PHP 5.6 release is tested on Windows Server 2016 and Windows Server 2022.
Access
NES for PHP requires an access token for the NES registry. See Access for how to get one.
The zip is at https://registry.nes.herodevs.com/bin/nes/php/<release>/<zip>, with the release and zip
name of your PHP version from the table above. Authenticate with your contact
e-mail and your access token.
In PowerShell, set the version once:
$line = "7.4" # or "7.2" or "5.6"
$tag = @{ "7.4" = "v7.4.33-nes-7.4.4"; "7.2" = "v7.2.34-nes-7.2.2"; "5.6" = "v5.6.40-nes-5.6.2" }[$line]
$zip = "php-$tag.windows.x64.ts.zip"
Prerequisites
Install Microsoft's Visual C++ Redistributable for Visual Studio 2015-2026 (x64), version 14.51.36247 or later. The zip does not include it. Download it from Microsoft.
PHP 5.6 also needs the Visual C++ Redistributable for Visual Studio 2012
Update 4 (x64), version 11.0.61030 or later, for PHP itself. The 2015-2026
runtime is for OpenSSL and the other libraries beside php.exe.
Then check the versions:
(Get-Item "$env:windir\System32\vcruntime140_1.dll").VersionInfo.FileVersion
PHP 5.6: without the 2012 runtime, php.exe does not start (exit code
-1073741515). Without the 2015-2026 runtime, PHP starts but the OpenSSL, cURL
and PostgreSQL extensions do not load.
To verify the download, install Gpg4win, which
provides gpg.
Download and verify
In an empty directory, download the signing key, the checksums and the zip:
$base = "https://registry.nes.herodevs.com/bin/nes/php/$tag"
$auth = "<your-contact-email>:<your-nes-access-token>"
foreach ($f in "RPM-GPG-KEY-php-nes", "SHASUMS256.txt", "SHASUMS256.txt.asc", $zip) {
curl.exe -fSLO -u $auth "$base/$f"
}
Then verify the downloads. gpg --verify must report a good signature, and the
last command must print True:
gpg --show-keys .\RPM-GPG-KEY-php-nes # must show CA44E935A3995EB733AF292B18DD1E9212F3C6A2
gpg --import .\RPM-GPG-KEY-php-nes
gpg --verify .\SHASUMS256.txt.asc .\SHASUMS256.txt
$expected = (Select-String -Path .\SHASUMS256.txt -SimpleMatch $zip).Line.Split(" ")[0]
(Get-FileHash -Algorithm SHA256 ".\$zip").Hash -eq $expected
The programs in the zip are not Authenticode-signed: the signed checksums are how you check the download.
Install
Unpack the zip to C:\php and add that folder to the system Path:
Expand-Archive -LiteralPath ".\$zip" -DestinationPath C:\php
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "Machine") + ";C:\php", "Machine")
Open a new PowerShell window and check the installation:
php -v
PHP 7 shows PHP <version>-nes, built thread-safe (ZTS) for x64:
PHP <version>-nes (cli) (built: <date> <time>) ( ZTS Visual C++ 2017 x64 )
PHP 5.6 shows PHP 5.6.40-nes (cli), then Thread Safety => enabled.
Configure
PHP reads the php.ini in its own folder. Start from the production settings:
Copy-Item C:\php\php.ini-production C:\php\php.ini
In php.ini, remove the ; from the extension_dir = "ext" line and set it to
"C:\php\ext". Enable each extension you use by removing the ; from its
extension= line, for example extension=curl, extension=mbstring and
extension=openssl (on PHP 5.6, extension=php_curl.dll,
extension=php_mbstring.dll and extension=php_openssl.dll). Then check what
loads:
php --ini
php -m
PHP on Windows reads no certificate store. Set curl.cainfo and openssl.cafile in php.ini to a CA bundle file for HTTPS requests to succeed.
IIS
IIS runs PHP through FastCGI. Install the CGI feature
(Install-WindowsFeature Web-CGI), then in IIS Manager open Handler Mappings
and add a module mapping:
| Setting | Value |
|---|---|
| Request path | *.php |
| Module | FastCgiModule |
| Executable | C:\php\php-cgi.exe |
| Name | PHP |
and set these in php.ini:
fastcgi.impersonate = 1
cgi.fix_pathinfo = 1
cgi.force_redirect = 0
Apache
For a 64-bit Apache 2.4, add these lines to httpd.conf and restart Apache:
LoadModule php7_module "C:/php/php7apache2_4.dll"
PHPIniDir "C:/php"
AddType application/x-httpd-php .php
Move from another PHP zip
To switch from another PHP zip of the same version, replace its folder as described under Upgrade. The extension build is the same as the zip you use now (see the table above), so the extension DLLs you load today keep loading. These differ:
- OpenSSL is the version in the table above.
- PHP 7.4: the zip you use now has OpenSSL 1.1.1; the legacy provider is in
extras\ssl. The enchant extension uses Enchant 2.
PHP 5.6
To switch from the PHP 5.6.40 zip you use now, also install the 2015-2026 runtime under Prerequisites. These differ:
- OpenSSL is 3.5.9, where the zip you use now has OpenSSL 1.0.2:
libeay32.dllandssleay32.dllare gone, and an extension DLL built against them does not load. Ciphers OpenSSL 3 moved to its legacy provider, such as RC4, the default ofopenssl_seal(), fail with an OpenSSL error unless that provider is loaded. The legacy provider is inextras\ssl. - These extensions are not in the zip yet:
intl,ldap,imap,tidy,snmp,oci8andpdo_oci(with their DLLs, such as the ICU ones), andenchant. Remove theirextension=lines from yourphp.ini, or PHP warns that it cannot load them at startup. Thegdextension reads and writes no WebP images. pg_trace()is not supported: it warns and returnsfalse.
Upgrade
Set $tag and $zip to the new release's, download and verify the zip as above. Stop the web server or
application that uses PHP, then replace the folder and keep your php.ini:
Rename-Item C:\php C:\php-old
Expand-Archive -LiteralPath ".\$zip" -DestinationPath C:\php
Copy-Item C:\php-old\php.ini C:\php\php.ini
php -v
Start the web server or application again. Compare your php.ini with the new
php.ini-production for settings the release adds, then remove C:\php-old.
Uninstall
Stop the web server or application that uses PHP, remove the C:\php folder
and remove C:\php from the system Path.