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.

Dynamsoft Barcode Reader SDK
Ads Powered by Dynamsoft

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:

  1. Download and unzip PHP 5.6 source code and VC11 build.
  2. Install Bison for Windows.
  3. Run <Visual Studio 11.0>VC\bin\vcvars32.bat to register variables. The path of cl.exe is required.
  4. Run <php-5.6.10-src>\buildconf.bat.
  5. Run <php-5.6.10-src>\configure.bat to generate config.w32.h in main folder.
  6. Create an empty Win32 project with application type DLL.PHP extension project
  7. 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
  8. Add Library directories:
    F:\php_pack\php-5.6.10-Win32-VC11-x86\dev
  9. Add dependency:
    php5ts.lib
  10. Create php_dbr.h with following code:
    #pragma once
    
    #include "zend_config.w32.h"    
    #include "php.h"
  11. 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);
    }
  12. Add preprocessor definitions:
    ZEND_DEBUG=0
    ZTS=1
    ZEND_WIN32
    PHP_WIN32

    If you build the project directly, you will see many errors.

    PHP preprocessor errors

  13. Build your project to generate php_dbr.dll.

Making PHP Barcode Reader with Dynamsoft Barcode Reader SDK

Download and install Dynamsoft Barcode Reader.

DBR download button

Let’s take a glimpse of how to use PHP extension to call third-party DLL libraries:

  1. Add Include directories and Library directories of Dynamsoft Barcode Reader SDK to project properties.
  2. Copy the sample code written in previous Python or Node.js examples.
  3. 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

php.ini configuration

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:

PHP DLL error

How to fix this issue? You just need to copy the DLL file to PHP root directory. Try it again:

PHP Barcode Reader Extension

Source Code

https://github.com/dynamsoftsamples/php-barcode-extension

12 thoughts on “Making PHP Barcode Extension with Dynamsoft Barcode SDK

  1. I do have apache webserver(with wamp) on which i’m hosting the php pages, i guess i got a wrong info, i’m running Nginx as well which may not be required as you said

  2. the issue was i followed only this thread! and not the one on github hence i was missing nginx installation,
    and as u mentioned the version mismatch was an issue later, thankfully fixed everything now!!
    thanks for the reply

  3. I’ve installed php5.5.12 on my system
    and have referred the src files of php-5.6.16-src to compile php_dbr.dll
    any idea if thats a matter of concern

  4. yes I have tried placing both “DynamsoftBarcodeReaderx86.dll” / “DynamsoftBarcodeReaderx64.dll” in php_root_directory(C:wampbinphpphp5.5.12)

    and

    php_dbr.dll is placed in php_root_directory/ext(C:wampbinphpphp5.5.12ext)

Comments are closed.