对比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-
来源:oschina
链接:https://my.oschina.net/u/1187419/blog/626498