最近在作个项目,须要用到惟一ID的生成,本来在Java和Delphi中,作了一个生成20位字符串(160bit)形式的惟一ID的算法,可是对比GUID(128bit),除了看起来比他短以外,其余并没有优点。因此考虑从新采用Twitter-Snowflake的算法,作一个64bit的惟一ID生成。php
可是在纯PHP语言环境中,维护序列号是个麻烦的问题,因此考虑写php扩展,用C在底层实现支持。html
好了,如今这里割了,进入正题。。。算法
=============================windows
软件环境:php7
一、Windows7 x64;工具
二、安装cygwin,我选择的是下载在线的安装包,离线包个头太大,而后在线安装的时候,选择国内的源就能够了,速度仍是很是快的。开发工具
下载地址:https://cygwin.com/install.html;测试
二、PHP 7.1。ui
开发工具:spa
php7开始,官方是使用vc14编译的,因此从避免给本身找麻烦的角度,仍是下了个vs2015的社区版(这个免费哦,并且非团队开发的话,用起来基本没啥差异),
下载地址:https://www.visualstudio.com/zh-hans/downloads/
事先准备:
一、php-sdk-binary-tools-20110915,sdk工具包,还有个更早点的版本,不知道有啥区别,下了最新的。
二、deps-7.1-vc14-x64,php编译的依赖包。
下载地址:http://windows.php.net/downloads/php-sdk/
三、php-7.1.2-src,php对应版本的源码,这个看本身需求咯。
下载地址:http://windows.php.net/downloads/releases/
好了,万事具有,开工吧。
解压php-sdk-binary-tools-20110915,而后打开VS的开发人员命令提示,要编译64位的,记得开x64版本。
进入解压后文件夹的bin目录,执行如下语句:
phpsdk_setvars.bat //载入环境变量
phpsdk_buildtree.bat extdev //生成开发目录(其实没啥用,喜欢循序渐进的能够生成完了本身更名)
新建一个vc14文件夹,将deps包中解压的文件放入该文件夹,如果生成的目录的话,覆盖其中的deps文件夹便可,最后再将源码包解压到当前目录。
接下来进入源码目录:
cd E:\PHP\extdev\vc14\x64\php-7.1.2-src\
首先修改ext目录下的ext_skel_win32.php,将其中的$cygwin_path设置为你当前cygwin安装目录的bin目录。
执行该php文件
cd ext
php ext_skel_win32.php --extname=extname
若是出错,根据提示查看环境配置问题,这个再也不这里多说。
正常状况执行完毕后,会生成一个extname的文件夹。(extname能够本身随意定义)
进入该文件夹,修改一下config.w32文件,去掉下面这行的注释
//ARG_ENABLE("extname", "enable extname support", "no");
回到src目录下,执行下列命令:
buildconf --force //编译配置文件
configure --help //检查配置文件
若是报错的话,打开目录下的configure.js文件,找到
ARG_ENABLE("extname", "enable extname support", "no"); */
删除掉生成错误的注释符便可。
在未报错的状况下,执行configure --help后,检查输出中,是否包括自定义的ext信息,显示以下:
--enable-extname enable extname support
若是有,则执行以下命令进行编译
configure --disable-all --enable-cli --enable-extname=shared
nmake
编译完成后,会在Release_TS或者x64\Release_TS中,生成php_extname.dll。
按照常规配置方式,将dll放入php的ext目录中,php.ini中加上extension=php_extname.dll后,即可以直接测试dll中的默认方法,方法源码以下:
/* Remove the following function when you have successfully modified config.m4 so that your module can be compiled into PHP, it exists only for testing purposes. */ /* Every user-visible function in PHP should document itself in the source */ /* {{{ proto string confirm_extname_compiled(string arg) Return a string to confirm that the module is compiled in */ PHP_FUNCTION(confirm_extname_compiled) { char *arg = NULL; size_t arg_len; zend_string *strg; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { return; } strg = strpprintf(0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "extname", arg); RETURN_STR(strg); }
执行方式:
php -r "echo confirm_extname_compiled(0);"