Getting PHP’s GD module to work with IIS

Grrr, this cost me about 10 hours, and was hard to research, so I’m documenting it here for The Good Of Everyone:

Problem

I work with PHP on a bunch of different web servers. In this case I needed to resize photos (JPEGs) from Microsoft SQL Server (MSSQL) blobs on a Windows web server running IIS. I got stuff working on my local Windows development machine (under Apache, XAMPP rocks BTW), but when I moved to the production server:

  • the script would silently fail with a 500 error whenever I called a GD function, specifically imagecreatefromstring()
  • The most common IIS and GD error appears to be when PHP can’t find the GD DLL at all, which produces a nice message like
    Fatal error: Call to undefined function: imagecreatefromstring() in c:\inetpub\wwwroot\test2.php on line 7 PHP Warning: Unable to load dynamic library ‘c:\php\ext\php_gd2.dll’ – The specified procedure could not be found. in Unknown on line 0
    This was NOT my problem. My script kept failing silently, with no output after I called the first GD function.
  • IIS has no real error log like Apache. When my script silently failed, nothing was logged in the Application Event log, PHP’s error.log or the pathetic c:\WINDOWS\system32\LogFiles\HTTPERR\httperr*.log. Googling hard, I found I might have luck looking for “Worker Process Recycling Events”, which is apparently Microsoft’s IIS term for that confusing word “error”, but I didn’t go far down that path.
  • Running my script from the command line using PHP didn’t produce any visible error either

IIS sucks. Apache’s error log is way better.

Solutions

I had to do both these things:

  • Copy the php_gd2.dll to C:\WINDOWS\system32. Ridiculous, but I have had to do it before with other PHP modules to have them really work. After I did that, the script would work for small JPEG images.
  • Increase the memory_limit in php.ini from 16MB to 32MB, so any whole high-res JPEG from the database will fit uncompressed in PHP’s memory