Ubuntu上輕松實現PHP擴展
來自: http://my.oschina.net/yushulx/blog/626498
對比Windows,Linux上實現PHP擴展要簡單輕松的多。
參考原文:How to Make PHP Barcode Reader on Linux
作者:Xiao Ling
翻譯:yushulx
幾步構建PHP Barcode擴展
安裝DBR。
要構建PHP擴展,一定要使用對應版本的源碼:
php –v
下載PHP源碼。
解壓代碼,切換到ext目錄:
cd ~/Downloads/php-5.5.9/ext
創建擴展dbr:
./ext_skel --extname=dbr cd dbr
編輯config.m4,添加頭文件和庫文件路徑:
PHP_ARG_ENABLE(dbr, whether to enable dbr support, dnl Make sure that the comment is aligned: [ --enable-dbr Enable dbr support]) if test "$PHP_DBR" != "no"; then PHP_ADD_LIBRARY_WITH_PATH(DynamsoftBarcodeReaderx64, /home/xiao/Dynamsoft/BarcodeReader4.0/Redist, DBR_SHARED_LIBADD) PHP_ADD_INCLUDE(/home/xiao/Dynamsoft/BarcodeReader4.0/Include) PHP_SUBST(DBR_SHARED_LIBADD) PHP_NEW_EXTENSION(dbr, dbr.c, $ext_shared) fi
編輯dbr.c:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_dbr.h"
#include "If_DBR.h"
#include "BarcodeFormat.h"
#include "BarcodeStructs.h"
#include "ErrorCode.h"
#include <stdbool.h>
/* If you declare any globals in php_dbr.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(dbr)
*/
/* True global resources - no need for thread safety here */
static int le_dbr;
/* {{{ dbr_functions[]
*
* Every user visible function must have an entry in dbr_functions[].
*/
const zend_function_entry dbr_functions[] = {
PHP_FE(DecodeBarcodeFile, NULL) /* For testing, remove later. */
PHP_FE_END /* Must be the last line in dbr_functions[] */
};
/* }}} */
/* {{{ dbr_module_entry
*/
zend_module_entry dbr_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"dbr",
dbr_functions,
PHP_MINIT(dbr),
PHP_MSHUTDOWN(dbr),
PHP_RINIT(dbr), /* Replace with NULL if there's nothing to do at request start */
PHP_RSHUTDOWN(dbr), /* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(dbr),
#if ZEND_MODULE_API_NO >= 20010901
PHP_DBR_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
/* }}} */
#ifdef COMPILE_DL_DBR
ZEND_GET_MODULE(dbr)
#endif
/* {{{ PHP_INI
*/
/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("dbr.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_dbr_globals, dbr_globals)
STD_PHP_INI_ENTRY("dbr.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_dbr_globals, dbr_globals)
PHP_INI_END()
*/
/* }}} */
/* {{{ php_dbr_init_globals
*/
/* Uncomment this function if you have INI entries
static void php_dbr_init_globals(zend_dbr_globals *dbr_globals)
{
dbr_globals->global_value = 0;
dbr_globals->global_string = NULL;
}
*/
/* }}} */
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(dbr)
{
/* If you have INI entries, uncomment these lines
REGISTER_INI_ENTRIES();
*/
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(dbr)
{
/* uncomment this line if you have INI entries
UNREGISTER_INI_ENTRIES();
*/
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
*/
PHP_RINIT_FUNCTION(dbr)
{
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
PHP_RSHUTDOWN_FUNCTION(dbr)
{
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(dbr)
{
php_info_print_table_start();
php_info_print_table_header(2, "dbr support", "enabled");
php_info_print_table_end();
/* Remove comments if you have entries in php.ini
DISPLAY_INI_ENTRIES();
*/
}
/* }}} */
// Barcode format
const char * GetFormatStr(__int64 format)
{
if (format == CODE_39)
return "CODE_39";
if (format == CODE_128)
return "CODE_128";
if (format == CODE_93)
return "CODE_93";
if (format == CODABAR)
return "CODABAR";
if (format == ITF)
return "ITF";
if (format == UPC_A)
return "UPC_A";
if (format == UPC_E)
return "UPC_E";
if (format == EAN_13)
return "EAN_13";
if (format == EAN_8)
return "EAN_8";
if (format == INDUSTRIAL_25)
return "INDUSTRIAL_25";
if (format == QR_CODE)
return "QR_CODE";
if (format == PDF417)
return "PDF417";
if (format == DATAMATRIX)
return "DATAMATRIX";
return "UNKNOWN";
}
PHP_FUNCTION(DecodeBarcodeFile)
{
array_init(return_value);
// Get Barcode image path
char* pFileName = NULL;
bool isNativeOuput = false;
bool isLogOn = false;
int iLen = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb|b", &pFileName, &iLen, &isNativeOuput, &isLogOn) == FAILURE) {
RETURN_STRING("Invalid parameters", true);
}
if (isLogOn)
{
printf("params: %s, %d, %d\n", pFileName, iLen, isNativeOuput);
}
// Dynamsoft Barcode Reader: init
__int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX);
int iMaxCount = 0x7FFFFFFF;
int iIndex = 0;
ReaderOptions ro = {0};
pBarcodeResultArray pResults = NULL;
int iRet = -1;
char * pszTemp = NULL;
// Initialize license
iRet = DBR_InitLicense("84D34246FC1BC4BDD4078D71FCB5A3AA");
printf("DBR_InitLicense ret: %d\n", iRet);
ro.llBarcodeFormat = llFormat;
ro.iMaxBarcodesNumPerPage = iMaxCount;
// Decode barcode image
int ret = DBR_DecodeFile(pFileName, &ro, &pResults);
if (ret == DBR_OK)
{
int count = pResults->iBarcodeCount;
pBarcodeResult* ppBarcodes = pResults->ppBarcodes;
pBarcodeResult tmp = NULL;
char result[2048] = {0};
int i = 0;
if (count == 0)
{
add_next_index_string(return_value, "No Barcode detected", true);
}
// loop all results
for (; i < count; i++)
{
char barcodeResult[1024];
// A barcode result.
tmp = ppBarcodes[i];
{
// Working with PHP array: http://php.net/manual/en/internals2.variables.arrays.php
zval *tmp_array;
// Initialize zval
MAKE_STD_ZVAL(tmp_array);
array_init(tmp_array);
// Add format & value to an array
add_next_index_string(tmp_array, GetFormatStr(tmp->llFormat), true);
add_next_index_string(tmp_array, tmp->pBarcodeData, true);
// Add result to returned array
add_next_index_zval(return_value, tmp_array);
}
}
// Dynamsoft Barcode Reader: release memory
DBR_FreeBarcodeResults(&pResults);
if (isLogOn && isNativeOuput)
{
printf("Native result: %s\n", result);
}
if (isNativeOuput)
{
add_next_index_string(return_value, result, true);
}
}
else
{
add_next_index_string(return_value, "No Barcode detected", true);
}
} 要獨立構建PHP擴展模塊,需要使用phpize。安裝開發包:
sudo apt-get install php5-dev
構建PHP擴展模塊:
phpize ./configure make
C90規范不支持布爾類型。如果看到錯誤“unknown type name ‘bool’”,加上頭文件:
#include <stdbool.h>
動態鏈接庫dbr.so會自動生成到目錄modules下面:

簡單的PHP Barcode應用
創建reader.php:
<?php
$filename = "/home/xiao/Dynamsoft/BarcodeReader4.0/Images/AllSupportedBarcodeTypes.tif";
if (file_exists($filename)) {
echo "Barcode file: $filename \n";
$resultArray = DecodeBarcodeFile($filename, 0);
if (is_array($resultArray[0])) {
$resultCount = count($resultArray);
echo "Total count: $resultCount\n";
for($i = 0; $i < $resultCount ; $i++) {
$result = $resultArray[$i];
echo "Barcode format: $result[0], value: $result[1]\n";
}
}
else {
echo "$resultArray[0]";
}
} else {
echo "The file $filename does not exist";
}
?> 安裝剛才編譯出來的擴展:
sudo make install
把安裝之后的路徑(/usr/lib/php5/20121212/dbr.so)加入到php.ini文件中:
locate php.ini

通過命令找尋php.ini文件會發現有好幾個相關的。到底用哪個呢?可以隨便選一個或者新建一個。我選擇了php.ini-production :
extension=/usr/lib/php5/20121212/dbr.so
運行PHP barcode reader,記得帶上php.ini的文件路徑:
php -c /usr/share/php5/php.ini-production reader.php

源碼
https://github.com/dynamsoftlabs/linux-php-barcode-reader-
本文由用戶 co518248 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!