对比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=dbrcd 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_DBRZEND_GET_MODULE(dbr)#endif /* {{{ PHP_INI *//* Remove comments and fill if you need to have entries in php.iniPHP_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 entriesstatic 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 formatconst 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./configuremake
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-

计算PHP多维数组的元素总数可以使用递归或迭代方法。1.递归方法通过遍历数组并递归处理嵌套数组来计数。2.迭代方法使用栈来模拟递归,避免深度问题。3.array_walk_recursive函数也能实现,但需手动计数。

在PHP中,do-while循环的特点是保证循环体至少执行一次,然后再根据条件决定是否继续循环。1)它在条件检查之前执行循环体,适合需要确保操作至少执行一次的场景,如用户输入验证和菜单系统。2)然而,do-while循环的语法可能导致新手困惑,且可能增加不必要的性能开销。

在PHP中高效地哈希字符串可以使用以下方法:1.使用md5函数进行快速哈希,但不适合密码存储。2.使用sha256函数提高安全性。3.使用password_hash函数处理密码,提供最高安全性和便捷性。

在PHP中实现数组滑动窗口可以通过函数slidingWindow和slidingWindowAverage来完成。1.使用slidingWindow函数可以将数组分割成固定大小的子数组。2.使用slidingWindowAverage函数可以在每个窗口内计算平均值。3.对于实时数据流,可以使用ReactPHP进行异步处理和异常值检测。

PHP中的__clone方法用于在对象克隆时进行自定义操作。使用clone关键字克隆对象时,如果对象有__clone方法,会自动调用该方法,允许在克隆过程中进行定制化处理,如重置引用类型属性以确保克隆对象的独立性。

在PHP中,goto语句用于无条件跳转到程序中的特定标签。1)它可以简化复杂嵌套循环或条件语句的处理,但2)使用goto可能导致代码难以理解和维护,3)建议优先使用结构化控制语句。整体而言,goto应谨慎使用,并遵循最佳实践以确保代码的可读性和可维护性。

在PHP中,数据统计可以通过使用内置函数、自定义函数和第三方库来实现。1)使用内置函数如array_sum()和count()进行基本统计。2)编写自定义函数计算中位数等复杂统计。3)利用PHP-ML库进行高级统计分析。通过这些方法,可以高效地进行数据统计。

是的,PHP中的匿名函数是指没有名字的函数。它们可以作为参数传递给其他函数,并作为函数的返回值,使代码更加灵活和高效。使用匿名函数时需要注意作用域和性能问题。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Atom编辑器mac版下载
最流行的的开源编辑器

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境