When developing a web barcode reader app in PHP, you can either use some JavaScript barcode libraries to recognize barcode images on client-side or read the barcode images on server-side with some PHP extensions that are capable of reading 1D and 2D barcode. In this post, I will demonstrate how to create a PHP barcode reader with DBR (Dynamsoft Barcode Reader for Linux) on Ubuntu 14.04.
How to Make PHP Extension with C Source Code and Shared Library
Install DBR.
To build PHP extension, you need to use the source code. Before downloading, you have to check which PHP version is used:
php –v
Download the corresponding source code of PHP.
Extract the package and change to the ext folder. Here is mine:
cd ~/Downloads/php-5.5.9/ext
Create an extension dbr:
./ext_skel --extname=dbr
Change directory to dbr:
cd dbr
Edit config.m4 to configure the paths of include and library:
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
Edit 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>
static int le_dbr;
const zend_function_entry dbr_functions[] = {
PHP_FE(DecodeBarcodeFile, NULL)
PHP_FE_END
};
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),
PHP_RSHUTDOWN(dbr),
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_MINIT_FUNCTION(dbr)
{
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(dbr)
{
return SUCCESS;
}
PHP_RINIT_FUNCTION(dbr)
{
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(dbr)
{
return SUCCESS;
}
PHP_MINFO_FUNCTION(dbr)
{
php_info_print_table_start();
php_info_print_table_header(2, "dbr support", "enabled");
php_info_print_table_end();
}
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);
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);
}
__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;
iRet = DBR_InitLicense("84D34246FC1BC4BDD4078D71FCB5A3AA");
printf("DBR_InitLicense ret: %d\n", iRet);
ro.llBarcodeFormat = llFormat;
ro.iMaxBarcodesNumPerPage = iMaxCount;
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);
}
for (; i < count; i++)
{
char barcodeResult[1024];
tmp = ppBarcodes[i];
{
zval *tmp_array;
MAKE_STD_ZVAL(tmp_array);
array_init(tmp_array);
add_next_index_string(tmp_array, GetFormatStr(tmp->llFormat), true);
add_next_index_string(tmp_array, tmp->pBarcodeData, true);
add_next_index_zval(return_value, tmp_array);
}
}
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);
}
}
To build PHP extension independently, you need to use phpize
, which is a shell script to prepare PHP extension for compiling. Install the dev
package as follows:
sudo apt-get install php5-dev
Build the extension with the following commands:
phpize
./configure
make
C90 does not support the boolean data type. If you see the error “unknown type name ‘bool’”, please include the header file:
#include <stdbool.h>
A shared library dbr.so
is generated under folder modules:
Simple PHP Barcode Reader
Create reader.php:
<?php
$filename = "/home/xiao/Dynamsoft/BarcodeReader4.0/Images/AllSupportedBarcodeTypes.tif";
if (file_exists($filename)) {
echo "Barcode file: $filename \n";
$resultArray = DecodeBarcodeFile($filename, false);
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";
}
?>
Install the PHP Barcode extension:
sudo make install
To load the custom extension, you have to add the library path (e.g. /usr/lib/php5/20121212/dbr.so) into php.ini:
locate php.ini
You may ask which php.ini file should be used? The answer is that you can modify any php.ini file or make it yourself. When executing PHP script, you can designate the php.ini file. I picked php.ini-production and then added the following line:
extension=/usr/lib/php5/20121212/dbr.so
Test the simple PHP barcode reader:
php -c /usr/share/php5/php.ini-production reader.php