Prerequisites
- Visual Studio 2005 You can alternately use the free Visual C++ Express Edition or the VC++ 8 compiler in the Windows SDK v6.0 if you’re a makefile master. Visual Studio 2003 (VC++ 7) will probably work just fine, but some of the project configuration steps will be different than what is explained here
- A web server For this article I used Sambar Server 7.0. Any HTTP server that can run thePHP 5.x ISAPI extension (php5isapi.dll) will do
- PHP 5 binaries, installed and configured for your server I used PHP 5.2.4. Using the windows installer package (.msi file) makes configuration easier
- PHP 5 source code DONT PANIC! You do not need to build PHP from source, just get the source that matches your binary version. You will need an extraction utility likeWinRAR or ZipGenius that can handle .tar archives.
Conventions
Italics denote file paths and names. C:\Server\PHP\dev Screenshot icons

Configuring the Environment
I will not discuss installing and running the HTTP web server. If you do not already have IIS available on your machine, I recommend the Sambar Server. If you do not already have PHP 5 installed, download it from php.net. If you download and run the MSI installer package, it will configure your web server. After you’ve got PHP 5 installed and configured for your server, download and extract the complete PHP 5 source code, also from php.net. Caution: Do NOT extract the source archive over top of your existing binary installation. This article’s example setup includes the PHP 5 binaries installed to C:\Server\PHP5, and the source code extracted toC:\Server\PHP5Src.Creating the Project
In Visual Studio 2005, create a new Visual C++ Win32 project using the project template.

Change Default C++ Options
Bring up the Project Properties dialog, and make sure the Debug configuration is active. Under Configuration Properties > General, change the Character Set to “Use Multi-Byte Character Set”.

- Enable String Pooling to “Yes (/GF)”
- Enable Minimal Rebuild to “No”
- Basic Runtime Checks to “Default”
- Runtime Library to “Multi-threaded Debug (/MTd)”
- Debug Information Format to “Program Database (/Zi)”
- Detect 64-bit Portability Issues to “No”
Set the INCLUDE Paths
Still on the Project Properties dialog unders Configuration Properties > C/C++ > General, in the Additional Include Directories, add the following paths, replacingC:\Server\PHP5Src with the location on your machine where you extracted the source code.
C:/Server/PHP5Src/main C:/Server/PHP5Src/Zend C:/Server/PHP5Src/TSRM C:/Server/PHP5Src/regex C:/Server/PHP5SrcAgain, be sure to click Apply to save the settings as you go along.
Set the Preprocessor Definitions
On the Project Properties dialog, under Configuration Properties > C/C++ > Preprocessor, add the following definitions:
ZEND_DEBUG=0 ZTS=1 ZEND_WIN32 PHP_WIN32Note: Do not be tempted to change ZEND_DEBUG to 1, even for this Debug build, as this will prevent your extension from being loaded into the pre-built PHP binaries installed on your system.
Set the Linker Options
On the Project Properties dialog, under Configuration Properties > Linker > Generaladd the path to the C:\Server\PHP\dev directory to the Additional Library Directories. This is the directory underneath your installed PHP binaries (not the extracted source). This directory should contain php5ts.lib.

The Extension Code
Replace the contents of stdafx.h with the following, or download it
#pragma once /* PHP Extension headers */ /* include zend win32 config first */ #include "zend_config.w32.h" /* include standard header */ #include "php.h"Replace the contents of ProjectName.cpp (in this example CustomExt.cpp) with the following (or download it

#include "stdafx.h"/* declaration of functions to be exported */ ZEND_FUNCTION(DoubleUp); /* compiled function list so Zend knows what's in this module */ zend_function_entry CustomExtModule_functions[] = { ZEND_FE(DoubleUp, NULL) {NULL, NULL, NULL} }; /* compiled module information */ zend_module_entry CustomExtModule_module_entry = { STANDARD_MODULE_HEADER, "CustomExt Module", CustomExtModule_functions, NULL, NULL, NULL, NULL, NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES }; /* implement standard "stub" routine to introduce ourselves to Zend */ ZEND_GET_MODULE(CustomExtModule) /* DoubleUp function */ /* This method takes 1 parameter, a long value, returns the value multiplied by 2 */ ZEND_FUNCTION(DoubleUp){ long theValue = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &theValue) == FAILURE){ RETURN_STRING("Bad parameters!", true); } theValue *= 2; RETURN_LONG(theValue); }You should now be able to build the project without any errors. Be careful when renaming CustomExtModule or DoubleUp, and you must replace every instance in the file, or the Zend macros will yield nearly indecipherable compiler errors.
Enable the extension
The first step is to locate the \ext directory beneath your PHP 5 binaries (not the directory where you extracted the PHP source code). On my sample system this isC:\Server\PHP\ext. Copy the DLL that you just built to this directory. If you are going to attach a debugger to your extension, you will also want to copy the .pdb files. The second step is to configure PHP to load your extension DLL. You do this by modifying PHP.ini, adding a
1 |
extension=php_ext_name.dll |
;;;;;;;;;;;;;;;;;;;;;; ; Dynamic Extensions ; ;;;;;;;;;;;;;;;;;;;;;; [CustomExt] extension=php_custom_ext.dll
Verify that the extension can be loaded
Once you’ve edited and saved php.ini, you may need to restart the HTTP server in order to pick up the new module. After the server is restarted, browse to the phpinfo.php web page. If you do not already have a phpinfo.php page, create one using the following text, and save it to one of your virtual directories:<?php phpinfo(); ?>Now browse to http://localhost/virtualpath/phpinfo.php, and look for the Additional Modules section. Your new extension should now be seen in the listing. If your extension is not listed, you may need to resave php.ini and restart the server. Also,make sure that the php.ini file that your server is using is the same ini file that you just edited. On most servers, php.ini is located in the PHP 5 installation directory, but your server may be different. To make certain, look at the information at the top of the page for the Loaded Configuration File entry, which shows the full path to the ini file PHPis currently using.
Write a test page
Copy the following code to testext.php (or download it
<?php $value = 14; $result = DoubleUp($value); print "Calling DoubleUp($value) returned $result"; ?>You can now browse to http://localhost/virtualpath/testext.php.
Debugging the extension
In order to debug the extension you need to attach the debugger to the running instance of the web server process. For IIS, this is w3wp.exe. For the Sambar server, this is sambar70\bin\server.exe. On the Project Properties dialog, under Configuration Properties > Debugging , set the following values:- Command to the full path to the server executable
- Attach to “Yes”
- Debugger Type to “Native Only”