在Win32下用VS2008编译PHP扩展

网络整理 - 08-26

  首先要下载PHP源代码及Windows下的二进制压缩包(需要解压开后并正确配置php.ini,甚至Apache),因为在编译扩展的过程中我们需要二进制压缩包里的dev/php5ts.lib文件(提示:此文件可在你本地服务器环境的PHP的目录下的dev目录中找到,注意 php5ts.lib版本最好与你下载的源码包版本一致,避免后续的一些问题)。接着使用PHP源代码目录下的 ext/ext_skel_win32.php来生成扩展的骨架类。但ext_skel_win32.php中说要使用cygwin,但我机器上没有装 cygwin,另外发现其中实际上只使用到了sh,而我机器上装的MSYS里也有sh,应该可以用的吧,于是就将ext_skel_win32.php中的$cygwin_path变量设置成了MSYS的BIN目录

  $cygwin_path = ‘c:\msys\1.0\bin’;

  然后设置环境变量,将解压开的PHP二进制包目录(包含php.exe的)以及MSYS的BIN目录加入到PATH环境变量中。在控制台切换到PHP源码ext目录下执行ext_skel_win32.php脚本以生成骨架类:

  php ext_skel_win32.php –extname=mytest

  这样就在PHP源码的ext目录下生成一个了一个mytest的目录,里面有php_mytest.h, mytest.c和mytest.dsp,可以使用VC2008来打开mytest.dsp,它提示要转换工程。

  然后将mytest.c改名字为mytest.cpp,将里面的

  #include “php.h”

  #include “php_ini.h”

  #include “ext/standard/info.h”

  #include “php_mytest.h”

  用extern “C”括起来:

  extern “C”

  {

  #include “php.h”

  #include “php_ini.h”

  #include “ext/standard/info.h”

  #include “php_mytest.h”

  }

  还要将

  #ifdef COMPILE_DL_MYTEST

  ZEND_GET_MODULE(mytest)

  #endif

  也括起来

  #ifdef COMPILE_DL_MYTEST

  extern “C”

  {

  ZEND_GET_MODULE(mytest)

  }

  #endif

  设置工程属性页中的C++->代码生成->运行库改为多线程DLL(/MD),将C++->高级->编译为改为编译为C++代码(/TP),链接器->附加库目录加一项PHP二进制包的dev目录。

  处理完这些后,还要修改PHP源码中Zend/Zend.h,将

  #include

  移动到

  #ifdef ZEND_WIN32

  # include “zend_config.w32.h”

  # define ZEND_PATHS_SEPARATOR ‘;’

  #elif defined(NETWARE)

  # include

  # define ZEND_PATHS_SEPARATOR ‘;’

  #elif defined(__riscos__)

  # include

  # define ZEND_PATHS_SEPARATOR ‘;’

  #else

  # include

  # define ZEND_PATHS_SEPARATOR ‘:’

  #endif

  的后面去。 还要修改zend_config.w32.h,将

  #define vsnprintf _vsnprintf

  这行注释掉,这样就可以正常编译了(按Release_TS编译),在PHP源码目录下的Release_TS目录下生成了 php_mytest.dll,将其拷贝到PHP二进制文件目录下的ext目录中,修改其php.ini文件,加上 extension=php_mytest.dll,在命令行用php -i命令来查看模块是否加载成功了:

  mytest

  mytest support => enabled

  ==========================================================

  Q1: 如果在编译时遇到这样的警告

  warning C4273: “getwchar”: dll 链接不一致

  warning C4273: “putwchar”: dll 链接不一致

  warning C4005: “_WIN32_WINNT”: 宏重定义

  这是因为路径设置的问题,本人对VS2008不太熟悉,在同事帮助下解决这个问题:

  设置工程属性页-》链接器-》输入-》附加依赖项 把php5ts.lib设置成绝对路径后,

  再编译即可成功!

  Q2: 在页面中运行时会提示这样的信息:“Not supported in multithreaded Web servers ”

  ,意思是说Web Server不支持多线程,本人在集成套件wamp和xampp下测试,

  环境分别为,

  wamp:

  Apache 2.*

  PHP 5.2.5

  xampp:

  Apache 2.2.11

  PHP 5.2.9

  (MYSQL和其它的就不说了,测试扩展用不着就省了。)

  在Wamp环境中,WebServer未能通过,命令行通过

  在Xampp环境中,WebServer通过,命令行通过,但是当在PHP脚本中,使用DL函数加载扩展时,

  这时WebServer就会提示不支持多线程警告,由此可见,PHP v5.2.9以下版本DL在WebServer下是不支持多线程的,不知道更高版本是否支持,没测试过。

  说得有不对的地方请高手指点!

  参考:

  如在VS2008下创建控制台程序,可参考这篇文章: