和Python,JavaScript等高級語言同樣,PHP也能夠經過C/C++編寫擴展功能。這裏分享下如何構建一個簡單的PHP擴展,以及如何調用第三方DLL庫。php
參考原文:Making PHP Barcode Extension with Dynamsoft Barcode SDKhtml
Windows PHP的安裝包自己不包涵頭文件,因此要構建PHP擴展,必須下載PHP的源碼。在Windows上,要編譯PHP,以及構建PHP擴展都必須使用對應的Visual Studio,否則會出現大量的錯誤。在這裏咱們使用Visual Studio 2012去構建PHP 5.6的擴展。步驟以下:
git
下載PHP 5.6的源碼以及VC11 build版本。github
建立一個空的Win32工程,應用類型選擇DLL。windows
添加頭文件路徑:oop
F:\php_pack\php-5.6.10-src F:\php_pack\php-5.6.10-src\Zend F:\php_pack\php-5.6.10-src\win32 F:\php_pack\php-5.6.10-src\TSRM F:\php_pack\php-5.6.10-src\main
添加庫路徑:測試
F:\php_pack\php-5.6.10-Win32-VC11-x86\dev
添加依賴:ui
php5ts.lib
建立php_dbr.h:spa
#pragma once #include "zend_config.w32.h" #include "php.h"
建立php_dbr.cpp:.net
#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=0 ZTS=1 ZEND_WIN32 PHP_WIN32
若是不添加,會出現不少錯誤。
如今build工程就能夠生成php_dbr.dll了。
來看一下如何經過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