最近在作個項目,須要用到惟一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);"