Making PHP Barcode Extension with Dynamsoft Barcode SDK
After writing articles talking about how to wrap Dynamsoft Barcode SDK to make Barcode extensions for Java, Python and JavaScript, I started to consider PHP. It is one of the most popular tags on StackOverflow. Most Web developers prefer using PHP for server-side development. Since PHP allows developers to write extensions in C/C++, I was going to create a PHP Barcode extension with Dynamsoft Barcode Reader SDK. However, the whole process was not as easy as I expected. In this post, I’d like to share what troubles I’ve got and what solutions I’ve found.
A Simple PHP Extension with Visual Studio 2012
As I did before, learning a “Hello World” program is always my first step. I started to search the relevant keywords “PHP Windows extension” on StackOverflow, but only found a few snippets of information that are not useful enough. Alternatively, I spent some time Googling relevant articles and finally found the post - Creating a PHP 5 Extension with Visual C++ 2005. The post shared how to create extensions for PHP 5.2.4 with Visual Studio 2005, whereas the latest PHP Windows version is 5.6 that built with Visual Studio 2012. If you do not build PHP extension with the corresponding Visual Studio, you will have amounts of building errors.
Here are the steps to build and run the basic extension for PHP 5.6 with Visual Studio 2012 on Windows:
- Download and unzip PHP 5.6 source code and VC11 build.
- Install Bison for Windows.
- Run <Visual Studio 11.0>VC\bin\vcvars32.bat to register variables. The path of cl.exe is required.
- Run **
\buildconf.bat**. - Run **
\configure.bat** to generate **config.w32.h** in **main** folder. - Create an empty Win32 project with application type DLL.
- Add Include directories:
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
- Add Library directories:
F:\php_pack\php-5.6.10-Win32-VC11-x86\dev
- Add dependency:
php5ts.lib
- Create php_dbr.h with following code:
#pragma once
#include "zend_config.w32.h"
#include "php.h"
- Create php_dbr.cpp with following code:
#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);
}
- Add preprocessor definitions:
ZEND_DEBUG=0
ZTS=1
ZEND_WIN32
PHP_WIN32
If you build the project directly, you will see many errors.
- Build your project to generate php_dbr.dll.
Making PHP Barcode Reader with Dynamsoft Barcode Reader SDK
Download and install Dynamsoft Barcode Reader.
Let’s take a glimpse of how to use PHP extension to call third-party DLL libraries:
- Add Include directories and Library directories of Dynamsoft Barcode Reader SDK to project properties.
- Copy the sample code written in previous Python or Node.js examples.
- Convert the returned results to PHP-readable type.
#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);
}
}
Now, we need to deploy the generated DLL to PHP and write a PHP script to test it.
Here is the source code of your 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";
}
?>
Open php.ini, and add our custom extension:
[Dynamsoft Barcode Reader]
extension=php_dbr.dll
As you know that we have to copy php_dbr.dll to {PHP root directory}\ext. What about the third-party DLL file DynamsoftBarcodeReaderx86.dll? If you just copy the DLL file with the PHP extension to the same folder, you will see the following error when running your PHP Barcode reader application:
How to fix this issue? You just need to copy the DLL file to PHP root directory. Try it again: