├── .svnignore ├── CREDITS ├── EXPERIMENTAL ├── README.md ├── config.h.in~ ├── config.m4 ├── config.w32 ├── php_qrencode.h ├── qrencode.c ├── qrencode.php └── tests └── 001.phpt /.svnignore: -------------------------------------------------------------------------------- 1 | .deps 2 | *.lo 3 | *.la 4 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | qrencode 2 | -------------------------------------------------------------------------------- /EXPERIMENTAL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Leon2012/php-qrencode/43c192a65b75fee5da14173f82ccbef6315a4129/EXPERIMENTAL -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # php-qrencode 2 | 3 | 基于libqrencode+libgd的生成二维码的php扩展 4 | 5 | 6 | ## 安装: 7 | 8 | 1,安装libpng & libjpg 9 | 10 | sudo apt-get install libpng-dev 11 | sudo apt-get install libjpeg-dev 12 | 13 | 2,安装libqrencode 14 | 15 | wget http://fukuchi.org/works/qrencode/qrencode-3.4.4.tar.gz 16 | tar zxvf qrencode-3.4.4.tar.gz 17 | cd qrencode-3.4.4/ 18 | ./configure 19 | make&make install 20 | 21 | 3,安装libgd 22 | 23 | sudo apt-get install libgd-dev 24 | 25 | 4,安装php-qrencode 26 | 27 | git clone https://github.com/Leon2012/php-qrencode 28 | cd php-qrencode 29 | phpize 30 | ./configure 31 | make&sudo make install 32 | 33 | 5,修改配置文件 34 | 35 | vi php.ini 36 | extension=qrencode.so 37 | 38 | ## 用法: 39 | 48 | 49 | ## 和phpqrcode对比 50 | 51 | php-qrencode代码: 52 | 53 | 62 | 63 | 运行时间:0.60701370239258:ms 64 | 65 | phpqrcode代码: 66 | 67 | 76 | 运行时间:23.189067840576:ms 77 | 78 | -------------------------------------------------------------------------------- /config.h.in~: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.in by autoheader. */ 2 | 3 | /* Whether to build qrencode as dynamic module */ 4 | #undef COMPILE_DL_QRENCODE 5 | 6 | /* Define to 1 if you have the header file. */ 7 | #undef HAVE_DLFCN_H 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_INTTYPES_H 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_MEMORY_H 14 | 15 | /* */ 16 | #undef HAVE_QRENCODELIB 17 | 18 | /* Define to 1 if you have the header file. */ 19 | #undef HAVE_STDINT_H 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #undef HAVE_STDLIB_H 23 | 24 | /* Define to 1 if you have the header file. */ 25 | #undef HAVE_STRINGS_H 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #undef HAVE_STRING_H 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #undef HAVE_SYS_STAT_H 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #undef HAVE_SYS_TYPES_H 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #undef HAVE_UNISTD_H 38 | 39 | /* Define to 1 if your C compiler doesn't accept -c and -o together. */ 40 | #undef NO_MINUS_C_MINUS_O 41 | 42 | /* Define to the address where bug reports for this package should be sent. */ 43 | #undef PACKAGE_BUGREPORT 44 | 45 | /* Define to the full name of this package. */ 46 | #undef PACKAGE_NAME 47 | 48 | /* Define to the full name and version of this package. */ 49 | #undef PACKAGE_STRING 50 | 51 | /* Define to the one symbol short name of this package. */ 52 | #undef PACKAGE_TARNAME 53 | 54 | /* Define to the home page for this package. */ 55 | #undef PACKAGE_URL 56 | 57 | /* Define to the version of this package. */ 58 | #undef PACKAGE_VERSION 59 | 60 | /* Define to 1 if you have the ANSI C header files. */ 61 | #undef STDC_HEADERS 62 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | PHP_ARG_WITH(qrencode_dir, for qrencode support, 2 | [ --with-qrencode-dir=[DIR] Include qrencode support]) 3 | 4 | 5 | PHP_ARG_ENABLE(qrencode, whether to enable qrencode support, 6 | [ --enable-qrencode Enable qrencode support]) 7 | 8 | if test "$PHP_QRENCODE_DIR" != "no"; then 9 | SEARCH_PATH="/usr/local /usr" 10 | SEARCH_FOR="/include/qrencode.h" 11 | if test -r $PHP_QRENCODE_DIR/$SEARCH_FOR; then # path given as parameter 12 | QRENCODE_DIR=$PHP_QRENCODE_DIR 13 | else 14 | AC_MSG_CHECKING([for qrencode files in default path]) 15 | for i in $SEARCH_PATH ; do 16 | if test -r $i/$SEARCH_FOR; then 17 | QRENCODE_DIR=$i 18 | AC_MSG_RESULT(found in $i) 19 | fi 20 | done 21 | fi 22 | 23 | if test -z "$QRENCODE_DIR"; then 24 | AC_MSG_RESULT([not found]) 25 | AC_MSG_ERROR([Please reinstall the qrencode distribution]) 26 | fi 27 | 28 | 29 | PHP_ADD_INCLUDE($QRENCODE_DIR/include) 30 | 31 | 32 | LIBNAME=qrencode 33 | LIBSYMBOL=QRcode_APIVersionString 34 | 35 | PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 36 | [ 37 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $QRENCODE_DIR/$PHP_LIBDIR, QRENCODE_SHARED_LIBADD) 38 | PHP_ADD_LIBRARY_WITH_PATH(gd, $QRENCODE_DIR/$PHP_LIBDIR, QRENCODE_SHARED_LIBADD) 39 | 40 | AC_DEFINE(HAVE_QRENCODELIB,1,[ ]) 41 | ],[ 42 | AC_MSG_ERROR([wrong qrencode lib version or lib not found]) 43 | ],[ 44 | -L$QRENCODE_DIR/$PHP_LIBDIR -lm 45 | ]) 46 | 47 | PHP_SUBST(QRENCODE_SHARED_LIBADD) 48 | 49 | PHP_NEW_EXTENSION(qrencode, qrencode.c, $ext_shared) 50 | fi 51 | 52 | 53 | dnl PHP_ARG_WITH(gd, for libgd support, 54 | dnl [ --with-gd[=DIR] Include gd support]) 55 | 56 | dnl if test "$PHP_GD" != "no"; then 57 | dnl if test -r $PHP_GD/lib/libgd.a; then 58 | dnl GD_DIR=$PHP_GD 59 | dnl else 60 | dnl AC_MSG_CHECKING(for libgd in default path) 61 | dnl for i in /usr/local/opt/gd /usr/local /usr ; do 62 | dnl if test -r $i/lib/libgd.a; then 63 | dnl GD_DIR=$i 64 | dnl AC_MSG_RESULT(found in $i) 65 | dnl fi 66 | dnl done 67 | dnl fi 68 | dnl 69 | dnl if test -z "$GD_DIR"; then 70 | dnl AC_MSG_RESULT(not found) 71 | dnl AC_MSG_ERROR(please install gd ) 72 | dnl fi 73 | dnl PHP_ADD_INCLUDE($GD_DIR/include) 74 | 75 | dnl PHP_ADD_LIBRARY_WITH_PATH(gd, $GD_DIR/lib, QRENCODE_SHARED_LIBADD) 76 | dnl AC_DEFINE(HAVE_GD,1,[ ]) 77 | dnl 78 | dnl PHP_SUBST(QRENCODE_SHARED_LIBADD) 79 | dnl 80 | dnl PHP_EXTENSION(qrencode, $ext_shared) 81 | dnl fi 82 | 83 | 84 | if test -z "$PHP_DEBUG"; then 85 | AC_ARG_ENABLE(debug, 86 | [ --enable-debug compile with debugging symbols],[ 87 | PHP_DEBUG=$enableval 88 | ],[ PHP_DEBUG=no 89 | ]) 90 | fi 91 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | // If your extension references something external, use ARG_WITH 5 | // ARG_WITH("qrencode", "for qrencode support", "no"); 6 | 7 | // Otherwise, use ARG_ENABLE 8 | // ARG_ENABLE("qrencode", "enable qrencode support", "no"); 9 | 10 | if (PHP_QRENCODE != "no") { 11 | EXTENSION("qrencode", "qrencode.c"); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /php_qrencode.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2014 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef PHP_QRENCODE_H 22 | #define PHP_QRENCODE_H 23 | 24 | extern zend_module_entry qrencode_module_entry; 25 | #define phpext_qrencode_ptr &qrencode_module_entry 26 | 27 | #define PHP_QRENCODE_VERSION "0.1.0" /* Replace with version number for your extension */ 28 | 29 | #ifdef PHP_WIN32 30 | # define PHP_QRENCODE_API __declspec(dllexport) 31 | #elif defined(__GNUC__) && __GNUC__ >= 4 32 | # define PHP_QRENCODE_API __attribute__ ((visibility("default"))) 33 | #else 34 | # define PHP_QRENCODE_API 35 | #endif 36 | 37 | #ifdef ZTS 38 | #include "TSRM.h" 39 | #endif 40 | 41 | PHP_MINIT_FUNCTION(qrencode); 42 | PHP_MSHUTDOWN_FUNCTION(qrencode); 43 | PHP_RINIT_FUNCTION(qrencode); 44 | PHP_RSHUTDOWN_FUNCTION(qrencode); 45 | PHP_MINFO_FUNCTION(qrencode); 46 | 47 | // PHP_FUNCTION(qrcode_version); 48 | // PHP_FUNCTION(gd_version); 49 | 50 | PHP_FUNCTION(qrencode_version); 51 | PHP_FUNCTION(qrencode_create); 52 | PHP_FUNCTION(qrencode_save); 53 | PHP_FUNCTION(qrencode_output); 54 | 55 | 56 | 57 | ZEND_BEGIN_MODULE_GLOBALS(qrencode) 58 | long version; 59 | long level; 60 | long hint; 61 | long casesensitive; 62 | ZEND_END_MODULE_GLOBALS(qrencode) 63 | 64 | /* In every utility function you add that needs to use variables 65 | in php_qrencode_globals, call TSRMLS_FETCH(); after declaring other 66 | variables used by that function, or better yet, pass in TSRMLS_CC 67 | after the last function argument and declare your utility function 68 | with TSRMLS_DC after the last declared argument. Always refer to 69 | the globals in your function as QRENCODE_G(variable). You are 70 | encouraged to rename these macros something shorter, see 71 | examples in any other php module directory. 72 | */ 73 | 74 | #ifdef ZTS 75 | #define QRENCODE_G(v) TSRMG(qrencode_globals_id, zend_qrencode_globals *, v) 76 | #else 77 | #define QRENCODE_G(v) (qrencode_globals.v) 78 | #endif 79 | 80 | #endif /* PHP_QRENCODE_H */ 81 | 82 | 83 | /* 84 | * Local variables: 85 | * tab-width: 4 86 | * c-basic-offset: 4 87 | * End: 88 | * vim600: noet sw=4 ts=4 fdm=marker 89 | * vim<600: noet sw=4 ts=4 90 | */ 91 | -------------------------------------------------------------------------------- /qrencode.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2014 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | #include "php.h" 27 | #include "php_ini.h" 28 | #include "ext/standard/info.h" 29 | //#include "ext/gd/libgd/gd.h" 30 | #include "php_qrencode.h" 31 | #include "SAPI.h" 32 | #include 33 | 34 | //#include "main/php_compat.h" 35 | //#include "ext/gd/php_gd.h" 36 | 37 | 38 | #define QRENCODE_RESOURCE_TYPE "Qrencode" 39 | 40 | //fix buy main/php_compat.h 41 | #define gdImageCreate gdImageCreate 42 | #define gdImagePng gdImagePng 43 | #define gdImageDestroy gdImageDestroy 44 | #define gdImageColorAllocate gdImageColorAllocate 45 | #define gdImageFill gdImageFill 46 | #define gdImageFilledRectangle gdImageFilledRectangle 47 | 48 | gdImagePtr qrcode_png(QRcode *code, int fg_color[3], int bg_color[3], int size, int margin); 49 | 50 | ZEND_DECLARE_MODULE_GLOBALS(qrencode) 51 | 52 | /* True global resources - no need for thread safety here */ 53 | static int le_qrencode; 54 | typedef struct _qrencode { 55 | QRcode *code; 56 | }qrencode; 57 | 58 | 59 | ZEND_BEGIN_ARG_INFO(qrencode_create_arginfo, 0) 60 | ZEND_ARG_INFO(0, str) 61 | ZEND_ARG_INFO(0, level) 62 | ZEND_ARG_INFO(0, hint) 63 | ZEND_END_ARG_INFO() 64 | 65 | 66 | ZEND_BEGIN_ARG_INFO(qrencode_save_arginfo, 0) 67 | ZEND_ARG_INFO(0, qrencode) 68 | ZEND_ARG_INFO(0, path) 69 | 70 | ZEND_ARG_INFO(0, red) 71 | ZEND_ARG_INFO(0, green) 72 | ZEND_ARG_INFO(0, blue) 73 | ZEND_END_ARG_INFO() 74 | 75 | ZEND_BEGIN_ARG_INFO(qrencode_output_arginfo, 0) 76 | ZEND_ARG_INFO(0, qrencode) 77 | 78 | ZEND_ARG_INFO(0, red) 79 | ZEND_ARG_INFO(0, green) 80 | ZEND_ARG_INFO(0, blue) 81 | ZEND_END_ARG_INFO() 82 | 83 | /* {{{ qrencode_functions[] 84 | * 85 | * Every user visible function must have an entry in qrencode_functions[]. 86 | */ 87 | const zend_function_entry qrencode_functions[] = { 88 | PHP_FE(qrencode_version, NULL) /* For testing, remove later. */ 89 | //PHP_FE(gd_version, NULL) 90 | PHP_FE(qrencode_create, qrencode_create_arginfo) 91 | PHP_FE(qrencode_save, qrencode_save_arginfo) 92 | PHP_FE(qrencode_output, qrencode_output_arginfo) 93 | PHP_FE_END /* Must be the last line in qrencode_functions[] */ 94 | }; 95 | /* }}} */ 96 | 97 | /* {{{ qrencode_module_entry 98 | */ 99 | zend_module_entry qrencode_module_entry = { 100 | #if ZEND_MODULE_API_NO >= 20010901 101 | STANDARD_MODULE_HEADER, 102 | #endif 103 | "qrencode", 104 | qrencode_functions, 105 | PHP_MINIT(qrencode), 106 | PHP_MSHUTDOWN(qrencode), 107 | PHP_RINIT(qrencode), /* Replace with NULL if there's nothing to do at request start */ 108 | PHP_RSHUTDOWN(qrencode), /* Replace with NULL if there's nothing to do at request end */ 109 | PHP_MINFO(qrencode), 110 | #if ZEND_MODULE_API_NO >= 20010901 111 | PHP_QRENCODE_VERSION, 112 | #endif 113 | STANDARD_MODULE_PROPERTIES 114 | }; 115 | /* }}} */ 116 | 117 | #ifdef COMPILE_DL_QRENCODE 118 | ZEND_GET_MODULE(qrencode) 119 | #endif 120 | 121 | PHP_INI_BEGIN() 122 | STD_PHP_INI_ENTRY("qrencode.version", "3", PHP_INI_ALL, OnUpdateLong, version, zend_qrencode_globals, qrencode_globals) 123 | STD_PHP_INI_ENTRY("qrencode.level", "2", PHP_INI_ALL, OnUpdateLong, level, zend_qrencode_globals, qrencode_globals) 124 | STD_PHP_INI_ENTRY("qrencode.hint", "2", PHP_INI_ALL, OnUpdateLong, hint, zend_qrencode_globals, qrencode_globals) 125 | STD_PHP_INI_ENTRY("qrencode.casesensitive", "1", PHP_INI_ALL, OnUpdateLong, casesensitive, zend_qrencode_globals, qrencode_globals) 126 | PHP_INI_END() 127 | 128 | 129 | /* {{{ php_qrencode_init_globals 130 | */ 131 | /* Uncomment this function if you have INI entries 132 | static void php_qrencode_init_globals(zend_qrencode_globals *qrencode_globals) 133 | { 134 | qrencode_globals->global_value = 0; 135 | qrencode_globals->global_string = NULL; 136 | } 137 | */ 138 | /* }}} */ 139 | 140 | 141 | /*释放resource资源,在脚本结束后执行*/ 142 | static void qrencode_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) { 143 | qrencode *q = (qrencode *)rsrc->ptr; 144 | if (q->code != NULL) { 145 | //QRcode_free(q->code); 146 | q->code = NULL; 147 | } 148 | efree(q); 149 | } 150 | 151 | 152 | /* {{{ PHP_MINIT_FUNCTION 153 | */ 154 | PHP_MINIT_FUNCTION(qrencode) 155 | { 156 | REGISTER_INI_ENTRIES(); 157 | 158 | REGISTER_LONG_CONSTANT("QRENCODE_QRECLEVEL_L", QR_ECLEVEL_L, CONST_CS|CONST_PERSISTENT); 159 | REGISTER_LONG_CONSTANT("QRENCODE_QRECLEVEL_M", QR_ECLEVEL_M, CONST_CS|CONST_PERSISTENT); 160 | REGISTER_LONG_CONSTANT("QRENCODE_QRECLEVEL_Q", QR_ECLEVEL_Q, CONST_CS|CONST_PERSISTENT); 161 | REGISTER_LONG_CONSTANT("QRENCODE_QRECLEVEL_H", QR_ECLEVEL_H, CONST_CS|CONST_PERSISTENT); 162 | 163 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_NUL", QR_MODE_NUL, CONST_CS|CONST_PERSISTENT); 164 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_NUM", QR_MODE_NUM, CONST_CS|CONST_PERSISTENT); 165 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_AN", QR_MODE_AN, CONST_CS|CONST_PERSISTENT); 166 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_8", QR_MODE_8, CONST_CS|CONST_PERSISTENT); 167 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_KANJI", QR_MODE_KANJI, CONST_CS|CONST_PERSISTENT); 168 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_STRUCTURE", QR_MODE_STRUCTURE, CONST_CS|CONST_PERSISTENT); 169 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_ECI", QR_MODE_ECI, CONST_CS|CONST_PERSISTENT); 170 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_FNC1FIRST", QR_MODE_FNC1FIRST, CONST_CS|CONST_PERSISTENT); 171 | REGISTER_LONG_CONSTANT("QRENCODE_MODE_FNC1SECOND", QR_MODE_FNC1SECOND, CONST_CS|CONST_PERSISTENT); 172 | 173 | le_qrencode = zend_register_list_destructors_ex(qrencode_dtor, NULL, QRENCODE_RESOURCE_TYPE, module_number); 174 | 175 | return SUCCESS; 176 | } 177 | /* }}} */ 178 | 179 | /* {{{ PHP_MSHUTDOWN_FUNCTION 180 | */ 181 | PHP_MSHUTDOWN_FUNCTION(qrencode) 182 | { 183 | 184 | UNREGISTER_INI_ENTRIES(); 185 | return SUCCESS; 186 | } 187 | /* }}} */ 188 | 189 | /* Remove if there's nothing to do at request start */ 190 | /* {{{ PHP_RINIT_FUNCTION 191 | */ 192 | PHP_RINIT_FUNCTION(qrencode) 193 | { 194 | return SUCCESS; 195 | } 196 | /* }}} */ 197 | 198 | /* Remove if there's nothing to do at request end */ 199 | /* {{{ PHP_RSHUTDOWN_FUNCTION 200 | */ 201 | PHP_RSHUTDOWN_FUNCTION(qrencode) 202 | { 203 | return SUCCESS; 204 | } 205 | /* }}} */ 206 | 207 | /* {{{ PHP_MINFO_FUNCTION 208 | */ 209 | PHP_MINFO_FUNCTION(qrencode) 210 | { 211 | php_info_print_table_start(); 212 | php_info_print_table_header(2, "qrencode support", "enabled"); 213 | php_info_print_table_end(); 214 | 215 | /* Remove comments if you have entries in php.ini 216 | DISPLAY_INI_ENTRIES(); 217 | */ 218 | } 219 | /* }}} */ 220 | 221 | 222 | 223 | // PHP_FUNCTION(qrcode_version) 224 | // { 225 | // RETURN_STRING(QRcode_APIVersionString(), 1); 226 | // } 227 | 228 | // PHP_FUNCTION(gd_version) 229 | // { 230 | // RETURN_STRING(GD_VERSION_STRING, 1); 231 | // } 232 | 233 | PHP_FUNCTION(qrencode_version) 234 | { 235 | RETURN_STRING(PHP_QRENCODE_VERSION, 1); 236 | } 237 | 238 | 239 | /*实例化并注册resource*/ 240 | PHP_FUNCTION(qrencode_create) 241 | { 242 | char *str; 243 | int str_len; 244 | qrencode *qe; 245 | 246 | long level = 0; 247 | long hint = 0; 248 | 249 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &str, &str_len, &level, &hint) == FAILURE) { 250 | RETURN_NULL(); 251 | } 252 | 253 | int version = (int)QRENCODE_G(version); 254 | int casesensitive = (int)QRENCODE_G(casesensitive); 255 | QRecLevel q_level = (int)QRENCODE_G(level); 256 | QRencodeMode q_hint = (int)QRENCODE_G(hint); 257 | 258 | if (level >= 0 && level <= 3) { 259 | q_level = level; 260 | } 261 | 262 | if (hint >= QR_MODE_NUL && hint <= QR_MODE_FNC1SECOND) { 263 | q_hint = hint; 264 | } 265 | 266 | // php_printf("version:%d\n", version); 267 | // php_printf("casesensitive:%d\n", casesensitive); 268 | // php_printf("Level:%d\n", q_level); 269 | // php_printf("hint:%d\n", q_hint); 270 | 271 | QRcode *code = QRcode_encodeString(str, version, q_level, q_hint, casesensitive); 272 | if (code == NULL) { 273 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "QRcode_encodeString error!!!"); 274 | RETURN_NULL(); 275 | } 276 | 277 | qe = emalloc(sizeof(qrencode)); 278 | qe->code = code; 279 | 280 | ZEND_REGISTER_RESOURCE(return_value, qe, le_qrencode); 281 | } 282 | 283 | 284 | /*保存*/ 285 | PHP_FUNCTION(qrencode_save) 286 | { 287 | zval *zqe; 288 | qrencode *qe; 289 | char *path; 290 | int path_len; 291 | 292 | int int_bg_color[3] = {255,255,255} ; 293 | 294 | int size = 100; 295 | int margin = 2; 296 | 297 | int red = 0; 298 | int green = 0; 299 | int blue = 0; 300 | 301 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|llll", &zqe, &path, &path_len, &size, &red, &green, &blue) == FAILURE) { 302 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "parse parameter error!!!"); 303 | RETURN_FALSE; 304 | } 305 | 306 | if (red<0 || red>255) { 307 | red = 0; 308 | } 309 | if (green<0 || green>255) { 310 | green = 0; 311 | } 312 | if (blue<0 || blue>255) { 313 | blue = 0; 314 | } 315 | 316 | int int_fg_color [3] = {red,green,blue}; 317 | 318 | 319 | ZEND_FETCH_RESOURCE(qe, qrencode*, &zqe, -1, QRENCODE_RESOURCE_TYPE, le_qrencode); 320 | 321 | FILE * out = fopen(path,"w+"); 322 | if (out == NULL){ 323 | php_error_docref (NULL TSRMLS_CC, E_WARNING, "can not open the file"); 324 | RETURN_FALSE; 325 | } 326 | 327 | gdImagePtr im = qrcode_png(qe->code,int_fg_color,int_bg_color,size,margin) ; 328 | gdImagePng(im,out); 329 | QRcode_free(qe->code); 330 | qe->code = NULL; 331 | gdImageDestroy(im); 332 | fclose(out); 333 | RETURN_TRUE; 334 | } 335 | 336 | static void _qrencode_output_putc(struct gdIOCtx *ctx, int c) 337 | { 338 | /* without the following downcast, the write will fail 339 | * (i.e., will write a zero byte) for all 340 | * big endian architectures: 341 | */ 342 | unsigned char ch = (unsigned char) c; 343 | TSRMLS_FETCH(); 344 | php_write(&ch, 1 TSRMLS_CC); 345 | } 346 | 347 | static int _qrencode_output_putbuf(struct gdIOCtx *ctx, const void* buf, int l) 348 | { 349 | TSRMLS_FETCH(); 350 | return php_write((void *)buf, l TSRMLS_CC); 351 | } 352 | 353 | static void _qrencode_output_ctxfree(struct gdIOCtx *ctx) 354 | { 355 | if(ctx) { 356 | efree(ctx); 357 | } 358 | } 359 | 360 | /*输出*/ 361 | PHP_FUNCTION(qrencode_output) 362 | { 363 | zval *zqe; 364 | gdIOCtx *ctx = NULL; 365 | qrencode *qe; 366 | int int_bg_color[3] = {255,255,255} ; 367 | int size = 100; 368 | int margin = 2; 369 | int red = 0; 370 | int green = 0; 371 | int blue = 0; 372 | int q = -1; 373 | int f = -1; 374 | 375 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|llll", &zqe, &size, &red, &green, &blue) == FAILURE) { 376 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "parse parameter error!!!"); 377 | RETURN_FALSE; 378 | } 379 | 380 | if (red<0 || red>255) { 381 | red = 0; 382 | } 383 | if (green<0 || green>255) { 384 | green = 0; 385 | } 386 | if (blue<0 || blue>255) { 387 | blue = 0; 388 | } 389 | 390 | int int_fg_color [3] = {red,green,blue}; 391 | ZEND_FETCH_RESOURCE(qe, qrencode*, &zqe, -1, QRENCODE_RESOURCE_TYPE, le_qrencode); 392 | 393 | gdImagePtr im = qrcode_png(qe->code,int_fg_color,int_bg_color,size,margin) ; 394 | 395 | //输出Content-type 396 | char *content_type = "Content-type: image/png"; 397 | sapi_header_line ctr = {0}; 398 | ctr.line = content_type; 399 | ctr.line_len = strlen(content_type); 400 | ctr.response_code = 200; 401 | sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); 402 | 403 | //输出 404 | ctx = emalloc(sizeof(gdIOCtx)); 405 | ctx->putC = _qrencode_output_putc; 406 | ctx->putBuf = _qrencode_output_putbuf; 407 | ctx->gd_free = _qrencode_output_ctxfree; 408 | 409 | gdImagePngCtxEx(im, ctx, -1); 410 | ctx->gd_free(ctx); 411 | 412 | 413 | QRcode_free(qe->code); 414 | qe->code = NULL; 415 | gdImageDestroy(im); 416 | 417 | RETURN_TRUE; 418 | } 419 | 420 | gdImagePtr qrcode_png(QRcode *code, int fg_color[3], int bg_color[3], int size, int margin) 421 | { 422 | int code_size = size / code->width; 423 | code_size = (code_size == 0) ? 1 : code_size; 424 | int img_width = code->width * code_size + 2 * margin; 425 | gdImagePtr img = gdImageCreate (img_width,img_width); 426 | int img_fgcolor = gdImageColorAllocate(img,fg_color[0],fg_color[1],fg_color[2]); 427 | int img_bgcolor = gdImageColorAllocate(img,bg_color[0],bg_color[1],bg_color[2]); 428 | gdImageFill(img,0,0,img_bgcolor); 429 | unsigned char *p = code->data; 430 | int x,y ,posx,posy; 431 | for (y = 0 ; y < code->width ; y++) 432 | { 433 | for (x = 0 ; x < code->width ; x++) 434 | { 435 | if (*p & 1) 436 | { 437 | posx = x * code_size + margin; 438 | posy = y * code_size + margin; 439 | gdImageFilledRectangle(img,posx,posy,posx + code_size,posy + code_size,img_fgcolor); 440 | } 441 | p++; 442 | } 443 | } 444 | return img; 445 | } 446 | 447 | 448 | /* 449 | * Local variables: 450 | * tab-width: 4 451 | * c-basic-offset: 4 452 | * End: 453 | * vim600: noet sw=4 ts=4 fdm=marker 454 | * vim<600: noet sw=4 ts=4 455 | */ 456 | -------------------------------------------------------------------------------- /qrencode.php: -------------------------------------------------------------------------------- 1 | "; 3 | 4 | if(!extension_loaded('qrencode')) { 5 | dl('qrencode.' . PHP_SHLIB_SUFFIX); 6 | } 7 | $t1 = microtime(true); 8 | // echo qrcode_version()."\n"; 9 | // echo gd_version()."\n"; 10 | 11 | $resource = qrencode_create("http://www.163.com", QRENCODE_QRECLEVEL_Q, QRENCODE_MODE_8); 12 | //echo "resource: " . $resource ."\n"; 13 | if (!is_null($resource)) { 14 | echo qrencode_save($resource, "/Users/kentchen/Downloads/t7.png", 255) . "\n"; 15 | } 16 | 17 | //echo qrencode_version()."\n"; 18 | $t2 = microtime(true); 19 | 20 | echo (($t2-$t1)*1000).":ms\n"; 21 | ?> 22 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Check for qrencode presence 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 20 | --EXPECT-- 21 | qrencode extension is available 22 | --------------------------------------------------------------------------------