Building Enterprise-class PHP Barcode Extension for Web Development

This article guides you through the process of creating an enterprise-class PHP barcode extension with Dynamsoft Barcode Reader and PHP source code on Ubuntu 18.04.

Environment

Ubuntu 18.04

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.5 LTS
Release:        18.04
Codename:       bionic

Install PHP and Dynamsoft C++ Barcode SDK on Ubuntu 18.04

  • PHP

    Install php-cli, php-dev and libxml2-dev. The default php version installed by Ubuntu 18.04 is 7.2.24.

    ```bash
    sudo apt install php-cli php-dev libxml2-dev
    ```
    
  • Dynamsoft Barcode Reader

    1. Download the C++ SDK package.
    2. Extract the shared libraries and copy them to /usr/lib:

       unzip dbr-c_cpp-8.8.zip
       sudo cp DynamsoftBarcodeReader/Lib/Linux/*.so /usr/lib    
      

Steps to Build and Install PHP Barcode Extension

  1. Check the php version via php -v and then download the corresponding source code:

     tar -xzf php-php-7.4.27.tar.gz
     cd php-php-7.4.27/ext/
    
  2. Create an extension directory by running ext_skel.php:

     php ext_skel.php --ext dbr
    

    PHP barcode extension

    If you are using an old PHP version, the command may look like this:

     ./ext_skel --extname=dbr
    

    PHP barcode extension

  3. Change the directory to dbr folder and edit config.m4 as follows:

     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
    
  4. Configure and build the extension.

     phpize
     ./configure
     make
    

    A shared library dbr.so will be generated under modules folder.

  5. Install the PHP barcode extension:

     sudo make install
    
  6. Configure the php.ini file to make the custom shared library loaded by PHP environment:

     sudo nano /etc/php/7.<version>/cli/php.ini
     extension=dbr.so
    

Writing C Code for PHP Barcode Extension

Now, it is time to write C code to bridge PHP and the barcode SDK.

Here is an example of creating a function DecodeBarcodeFile() in dbr.c.

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);
		}
	}
}

Once the implementation is done, the function name needs to be added to the function entry array:

const zend_function_entry dbr_functions[] = {
	PHP_FE(DecodeBarcodeFile,   NULL) 
	PHP_FE_END	/* Must be the last line in dbr_functions[] */
};

In the same way, you can add the following functions that are required to make the SDK work:

const zend_function_entry dbr_functions[] = {
	PHP_FE(DBRInitLicense, NULL)
	PHP_FE(DBRInitRuntimeSettingsWithString, NULL)
	PHP_FE(DecodeBarcodeFile, NULL)
	PHP_FE(DBRCreate, NULL)
	PHP_FE(DBRDestroy, NULL)
	PHP_FE_END /* Must be the last line in dbr_functions[] */
};

Finally, re-build and re-install the extension.

make
sudo make install

To support more barcode APIs in PHP, read the online SDK documentation.

Test PHP Barcode Extension

So far, we have created a simple PHP barcode extension. Let’s do a quick test. A valid license key is required.

<?php

$filename = "AllSupportedBarcodeTypes.tif";
if (file_exists($filename)) {
  echo "Barcode file: $filename \n";

  // https://www.dynamsoft.com/customer/license/trialLicense?product=dbr
  DBRInitLicense("LICENSE-KEY");
  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";
}
?>

If you can see the barcode decoding results successfully, it means the PHP barcode extension is ready for use.

php -c /etc/php/7.2/cli/php.ini reader.php

PHP barcode reader

Source Code

https://github.com/dynamsoft-dbr/linux-php-barcode-reader-