Windows 平台 PHP 7.3 源码编译 + SqlSrv 扩展源码编译|图文教程

需求背景

微酷最近使用ThinkPHP框架开发了一个移动应用的 api 服务端,通过php_pdo_sqlsrv扩展和MSSQL数据库交互。移动前端技术采用vue + framework7开发,然后发现前端表单页面报错,错误内容大体为:控件期望得 Number 数字类型,结果得到的却是 String 字符串类型。看了下服务端 api 返回的json数据,发现原本数据库(MSSQL)中decimal类型的字段被解释成了string字符串,也就是说json值两边加了引号。

项目环境:

  • 服务器:Windows Server 2016 + IIS
  • 数据库:Sql Server 2016
  • PHP:7.3 + php_pdo_sqlsrv 5.6
  • 服务端开发框架:ThinkPHP 5.1
  • 移动端:vue + Framework7

解决思路

解决这个问题方法可能有好多,比如前端类转换型,或者服务端 TP 框架的模型也可以定义字段的类型转换,但微酷感觉这样还是麻烦,希望能从根本上解决这个问题,也就是说MSSQL数据库中的decimal字段,提取到 php 中能自动当做float类型(php 是没有 decimal 类型的)。

搜索方案

网上搜索了大半天,发现微软的 SqlSrv 只能将 decimal 类型转为 string 字符串,官方表示也不打算支持转换为 decimal,具体原因见:https://github.com/Microsoft/msphpsql/issues/291。同时链接中也有微软官方人员给出了解决方案:自己修改 SqlSrv 驱动的源代码编译后自用。

那就自己编译吧。


===== PHP 7.3 源码编译 =====

参考资料

编译环境搭建

安装 vs2017

php 7.2、7.3 需要 C++ v15 编译,需要安装 vs2017 的 C++ 功能。

20190409111857646.png

安装后可能要重启,如提示的话重启一下电脑。

下载 php-sdk-binary-tools

下载地址:https://github.com/Microsoft/php-sdk-binary-tools

下载后解压到喜欢的地方,如微酷这里解决到D:\php-sdk,如图:
20190409112446421.png

下载 PHP 源码

下载地址:https://github.com/php/php-src
选择需要编译的 php 版本的分支,然后下载。
微酷这里下载7.3.4版本。
20190409113516821.png

编译 PHP 步骤

运行命令提示符号进入到刚才解决的php-sdk目录(目录名微酷修改过)

运行命令:

phpsdk-vc15-x64.bat

其中vc15x64要根据编译的php版本来定,这里微酷要编译64位php 7.3,所以要运行vc15的脚本,如图:
20190409084831891.png

继续在当前目录运行命令:

phpsdk_buildtree phpdev

注意:这个脚本在bin目录下,不过可以直接在此目录运行。执行后会在当前目录自动创建phpdev目录。
20190409085258740.png

解压 PHP 源码:将之前下载的源码解压到:D:\php-sdk\phpdev\vc15\x64\php-src-7.3.4,如图(文件夹名可改)

20190409113807046.png

下载依赖:还是在之前打开的命令提示符窗口进入到 php 源码目录,然后执行以下命令:

phpsdk_deps -u

执行后开始自动下载编译所需要的依赖,下载后会放到D:\php-sdk\phpdev\vc15\x64\deps目录中。下载可能有点慢,等几分钟就好了,一共大约 30 多个文件需要下载,如图。
20190409090420228.png

命令提示符任然定位在 php 源码目录,执行命令:buildconf,然后会提示执行configure --help可以查看可用的参数。

20190409115037445.png

最终微酷使用以下参数编译phpconfigure --disable-all --enable-cli --disable-zts,其中--disable-zts是生成 NTS 版本的 php。

20190409115555398.png

最后执行执行nmake,执行nmake就开始编译 php 啦,等一会就 ok 了。完成如图:

20190409115848311.png

测试,编译完成后的 php.exe 在源码目录的x64\release目录(根据编译版本目录会不同),运行php -v 测试一下吧。

20190409122143641.png


===== 编译 PHP 扩展=====

微酷这里以编译 pdo_sqlsrv 扩展为例讲解步骤。

  1. 下载 php_pdo_sqlsrv 源码:https://github.com/Microsoft/msphpsql
  2. 解压后将source\shared目录拷贝到source\pdo_sqlsrvsource\sqlsrv各一份。
  3. 拷贝source目录下的sqlsrvpdo_sqlsrv目录到上文中提的 PHP 源码目录下的ext子目录。20190409123005664.png
  4. 好了,到这里就可以和前面编译 PHP 一样开始编译扩展了,只是编译配置增加了和扩展相关的参数,这里微酷一次性将所有命令全都列出来,依次执行即可。
# 重新构建 configure.js 以包含进 sqlsrv 和 pdo_sqlsrv 驱动扩展
buildconf --force

# 生成 makefile,启动 sqlsrv、pdo、pdo_sqlserv
configure --disable-all --enable-cli --disable-zts --enable-sqlsrv=shared --enable-pdo --with-pdo-sqlsrv=shared

--编译,编译前可以先执行一下 nmake clean 清理之前的文件
nmake

20190409123756.gif

最终生成的扩展和上面生成的 php.exe 在一起,编译完成。
20190409123845409.png


SqlSrv 将 mssql 中 decimal 类型转为 php 的 float 修改方法

修改pdo_sqlsrv\pdo_stmt.cpp文件,定位到1430行附近找到case SQL_DECIMAL:,移动到case SQL_FLOAT:下面。

20190408211440410.png

编译后编译即可,微酷测试ok。

最后修改:2019 年 11 月 25 日 08 : 21 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论