標籤:
和Python,JavaScript等進階語言一樣,PHP也可以通過C/C++編寫擴充功能。這裡分享下如何構建一個簡單的PHP擴充,以及如何調用第三方DLL庫。
參考原文:Making PHP Barcode Extension with Dynamsoft Barcode SDK
使用Visual Studio 2012構建PHP擴充
Windows PHP的安裝包本身不包涵標頭檔,所以要構建PHP擴充,必須下載PHP的源碼。在Windows上,要編譯PHP,以及構建PHP擴充都必須使用對應的Visual Studio,不然會出現大量的錯誤。在這裡我們使用Visual Studio 2012去構建PHP 5.6的擴充。步驟如下:
下載PHP 5.6的源碼以及VC11 build版本。
建立一個空的Win32工程,應用類型選擇DLL。
添加標頭檔路徑:
F:\php_pack\php-5.6.10-srcF:\php_pack\php-5.6.10-src\ZendF:\php_pack\php-5.6.10-src\win32F:\php_pack\php-5.6.10-src\TSRMF:\php_pack\php-5.6.10-src\main
添加庫路徑:
F:\php_pack\php-5.6.10-Win32-VC11-x86\dev
添加依賴:
php5ts.lib
建立php_dbr.h:
#pragma once #include "zend_config.w32.h" #include "php.h"
建立php_dbr.cpp:
#include "php_dbr.h" ZEND_FUNCTION(DecodeBarcodeFile); zend_function_entry CustomExtModule_functions[] = { ZEND_FE(DecodeBarcodeFile, NULL) {NULL, NULL, NULL}}; zend_module_entry CustomExtModule_module_entry = { STANDARD_MODULE_HEADER, "Dynamsoft Barcode Reader", CustomExtModule_functions, NULL, NULL, NULL, NULL, NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES}; ZEND_GET_MODULE(CustomExtModule) ZEND_FUNCTION(DecodeBarcodeFile){ RETURN_STRING("No Barcode detected", true);}
添加宏定義:
ZEND_DEBUG=0ZTS=1ZEND_WIN32PHP_WIN32
如果不添加,會出現很多錯誤。
現在build工程就可以產生php_dbr.dll了。
使用Dynamsoft Barcode SDK建立PHP Barcode Extension
來看一下如何通過PHP擴充調用第三方的DLL庫:
添加Dynamsoft Barcode SDK的標頭檔和庫檔案路徑到工程屬性中
通過SDK的C/C++介面解碼Barcode,並把結果轉換成PHP可讀資料:
#include "php_dbr.h" #include "If_DBR.h"#include "BarcodeFormat.h"#include "BarcodeStructs.h"#include "ErrorCode.h" #ifdef _WIN64#pragma comment(lib, "DBRx64.lib")#else#pragma comment(lib, "DBRx86.lib")#endif void SetOptions(pReaderOptions pOption, int option_iMaxBarcodesNumPerPage, int option_llBarcodeFormat){ if (option_llBarcodeFormat > 0) pOption->llBarcodeFormat = option_llBarcodeFormat; else pOption->llBarcodeFormat = OneD; if (option_iMaxBarcodesNumPerPage > 0) pOption->iMaxBarcodesNumPerPage = option_iMaxBarcodesNumPerPage; else pOption->iMaxBarcodesNumPerPage = INT_MAX; } ZEND_FUNCTION(DecodeBarcodeFile); zend_function_entry CustomExtModule_functions[] = { ZEND_FE(DecodeBarcodeFile, NULL) {NULL, NULL, NULL}}; zend_module_entry CustomExtModule_module_entry = { STANDARD_MODULE_HEADER, "Dynamsoft Barcode Reader", CustomExtModule_functions, NULL, NULL, NULL, NULL, NULL, NO_VERSION_YET, STANDARD_MODULE_PROPERTIES}; ZEND_GET_MODULE(CustomExtModule) ZEND_FUNCTION(DecodeBarcodeFile){ array_init(return_value); // Get Barcode image path char* pFileName = NULL; int iLen = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &pFileName, &iLen) == FAILURE) { RETURN_STRING("Invalid parameters", true); } // Dynamsoft Barcode Reader: init int option_iMaxBarcodesNumPerPage = -1; int option_llBarcodeFormat = -1; pBarcodeResultArray pResults = NULL; ReaderOptions option; SetOptions(&option, option_iMaxBarcodesNumPerPage, option_llBarcodeFormat); // decode barcode image file int ret = DBR_DecodeFile( pFileName, &option, &pResults ); if (ret == DBR_OK) { int count = pResults->iBarcodeCount; pBarcodeResult* ppBarcodes = pResults->ppBarcodes; pBarcodeResult tmp = NULL; // loop all results for (int i = 0; i < count; i++) { tmp = ppBarcodes[i]; // convert format type to string char format[64]; sprintf (format, "%d", tmp->llFormat); // (barcode type, result) add_assoc_string(return_value, format, tmp->pBarcodeData, 1); } // Dynamsoft Barcode Reader: release memory DBR_FreeBarcodeResults(&pResults); } else { RETURN_STRING("No Barcode detected", true); } }
現在我們需要寫一個PHP的測試指令碼,並把DLL部署到PHP中。
一個簡單的PHP Barcode Reader:
<?php $filename = "F:\\git\\Dynamsoft-Barcode-Reader\\Images\\AllSupportedBarcodeTypes.tif"; if (file_exists($filename)) { echo "Barcode file: $filename \n"; $resultArray = DecodeBarcodeFile($filename); if (is_array($resultArray)) { foreach($resultArray as $key => $value) { print "format:$key, result: $value \n"; print "*******************\n"; } } else { print "$resultArray"; } } else { echo "The file $filename does not exist";} ?>
開啟php.ini初始設定檔案,加入:
[Dynamsoft Barcode Reader]extension=php_dbr.dll
現在要把產生的DLL拷貝到{PHP root directory}\ext。如果你同時把DynamsoftBarcodeReaderx86.dll也拷貝到這個目錄下,PHP會找不到這個DLL,報出如下錯誤:
如何修複這個問題?你只要把第三方的DLL拷貝到PHP根目錄下即可。現在再試一次:
源碼
https://github.com/yushulx/Dynamsoft-Barcode-Reader/tree/master/samples/PHP
使用C/C++編寫PHP Extension