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

  • Anup

    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

  • http://www.dynamsoft.com/ Xiao Ling

    No. Nginx is just a Web server. Alternatively, you can use Apache or other Web server to work with PHP.

  • Anup

    Oh! I see, for php module to work from CLI
    Nginx is not necessary?

  • http://www.dynamsoft.com/ Xiao Ling

    You’re welcome. This article only shares how to create a PHP module, not a Web app. Nginx is the Web server used for Web app. I mentioned Nginx in another article: http://www.codepool.biz/php-nginx-web-barcode-reader.html

  • Anup

    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

  • http://www.dynamsoft.com/ Xiao Ling

    php5.5.12 and php-5.6.16-src may be the problem. Please use the same version number.

  • Anup

    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

  • Anup

    yes I have,
    //php.ini
    [Dynamsoft Barcode Reader]
    extension=php_dbr.dll

  • http://www.dynamsoft.com/ Xiao Ling

    Have you configured php.ini? Specify
    extension_dir = “./” and extension=php_dbr.dll

  • Anup

    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)

  • http://www.dynamsoft.com/ Xiao Ling

    Please check whether you have successfully load DynamsoftBarcodeReaderx86.dll (DynamsoftBarcodeReaderx64.dll for 64bit) and php_dbr.dll

  • Anup

    Following is the error I get on executing the php file
    “Call to undefined function DecodeBarcodeFile()”