How to Build a PHP Barcode and QR Code Reader Extension on Windows and Linux
When using PHP, you may sometimes need to integrate a few C++ libraries. This article guides you through the process of building a PHP Barcode and QR Code reading extension using the Dynamsoft C++ Barcode SDK on both Windows and Linux.
This article is Part 1 in a 2-Part Series.
Prerequisites
- PHP on Windows
-
Contains essential binaries required for building, such as
bison
andre2c
. -
Download the source code to build the extension statically.
-
Pre-built PHP 7.4 binaries for Windows.
-
Development package (SDK to develop PHP extensions)
Includes
phpize
, necessary for building PHP extensions with pre-built binaries.
-
-
PHP on Linux
php7.4-dev php7.4 libxml2-dev
-
Dynamsoft C++ Barcode Reader v9.x
This SDK includes shared libraries necessary for barcode and QR code functionality on both Windows and Linux.
-
Dynamsoft Barcode Reader License Key
Obtain a 30-day free trial license key to test barcode and QR code reading functionalities.
Visual C++ Compiler for Building PHP Extension
According to the PHP online tutorial, the supported Visual C++ compilers are as follows:
Visual C++ 14.0 (Visual Studio 2015) for PHP 7.0 or PHP 7.1.
Visual C++ 15.0 (Visual Studio 2017) for PHP 7.2, PHP 7.3 or PHP 7.4.
Visual C++ 16.0 (Visual Studio 2019) for master.
If you only have Visual Studio 2022
on Windows, you must install the corresponding Visual C++ build tools using the Visual Studio Installer
.
Afterward, locate and execute the vcvars64.bat
file to set the environment variables.
For example:
Here we use PHP 7.4, so we should run Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat
via cmd.exe
.
Note: It is important to use the matching Visual C++ compiler version. Otherwise, the generated extension will be incompatible.
Creating PHP Barcode QR Code Extension Project
We scaffold a PHP extension project using the following commands:
cd php-7.4.30-src/ext
php ext_skel.php --ext dbr
cd dbr
Then, copy DynamsoftCommon.h
, DynamsoftBarcodeReader.h
and DBRx64.lib
to the project root directory.
In dbr.c
, we implement the extension functions DBRInitLicense()
and DecodeBarcodeFile()
.
#include "DynamsoftBarcodeReader.h"
static void *hBarcode = NULL;
#define CHECK_DBR() \
if (!hBarcode) \
{ \
hBarcode = DBR_CreateInstance(); \
const char* versionInfo = DBR_GetVersion(); \
printf("Dynamsoft Barcode Reader %s\n", versionInfo); \
}
PHP_FUNCTION(DBRInitLicense)
{
CHECK_DBR();
char *pszLicense;
size_t iLen;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &pszLicense, &iLen) == FAILURE)
{
RETURN_STRING("Invalid parameters");
}
char errorMsgBuffer[512];
// Click https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform
DBR_InitLicense(pszLicense, errorMsgBuffer, 512);
printf("DBR_InitLicense: %s\n", errorMsgBuffer);
}
PHP_FUNCTION(DecodeBarcodeFile)
{
CHECK_DBR();
array_init(return_value);
// Get Barcode image path
char *pFileName;
long barcodeType = 0;
size_t iLen;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &pFileName, &iLen, &barcodeType) == FAILURE)
{
RETURN_STRING("Invalid parameters");
}
if (hBarcode)
{
int iMaxCount = 0x7FFFFFFF;
TextResultArray *pResults = NULL;
// Update DBR params
PublicRuntimeSettings pSettings = {0};
DBR_GetRuntimeSettings(hBarcode, &pSettings);
pSettings.barcodeFormatIds = barcodeType;
char szErrorMsgBuffer[256];
DBR_UpdateRuntimeSettings(hBarcode, &pSettings, szErrorMsgBuffer, 256);
// Barcode detection
int ret = DBR_DecodeFile(hBarcode, pFileName, "");
DBR_GetAllTextResults(hBarcode, &pResults);
if (pResults)
{
int count = pResults->resultsCount;
int i = 0;
char strLocalization[128];
for (; i < count; i++)
{
zval tmp_array;
array_init(&tmp_array);
add_next_index_string(&tmp_array, pResults->results[i]->barcodeFormatString);
add_next_index_string(&tmp_array, pResults->results[i]->barcodeText);
add_next_index_stringl(&tmp_array, pResults->results[i]->barcodeBytes, pResults->results[i]->barcodeBytesLength);
memset(strLocalization, 0, 128);
sprintf(strLocalization, "[(%d,%d),(%d,%d),(%d,%d),(%d,%d)]", \
pResults->results[i]->localizationResult->x1, pResults->results[i]->localizationResult->y1, \
pResults->results[i]->localizationResult->x2, pResults->results[i]->localizationResult->y2, \
pResults->results[i]->localizationResult->x3, pResults->results[i]->localizationResult->y3, \
pResults->results[i]->localizationResult->x4, pResults->results[i]->localizationResult->y4);
add_next_index_string(&tmp_array, strLocalization);
add_next_index_zval(return_value, &tmp_array);
}
DBR_FreeTextResults(&pResults);
}
}
}
static const zend_function_entry dbr_functions[] = {
PHP_FE(DBRInitLicense, NULL)
PHP_FE(DecodeBarcodeFile, NULL)
PHP_FE_END
};
config.w32 for Windows
To link DBRx64.lib
, we specify LDFLAGS
with linker options in the config.w32
file.
ARG_ENABLE('dbr', 'dbr support', 'no');
if (PHP_DBR != 'no') {
lib_path = "ext\\dbr";
ADD_FLAG("LDFLAGS", '/libpath:"' + lib_path + '" /DYNAMICBASE "DBRx64.lib"');
AC_DEFINE('HAVE_DBR', 1, 'dbr support enabled');
EXTENSION('dbr', 'dbr.c', null, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1');
}
config.m4 for Linux
To link shared libraries on Linux, we edit the config.m4
file.
PHP_ARG_ENABLE([dbr],
[whether to enable dbr support],
[AS_HELP_STRING([--enable-dbr],
[Enable dbr support])],
[no])
if test "$PHP_DBR" != "no"; then
LIBNAME=DynamsoftBarcodeReader
LIBSYMBOL=DBR_CreateInstance
PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
[
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, /usr/lib, DBR_SHARED_LIBADD)
AC_DEFINE(HAVE_DBRLIB,1,[ ])
],[
AC_MSG_ERROR([wrong dbr lib version or lib not found])
],[
-L$DBR_DIR/$PHP_LIBDIR -lm
])
PHP_SUBST(DBR_SHARED_LIBADD)
AC_DEFINE(HAVE_DBR, 1, [ Have dbr support ])
PHP_NEW_EXTENSION(dbr, dbr.c, $ext_shared)
fi
Then copy libDynamicPdf.so
, libDynamsoftBarcodeReader.so
, libDynamsoftLicenseClient.so
to the /usr/bin
directory.
Steps to Build and Install the PHP Extension
You can build the extension in two ways: from the source code or by using pre-built binaries.
Build the PHP Extension from Source Code
Windows
cd php-7.4.30-src
buildconf
configure --disable-all --enable-cli --enable-dbr
nmake
Linux
cd php-7.4.30-src
./buildconf
./configure --disable-all --enable-cli --enable-dbr
make
By default, the extension is statically linked. To build shared libraries, we can modify the line:
- configure --disable-all --enable-cli --enable-dbr
+ configure --disable-all --enable-cli --enable-dbr=shared
Build the PHP Extension with phpize
Windows
cd php-7.4.30-src/ext/dbr
phpize
configure --enable-dbr
nmake
Linux
cd php-7.4.30-src/ext/dbr
phpize
./configure --enable-dbr
make
Install the PHP Extension with *.dll and *.so Files
Windows
- Add
extension=dbr
to yourphp.ini
file. -
Copy the generated
php_dbr.dll
to thephp/ext/
folder, and also copyDynamicPdfx64.dll
,DynamsoftBarcodeReaderx64.dll
,DynamsoftLicenseClientx64.dll
andvcomp110.dll
to the PHP root directory.Alternatively, you can add the folder containing the DLLs to the system path for easier management.
Linux
- Add
extension=dbr
to/etc/php/7.4/cli/php.ini
. - Execute
sudo make install
to install the extension system-wide.
Test the PHP Barcode QR Code Reader Extension
-
Create a PHP script named
reader.php
that reads barcodes and QR codes from a local image. ReplaceLICENSE-KEY
with your own license key.<?php $filename = "AllSupportedBarcodeTypes.tif"; if (file_exists($filename)) { echo "Barcode file: $filename \n"; // Get license key from https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform DBRInitLicense("LICENSE-KEY"); //Best coverage settings DBRInitRuntimeSettingsWithString("{\"ImageParameter\":{\"Name\":\"BestCoverage\",\"DeblurLevel\":9,\"ExpectedBarcodesCount\":512,\"ScaleDownThreshold\":100000,\"LocalizationModes\":[{\"Mode\":\"LM_CONNECTED_BLOCKS\"},{\"Mode\":\"LM_SCAN_DIRECTLY\"},{\"Mode\":\"LM_STATISTICS\"},{\"Mode\":\"LM_LINES\"},{\"Mode\":\"LM_STATISTICS_MARKS\"}],\"GrayscaleTransformationModes\":[{\"Mode\":\"GTM_ORIGINAL\"},{\"Mode\":\"GTM_INVERTED\"}]}}"); $resultArray = DecodeBarcodeFile($filename, 0x3FF | 0x2000000 | 0x4000000 | 0x8000000 | 0x10000000); // 1D, PDF417, QRCODE, DataMatrix, Aztec Code if (is_array($resultArray)) { $resultCount = count($resultArray); echo "Total count: $resultCount\n"; for ($i = 0; $i < $resultCount; $i++) { $result = $resultArray[$i]; echo "Barcode format: $result[0], "; echo "value: $result[1], "; echo "raw: ", bin2hex($result[2]), "\n"; echo "Localization : ", $result[3], "\n"; } } else { echo "$resultArray[0]"; } } else { echo "The file $filename does not exist"; } ?>
-
Execute the PHP script in the terminal.
php reader.php
Source Code
https://github.com/yushulx/php-laravel-barcode-qr-reader/tree/main/ext/dbr