Ubuntu上轻松实现PHP扩展

╄→гoц情女王★ 提交于 2019-12-02 03:30:34

对比Windows,Linux上实现PHP扩展要简单轻松的多。

参考原文:How to Make PHP Barcode Reader on Linux

作者:Xiao Ling

翻译:yushulx

几步构建PHP Barcode扩展

安装DBR

要构建PHP扩展,一定要使用对应版本的源码:

php –v

下载PHP源码

解压代码,切换到ext目录:

cd ~/Downloads/php-5.5.9/ext

创建扩展dbr:

./ext_skel --extname=dbr
cd dbr

编辑config.m4,添加头文件和库文件路径:

PHP_ARG_ENABLE(dbr, whether to enable dbr support,
 
dnl Make sure that the comment is aligned:
 
[  --enable-dbr           Enable dbr support])
 
if test "$PHP_DBR" != "no"; then
 
  PHP_ADD_LIBRARY_WITH_PATH(DynamsoftBarcodeReaderx64, /home/xiao/Dynamsoft/BarcodeReader4.0/Redist, DBR_SHARED_LIBADD) 
 
  PHP_ADD_INCLUDE(/home/xiao/Dynamsoft/BarcodeReader4.0/Include)
 
  PHP_SUBST(DBR_SHARED_LIBADD)
 
  PHP_NEW_EXTENSION(dbr, dbr.c, $ext_shared)
 
fi
 

编辑dbr.c:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
 
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_dbr.h"
 
#include "If_DBR.h"
#include "BarcodeFormat.h"
#include "BarcodeStructs.h"
#include "ErrorCode.h"
#include <stdbool.h>
 
/* If you declare any globals in php_dbr.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(dbr)
*/
 
/* True global resources - no need for thread safety here */
static int le_dbr;
 
/* {{{ dbr_functions[]
 *
 * Every user visible function must have an entry in dbr_functions[].
 */
const zend_function_entry dbr_functions[] = {
    PHP_FE(DecodeBarcodeFile,   NULL)       /* For testing, remove later. */
    PHP_FE_END  /* Must be the last line in dbr_functions[] */
};
/* }}} */
 
/* {{{ dbr_module_entry
 */
zend_module_entry dbr_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,
#endif
    "dbr",
    dbr_functions,
    PHP_MINIT(dbr),
    PHP_MSHUTDOWN(dbr),
    PHP_RINIT(dbr),     /* Replace with NULL if there's nothing to do at request start */
    PHP_RSHUTDOWN(dbr), /* Replace with NULL if there's nothing to do at request end */
    PHP_MINFO(dbr),
#if ZEND_MODULE_API_NO >= 20010901
    PHP_DBR_VERSION,
#endif
    STANDARD_MODULE_PROPERTIES
};
/* }}} */
 
#ifdef COMPILE_DL_DBR
ZEND_GET_MODULE(dbr)
#endif
 
/* {{{ PHP_INI
 */
/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
    STD_PHP_INI_ENTRY("dbr.global_value",      "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_dbr_globals, dbr_globals)
    STD_PHP_INI_ENTRY("dbr.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_dbr_globals, dbr_globals)
PHP_INI_END()
*/
/* }}} */
 
/* {{{ php_dbr_init_globals
 */
/* Uncomment this function if you have INI entries
static void php_dbr_init_globals(zend_dbr_globals *dbr_globals)
{
    dbr_globals->global_value = 0;
    dbr_globals->global_string = NULL;
}
*/
/* }}} */
 
/* {{{ PHP_MINIT_FUNCTION
 */
PHP_MINIT_FUNCTION(dbr)
{
    /* If you have INI entries, uncomment these lines 
    REGISTER_INI_ENTRIES();
    */
    return SUCCESS;
}
/* }}} */
 
/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(dbr)
{
    /* uncomment this line if you have INI entries
    UNREGISTER_INI_ENTRIES();
    */
    return SUCCESS;
}
/* }}} */
 
/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(dbr)
{
    return SUCCESS;
}
/* }}} */
 
/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
PHP_RSHUTDOWN_FUNCTION(dbr)
{
    return SUCCESS;
}
/* }}} */
 
/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(dbr)
{
    php_info_print_table_start();
    php_info_print_table_header(2, "dbr support", "enabled");
    php_info_print_table_end();
 
    /* Remove comments if you have entries in php.ini
    DISPLAY_INI_ENTRIES();
    */
}
/* }}} */
 
// Barcode format
const char * GetFormatStr(__int64 format)
{
    if (format == CODE_39)
        return "CODE_39";
    if (format == CODE_128)
        return "CODE_128";
    if (format == CODE_93)
        return "CODE_93";
    if (format == CODABAR)
        return "CODABAR";
    if (format == ITF)
        return "ITF";
    if (format == UPC_A)
        return "UPC_A";
    if (format == UPC_E)
        return "UPC_E";
    if (format == EAN_13)
        return "EAN_13";
    if (format == EAN_8)
        return "EAN_8";
    if (format == INDUSTRIAL_25)
        return "INDUSTRIAL_25";
    if (format == QR_CODE)
        return "QR_CODE";
    if (format == PDF417)
        return "PDF417";
    if (format == DATAMATRIX)
        return "DATAMATRIX";
 
    return "UNKNOWN";
}
 
PHP_FUNCTION(DecodeBarcodeFile)
{
    array_init(return_value);
 
    // Get Barcode image path
    char* pFileName = NULL;
    bool isNativeOuput = false;
    bool isLogOn = false;
    int iLen = 0;
 
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb|b", &pFileName, &iLen, &isNativeOuput, &isLogOn) == FAILURE) {
        RETURN_STRING("Invalid parameters", true);
    }
 
    if (isLogOn)
    {
        printf("params: %s, %d, %d\n", pFileName, iLen, isNativeOuput);
    }
 
    // Dynamsoft Barcode Reader: init
    __int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX);
    int iMaxCount = 0x7FFFFFFF;
    int iIndex = 0;
    ReaderOptions ro = {0};
    pBarcodeResultArray pResults = NULL;
    int iRet = -1;
    char * pszTemp = NULL;
 
    // Initialize license
    iRet = DBR_InitLicense("84D34246FC1BC4BDD4078D71FCB5A3AA");
    printf("DBR_InitLicense ret: %d\n", iRet);
    ro.llBarcodeFormat = llFormat;
    ro.iMaxBarcodesNumPerPage = iMaxCount;
 
    // Decode barcode image
    int ret = DBR_DecodeFile(pFileName, &ro, &pResults);
    if (ret == DBR_OK)
    {
        int count = pResults->iBarcodeCount;
        pBarcodeResult* ppBarcodes = pResults->ppBarcodes;
        pBarcodeResult tmp = NULL;
        char result[2048] = {0};
        int i = 0;
        if (count == 0)
        {
            add_next_index_string(return_value, "No Barcode detected", true);
        }
 
        // loop all results
        for (; i < count; i++)
        {
            char barcodeResult[1024];
 
            // A barcode result.
            tmp = ppBarcodes[i];
            {
                // Working with PHP array: http://php.net/manual/en/internals2.variables.arrays.php
                zval *tmp_array;
                // Initialize zval
                MAKE_STD_ZVAL(tmp_array);
                array_init(tmp_array);
                // Add format & value to an array
                add_next_index_string(tmp_array, GetFormatStr(tmp->llFormat), true);
                add_next_index_string(tmp_array, tmp->pBarcodeData, true);
                // Add result to returned array
                add_next_index_zval(return_value, tmp_array);
            }
        }
 
        // Dynamsoft Barcode Reader: release memory
        DBR_FreeBarcodeResults(&pResults);
 
        if (isLogOn && isNativeOuput)
        {
            printf("Native result: %s\n", result);
        }
 
        if (isNativeOuput)
        {
            add_next_index_string(return_value, result, true);
        }
    }
    else
    {
        add_next_index_string(return_value, "No Barcode detected", true);
    }
 
}
 

要独立构建PHP扩展模块,需要使用phpize。安装开发包:

sudo apt-get install php5-dev

构建PHP扩展模块:

phpize
./configure
make
 

C90规范不支持布尔类型。如果看到错误“unknown type name ‘bool’”,加上头文件:

#include <stdbool.h>

动态链接库dbr.so会自动生成到目录modules下面:


简单的PHP Barcode应用

创建reader.php:

<?php
$filename = "/home/xiao/Dynamsoft/BarcodeReader4.0/Images/AllSupportedBarcodeTypes.tif";
if (file_exists($filename)) {
  echo "Barcode file: $filename \n";
  $resultArray = DecodeBarcodeFile($filename, 0);
  if (is_array($resultArray[0])) {
    $resultCount = count($resultArray);
    echo "Total count: $resultCount\n";
    for($i = 0; $i < $resultCount ; $i++) {
        $result = $resultArray[$i];
            echo "Barcode format: $result[0], value: $result[1]\n";
    }
  }
  else {
    echo "$resultArray[0]";
  }
} else {
    echo "The file $filename does not exist";
}
?>
 

安装刚才编译出来的扩展:

sudo make install

把安装之后的路径(/usr/lib/php5/20121212/dbr.so)加入到php.ini文件中:

locate php.ini

通过命令找寻php.ini文件会发现有好几个相关的。到底用哪个呢?可以随便选一个或者新建一个。我选择了php.ini-production :

extension=/usr/lib/php5/20121212/dbr.so

运行PHP barcode reader,记得带上php.ini的文件路径:

php -c /usr/share/php5/php.ini-production reader.php

源码

https://github.com/dynamsoftlabs/linux-php-barcode-reader-


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!