diff -Nru php-memcached-3.1.3+2.2.0/debian/changelog php-memcached-3.1.4+2.2.0/debian/changelog --- php-memcached-3.1.3+2.2.0/debian/changelog 2019-08-07 23:36:34.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/debian/changelog 2019-11-29 07:03:03.000000000 +0000 @@ -1,8 +1,14 @@ -php-memcached (3.1.3+2.2.0-1build1) eoan; urgency=medium +php-memcached (3.1.4+2.2.0-1) unstable; urgency=medium - * No-change rebuild for php7.3 + * New upstream version 3.1.4+2.2.0 - -- Bryce Harrington Wed, 07 Aug 2019 23:36:34 +0000 + -- Ondřej Surý Fri, 29 Nov 2019 08:03:03 +0100 + +php-memcached (3.1.3+2.2.0-2) unstable; urgency=medium + + * No-change version bump for buster. + + -- Ondřej Surý Wed, 14 Aug 2019 07:20:34 +0200 php-memcached (3.1.3+2.2.0-1) unstable; urgency=medium diff -Nru php-memcached-3.1.3+2.2.0/debian/control php-memcached-3.1.4+2.2.0/debian/control --- php-memcached-3.1.3+2.2.0/debian/control 2019-08-07 23:36:34.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/debian/control 2019-11-29 07:03:03.000000000 +0000 @@ -1,8 +1,7 @@ Source: php-memcached Section: php Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian PHP PECL Maintainers +Maintainer: Debian PHP PECL Maintainers Uploaders: Ondřej Surý Build-Depends: debhelper (>= 9), dh-php (>= 0.33~), diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/ChangeLog php-memcached-3.1.4+2.2.0/memcached-3.1.3/ChangeLog --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/ChangeLog 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/ChangeLog 1970-01-01 00:00:00.000000000 +0000 @@ -1,281 +0,0 @@ -memcached extension changelog - -Version 3.1.3 (2018-12-24) --------------------------- - - * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) - -Version 3.1.2 (2018-12-22) --------------------------- - - * Fix --enable-memcached-protocol was set to yes by default, reverted to no (#418) - -Version 3.1.1 (2018-12-21) --------------------------- - - * Fix --disable-memcached-sasl and --disable-memcached-session replaced by --enable variants (#416) - -Version 3.1.0 (2018-12-21) --------------------------- - - New - * Support for PHP 7.3 (#385, #390) - * Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#344, #392) - * Add support for libmemcached encryption (#345, #381) - * Add error reporting to session code (#165) - * Expose build configuration via PECL (#383) - - Fixes - * Fix hanging getStats() when binary protocol and non-blocking are both enabled (#348) - * Fix session persistence by checking memcached behavior values before setting (#379) - * Fix memcached.sess_persistent not working with memcached.sess_binary_protocol = On (#375) - * Configure warns if libmemcached needs sasl.h (#341, #380) - * Resolve various INI deviations in 3.0.3 (#351) - * Turn off sess_binary_protocol by default with older libmemcached (#330) - - Changes - * Impove Windows builds (#411) - * Support Homebrew ZLIB path (#410) - * Remove forgotten unused comment about -lpthread (#406) - * Git ignore configure.ac (#405) - * Replace obsolete macros AC_TRY_FOO with AC_FOO_IFELSE (#403) - * Remove unused defines (#354) - * Change session_lock and sess_prefix default ini values (#340, #350) - * Use new fast_zpp parameter parsing API (#302, #311) - -Version 3.0.4 (2017-11-20) --------------------------- - - * Fix corrupted interned strings (#338) - * Fix unit tests for compatibility with PHP 7.2 (#358, #359) - * Fix \x0a in key name locks up connection and triggers a fatal timeout error (#339) - * Fix missing optional parameter getStats($type) (#337) - * Fix typo in skip message (#331) - * Fix build warnings (#329) - * Document GET_EXTENDED flag, add/rename other missing/misnamed constants (#335) - -Version 3.0.3 (2017-02-19) --------------------------- - - * Fix crash when checking session data with older versions of libmemcached (#328) - * Fix crash due to zend_mm_corrupted when fetching session data (#327) - -Version 3.0.2 (2017-02-12) --------------------------- - - * Update warning for touch command in binary protocol mode with libmemcached < 1.0.18 (#322) - * Add tests for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) - * Fix tests for 32-bit increment/decrement/incrementByKey/decrementByKey (#319) - -Version 3.0.1 (2017-02-07) --------------------------- - - * Add API entries for flushBuffers() and getAllKeys() (#316) - * Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) - * Fix compiling with memcached binary protocol enabled (#312) - * Restore php_libmemcached_compat with workaround for missing memcached_exists (#314) - * Travis CI purge old versions of memcached and libmemcached (#309) - -Version 3.0.0 (2017-01-27) --------------------------- - * Support for PHP 7.0 and PHP 7.1 - * Fix compiling with SASL disabled - * Improved the test suite and Travis CI test runners - * Fix small string compression / decompression - * Fix increment/decrement with adjustments greater than 32-bit integers - * Fix session.gc_maxlifetime to handle both relative and absolute times - * Fix inability to reset OPT_PREFIX_KEY - -Version 3.0.0a1 (2016-02-22) ----------------------------- - Dependencies - * Support for PHP 7.0 - * Requires libmemcached 1.0 or higher - * Optional extension igbinary must 2.0 or higher - * Optional extension msgpack must be 2.0 or higher - - API - * The method signature of get, getByKey, getMulti, and getMultiByKey changed. - * get* and getMulti* commands no longer take cas or user flags parameters. - * get* and getMulti* commands now take the Memcached::GET_EXTENDED flag to retrieve user flags and cas tokens. - * Fixes getStats command to return all stats from all servers - * Fixes allKeys command behaviour - * Fixes error where cache callback for get command was not setting expiration time properly - * Added server type to server list - * Remove use_sasl ini-variable and initialise sasl as needed - * CAS tokens are returned as integers and they overflow to strings as needed - - Session handler - * The session memcached protocol config name was changed, and the default protocol was changed from text to binary protocol. If your memcached setup does not support the binary protocol(e.g. if using twemproxy), then set memcached.sess_binary_protocol = Off. (Previously called memcached.sess_binary) - * Session lock algorithm updated (new ini-values memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries) - * Session extension uses PHP allocators (still some work to do on the rest of the extension) - * Ini-values take effect during session_start or session_regenerate_id - * Fixes crash with session_regenerate_id (work-around for PHP bug) - - Tests - * Fix several problematic tests - -Version 2.2.0 (2014-04-01) --------------------------- - * Added the OPT_SERVER_TIMEOUT_LIMIT behaviour - -Version 2.2.0RC1 (2014-03-12) ------------------------------ - * Added the OPT_SERVER_TIMEOUT_LIMIT behaviour - * Fixes incorrect size when compressing serialized objects - * Fixes endianess of compressed values - -Version 2.2.0b1 (2013-10-28) ----------------------------- - * Reinstate support for libememcached 0.x series - * Added SASL support to session handler - * Added Memcached::flushBuffers as per GH #78 - * Fixes GH #54: Fixed UDP server adding with newer libmemcached - * Fixed PHP bug #65334: (Segfault if uncompress value failed) - * Fixes GH #14: get with cas token fails to fetch all results - * Fixes GH #68: memcached 2.1.0 requires libmemcached 1.0.10 - * Fixes GH #69: compiling on CentOS 6.4 with libmemcached 1.0.17 - * Merged PR #91: memcached.sess_lock_wait and memcached.sess_lock_max_wait - * Added session handler settings: - - memcached.sess_number_of_replicas - - memcached.sess_randomize_replica_read - - memcached.sess_remove_failed - - memcached.sess_connect_timeout - * Added support for memcached protocol handlers - * Added Memcached::setBucket for virtual bucket support - * Added support for msgpack serialization - * Memcached::setSaslAuthData returns correct status on success - * Added support for user-defined flags in set and get operations - -Version 2.1.0 (2012-08-06) --------------------------- - * Drop support for libmemcached 0.x series, now 1.0.x is required - * Add support for virtual bucket distribution - * Fix compilation against PHP 5.2 - -Version 2.0.1 (2012-03-03) --------------------------- - * Fix embedded version number to be not -dev - -Version 2.0.0 (2012-03-02) --------------------------- - * Add touch() and touchByKey() methods - * Add resetServerList() and quit() methods - * Support binary protocol in sessions - * Make it work with libmemcached up to 1.0.4 - * Test against PHP 5.4.0 - -Version 2.0.0b2 (2011-06-24) ----------------------------- - * Add OPT_REMOVE_FAILED_SERVERS option. - * Make it work with libmemcached up to 0.49. - * Fix a case where invalid session ID could lock the script. - * Improve session support: - - Add support for libmemcached config string - - Add persistence support via PERSISTENT=persistent_id prefix - of the save_path - * Add 3rd parameter to the __construct() that allows specification - of libmemcached configuration string - * Fix a possible crash in __construct() when using persistent - connections - * Add work-around a bug in libmemcached < 0.50 that causes truncation - of last character of server key prefix - * When using multiple servers implement transparent fail-over - * Fix php_memc_cas_impl() implementation when server_key is not being used - * Add support for incrementByKey() and decrementByKey() - * Make increment/decrement initialize value when it is not available (when - using binary protocol) - -Version 2.0.0b1 (2011-03-12) ----------------------------- - * Add fastlz library that provides better/faster payload compression - * Add configure switch to enable/disable JSON serialization support - * Add getAllKeys() method - * Add deleteMulti() and deleteMultiByKey() methods - * Add isPristine() and isPersistent() methods - * Add setOptions() method to set multiple options at once - * Add SERIALIZER_JSON_ARRAY type that decodes JSON payloads as arrays - instead of objects - * Add support for Unix domain socket connections - * Add memcached.compression_threshold INI setting - * Add memcached.compression_factor INI setting - * Add memcached.compression_type INI setting - * Implement a few speed optimizations - * Many bug fixes and memory leaks plugged - * Add several more tests - * Add constants for libmemcached 0.37+: - - Memcached::OPT_NUMBER_OF_REPLICAS - - Memcached::OPT_RANDOMIZE_REPLICA_READ - * Add 'on_new' callback to constructor - * Add SASL support - -Version 1.0.2 (2010-05-03) --------------------------- - * Fix build for libmemcached-0.39 (memcached_server_list() issue) - -Version 1.0.1 (2010-03-11) --------------------------- - * Fix JSON API handling to account for PHP 5.2/5.3 version differences. - * Add memcached.sess_locking, memcached.sess_lock_wait, and - memcached.sess_prefix INI entries. - * Add OPT_AUTO_EJECT_HOSTS option. - -Version 1.0.0 (2009-07-04) --------------------------- - * First stable release. - * Add getResultMessage() method. - * Fix OPT_RECV_TIMEOUT definition. - * Initialize Session lock wait to max execution time (if max execution - time is unlimited, default to 30 seconds). - -Version 0.2.0 (2009-06-04) --------------------------- - * Add JSON serializer support, requires PHP 5.2.10+. - * Add HAVE_JSON and HAVE_IGBINARY class constants that indicate - whether the respective serializers are available. - * Add 'flags' parameter to getMulti() and getMultiByKey(). - * Add GET_PRESERVE_ORDER class constant that can be used with - abovementioned flags parameter to make the order of the keys in the - response match the request. - * Fix an issue with retrieving 0-length payloads (FALSE boolean value). - * Refactor the way payload types are stored in memcached flags to optimize - the structure and allow for future expansion. WARNING! You have to flush - the cache when upgrading to this version. - * Add several tests. - -Version 0.1.5 (2009-03-31) --------------------------- - * Implement getVersion(). - * Add support for preserving boolean value types. - * Fix crash when child class does not call constructor. - * Fix bug #16084 (Crash when addServers is called with an associative array). - * ZTS compilation fixes. - -Version 0.1.4 (2009-02-13) --------------------------- - * Fix compilation against PHP 5.3. - * Add support for 'igbinary' serializer (Oleg Grenrus) - -Version 0.1.3 (2009-02-06) --------------------------- - * Bludgeon bug #15896 (Memcached setMulti error) into submission. - -Version 0.1.2 (2009-02-06) --------------------------- - * Fix bug #15896 (Memcached setMulti error). - * Check for empty key in getServerByKey(). - * Allow passing 'null' for callbacks. - * get() with cas token fetching wasn't erroring out properly. - * Rename certain parameters in the API to be more clear. - * Allow only strings as the append/prepend value. - * Remove expiration parameter from append/prepend. - -Version 0.1.1 (2009-02-02) --------------------------- - * Add OPT_LIBKETAMA_COMPATIBLE option. - * Implement addServers() method. - * Swap internal compressed and serialized flags to be compatible with other clients. - -Version 0.1.0 (2009-01-29) --------------------------- - * Initial release diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/config.m4 php-memcached-3.1.4+2.2.0/memcached-3.1.3/config.m4 --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/config.m4 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/config.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,409 +0,0 @@ -dnl vim:se ts=2 sw=2 et: - -PHP_ARG_ENABLE(memcached, whether to enable memcached support, -[ --enable-memcached Enable memcached support]) - -PHP_ARG_WITH(libmemcached-dir, for libmemcached, -[ --with-libmemcached-dir=DIR Set the path to libmemcached install prefix.], yes) - -PHP_ARG_ENABLE(memcached-session, whether to enable memcached session handler support, -[ --enable-memcached-session Enable memcached session handler support], yes, no) - -PHP_ARG_ENABLE(memcached-igbinary, whether to enable memcached igbinary serializer support, -[ --enable-memcached-igbinary Enable memcached igbinary serializer support], no, no) - -PHP_ARG_ENABLE(memcached-json, whether to enable memcached json serializer support, -[ --enable-memcached-json Enable memcached json serializer support], no, no) - -PHP_ARG_ENABLE(memcached-msgpack, whether to enable memcached msgpack serializer support, -[ --enable-memcached-msgpack Enable memcached msgpack serializer support], no, no) - -PHP_ARG_ENABLE(memcached-sasl, whether to enable memcached sasl support, -[ --enable-memcached-sasl Enable memcached sasl support], yes, no) - -PHP_ARG_ENABLE(memcached-protocol, whether to enable memcached protocol support, -[ --enable-memcached-protocol Enable memcached protocol support], no, no) - -PHP_ARG_WITH(system-fastlz, whether to use system FastLZ library, -[ --with-system-fastlz Use system FastLZ library], no, no) - -if test -z "$PHP_ZLIB_DIR"; then -PHP_ARG_WITH(zlib-dir, for ZLIB, -[ --with-zlib-dir=DIR Set the path to ZLIB install prefix.], no) -fi - -if test -z "$PHP_DEBUG"; then - AC_ARG_ENABLE(debug, - [ --enable-debug Compile with debugging symbols],[ - PHP_DEBUG=$enableval - ],[ PHP_DEBUG=no - ]) -fi - -if test "$PHP_MEMCACHED" != "no"; then - - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - if test "x$PKG_CONFIG" = "xno"; then - AC_MSG_RESULT([pkg-config not found]) - AC_MSG_ERROR([Please reinstall the pkg-config distribution]) - fi - - dnl # zlib - if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then - if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then - PHP_ZLIB_DIR="$PHP_ZLIB_DIR" - PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include/zlib" - elif test -f "$PHP_ZLIB_DIR/include/zlib.h"; then - PHP_ZLIB_DIR="$PHP_ZLIB_DIR" - PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include" - else - AC_MSG_ERROR([Can't find ZLIB headers under "$PHP_ZLIB_DIR"]) - fi - else - for i in /usr/local /usr/local/opt/zlib /usr; do - if test -f "$i/include/zlib/zlib.h"; then - PHP_ZLIB_DIR="$i" - PHP_ZLIB_INCDIR="$i/include/zlib" - elif test -f "$i/include/zlib.h"; then - PHP_ZLIB_DIR="$i" - PHP_ZLIB_INCDIR="$i/include" - fi - done - fi - - AC_MSG_CHECKING([for zlib location]) - if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then - AC_MSG_RESULT([$PHP_ZLIB_DIR]) - PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR/$PHP_LIBDIR, MEMCACHED_SHARED_LIBADD) - PHP_ADD_INCLUDE($PHP_ZLIB_INCDIR) - else - AC_MSG_ERROR([memcached support requires ZLIB. Use --with-zlib-dir= to specify the prefix where ZLIB headers and library are located]) - fi - - if test "$PHP_MEMCACHED_SESSION" != "no"; then - AC_MSG_CHECKING([for session includes]) - session_inc_path="" - - if test -f "$abs_srcdir/include/php/ext/session/php_session.h"; then - session_inc_path="$abs_srcdir/include/php" - elif test -f "$abs_srcdir/ext/session/php_session.h"; then - session_inc_path="$abs_srcdir" - elif test -f "$phpincludedir/ext/session/php_session.h"; then - session_inc_path="$phpincludedir" - else - for i in php php4 php5 php6; do - if test -f "$prefix/include/$i/ext/session/php_session.h"; then - session_inc_path="$prefix/include/$i" - fi - done - fi - - if test "$session_inc_path" = ""; then - AC_MSG_ERROR([Cannot find php_session.h]) - else - AC_MSG_RESULT([$session_inc_path]) - fi - fi - - if test "$PHP_MEMCACHED_JSON" != "no"; then - AC_MSG_CHECKING([for json includes]) - json_inc_path="" - - if test -f "$abs_srcdir/include/php/ext/json/php_json.h"; then - json_inc_path="$abs_srcdir/include/php" - elif test -f "$abs_srcdir/ext/json/php_json.h"; then - json_inc_path="$abs_srcdir" - elif test -f "$phpincludedir/ext/json/php_json.h"; then - json_inc_path="$phpincludedir" - else - for i in php php4 php5 php6; do - if test -f "$prefix/include/$i/ext/json/php_json.h"; then - json_inc_path="$prefix/include/$i" - fi - done - fi - if test "$json_inc_path" = ""; then - AC_MSG_ERROR([Cannot find php_json.h]) - else - AC_DEFINE(HAVE_JSON_API,1,[Whether JSON API is available]) - AC_MSG_RESULT([$json_inc_path]) - fi - fi - - if test "$PHP_MEMCACHED_IGBINARY" != "no"; then - AC_MSG_CHECKING([for igbinary includes]) - igbinary_inc_path="" - - if test -f "$abs_srcdir/include/php/ext/igbinary/igbinary.h"; then - igbinary_inc_path="$abs_srcdir/include/php" - elif test -f "$abs_srcdir/ext/igbinary/igbinary.h"; then - igbinary_inc_path="$abs_srcdir" - elif test -f "$phpincludedir/ext/session/igbinary.h"; then - igbinary_inc_path="$phpincludedir" - elif test -f "$phpincludedir/ext/igbinary/igbinary.h"; then - igbinary_inc_path="$phpincludedir" - else - for i in php php4 php5 php6; do - if test -f "$prefix/include/$i/ext/igbinary/igbinary.h"; then - igbinary_inc_path="$prefix/include/$i" - fi - done - fi - - if test "$igbinary_inc_path" = ""; then - AC_MSG_ERROR([Cannot find igbinary.h]) - else - AC_MSG_RESULT([$igbinary_inc_path]) - fi - fi - - if test "$PHP_MEMCACHED_MSGPACK" != "no"; then - AC_MSG_CHECKING([for msgpack includes]) - msgpack_inc_path="" - - if test -f "$abs_srcdir/include/php/ext/msgpack/php_msgpack.h"; then - msgpack_inc_path="$abs_srcdir/include/php" - elif test -f "$abs_srcdir/ext/msgpack/php_msgpack.h"; then - msgpack_inc_path="$abs_srcdir" - elif test -f "$phpincludedir/ext/session/php_msgpack.h"; then - msgpack_inc_path="$phpincludedir" - elif test -f "$phpincludedir/ext/msgpack/php_msgpack.h"; then - msgpack_inc_path="$phpincludedir" - else - for i in php php4 php5 php6; do - if test -f "$prefix/include/$i/ext/msgpack/php_msgpack.h"; then - msgpack_inc_path="$prefix/include/$i" - fi - done - fi - - if test "$msgpack_inc_path" = ""; then - AC_MSG_ERROR([Cannot find php_msgpack.h]) - else - AC_MSG_RESULT([$msgpack_inc_path]) - fi - fi - - AC_MSG_CHECKING([for memcached session support]) - if test "$PHP_MEMCACHED_SESSION" != "no"; then - AC_MSG_RESULT([enabled]) - AC_DEFINE(HAVE_MEMCACHED_SESSION,1,[Whether memcache session handler is enabled]) - SESSION_INCLUDES="-I$session_inc_path" - ifdef([PHP_ADD_EXTENSION_DEP], - [ - PHP_ADD_EXTENSION_DEP(memcached, session) - ]) - else - SESSION_INCLUDES="" - AC_MSG_RESULT([disabled]) - fi - - AC_MSG_CHECKING([for memcached igbinary support]) - if test "$PHP_MEMCACHED_IGBINARY" != "no"; then - AC_MSG_RESULT([enabled]) - AC_DEFINE(HAVE_MEMCACHED_IGBINARY,1,[Whether memcache igbinary serializer is enabled]) - IGBINARY_INCLUDES="-I$igbinary_inc_path" - ifdef([PHP_ADD_EXTENSION_DEP], - [ - PHP_ADD_EXTENSION_DEP(memcached, igbinary) - ]) - else - IGBINARY_INCLUDES="" - AC_MSG_RESULT([disabled]) - fi - - AC_MSG_CHECKING([for memcached msgpack support]) - if test "$PHP_MEMCACHED_MSGPACK" != "no"; then - AC_MSG_RESULT([enabled]) - AC_DEFINE(HAVE_MEMCACHED_MSGPACK,1,[Whether memcache msgpack serializer is enabled]) - MSGPACK_INCLUDES="-I$msgpack_inc_path" - ifdef([PHP_ADD_EXTENSION_DEP], - [ - PHP_ADD_EXTENSION_DEP(memcached, msgpack) - ]) - else - MSGPACK_INCLUDES="" - AC_MSG_RESULT([disabled]) - fi - - AC_MSG_CHECKING([for libmemcached location]) - export ORIG_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" - - if test "$PHP_LIBMEMCACHED_DIR" != "no" && test "$PHP_LIBMEMCACHED_DIR" != "yes"; then - export PKG_CONFIG_PATH="$PHP_LIBMEMCACHED_DIR/$PHP_LIBDIR/pkgconfig" - - if test ! -f "$PHP_LIBMEMCACHED_DIR/include/libmemcached/memcached.h"; then - AC_MSG_ERROR(Unable to find memcached.h under $PHP_LIBMEMCACHED_DIR) - fi - else - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/$PHP_LIBDIR/pkgconfig:/usr/$PHP_LIBDIR/pkgconfig:/opt/$PHP_LIBDIR/pkgconfig" - fi - - if ! $PKG_CONFIG --exists libmemcached; then - AC_MSG_ERROR([memcached support requires libmemcached. Use --with-libmemcached-dir= to specify the prefix where libmemcached headers and library are located]) - else - PHP_LIBMEMCACHED_VERSION=`$PKG_CONFIG libmemcached --modversion` - PHP_LIBMEMCACHED_DIR=`$PKG_CONFIG libmemcached --variable=prefix` - - AC_MSG_RESULT([found version $PHP_LIBMEMCACHED_VERSION, under $PHP_LIBMEMCACHED_DIR]) - - PHP_LIBMEMCACHED_LIBS=`$PKG_CONFIG libmemcached --libs` - PHP_LIBMEMCACHED_INCLUDES=`$PKG_CONFIG libmemcached --cflags` - - PHP_EVAL_LIBLINE($PHP_LIBMEMCACHED_LIBS, MEMCACHED_SHARED_LIBADD) - PHP_EVAL_INCLINE($PHP_LIBMEMCACHED_INCLUDES) - - ORIG_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $INCLUDES" - - dnl # Always check if libmemcached was built with SASL support, - dnl # because it will require sasl.h even if not used here. - AC_CACHE_CHECK([for libmemcached sasl.h requirement], ac_cv_memc_sasl_support, [ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ - #if LIBMEMCACHED_WITH_SASL_SUPPORT - /* yes */ - #else - # error "no sasl support" - #endif - ]])], - [ac_cv_memc_sasl_support="yes"], - [ac_cv_memc_sasl_support="no"] - ) - ]) - - if test "$ac_cv_memc_sasl_support" = "yes"; then - AC_CHECK_HEADERS([sasl/sasl.h], [ac_cv_have_memc_sasl_h="yes"], [ac_cv_have_memc_sasl_h="no"]) - fi - - dnl # If libmemcached requires sasl.h but we can't find sasl.h, that's a hard error - dnl # regardless of the option --enable-memcached-sasl or --disable-memcached-sasl - AC_MSG_CHECKING([whether to enable sasl support]) - if test "$ac_cv_memc_sasl_support" = "yes" && test "$ac_cv_have_memc_sasl_h" = "no"; then - AC_MSG_ERROR([no, libmemcached built with sasl required, but sasl.h not found.]) - fi - - if test "$PHP_MEMCACHED_SASL" != "no"; then - AC_MSG_RESULT(yes) - if test "$ac_cv_memc_sasl_support" = "yes" && test "$ac_cv_have_memc_sasl_h" = "yes"; then - PHP_CHECK_LIBRARY(sasl2, sasl_client_init, [PHP_ADD_LIBRARY(sasl2, 1, MEMCACHED_SHARED_LIBADD)]) - AC_DEFINE(HAVE_MEMCACHED_SASL, 1, [Have SASL support]) - else - AC_MSG_ERROR([no, libmemcached built with sasl disabled. Run configure with --disable-memcached-sasl or update libmemcached with sasl support]) - fi - else - AC_MSG_RESULT([no]) - fi - - ORIG_CFLAGS="$CFLAGS" - ORIG_LIBS="$LIBS" - - CFLAGS="$CFLAGS $PHP_LIBMEMCACHED_INCLUDES" - LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" - - AC_CACHE_CHECK([whether memcached_exist is defined], ac_cv_have_memcached_exist, [ - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[memcached_exist (NULL, NULL, 0);]])], - [ac_cv_have_memcached_exist="yes"], - [ac_cv_have_memcached_exist="no"]) - ]) - - CFLAGS="$ORIG_CFLAGS" - LIBS="$ORIG_LIBS" - - CFLAGS="$CFLAGS $PHP_LIBMEMCACHED_INCLUDES" - LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" - - if test "$ac_cv_have_memcached_exist" = "yes"; then - AC_DEFINE(HAVE_MEMCACHED_EXIST, [1], [Whether memcached_exist is defined]) - fi - - AC_CACHE_CHECK([whether memcached_set_encoding_key is defined], ac_cv_have_memcached_set_encoding_key, [ - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[memcached_set_encoding_key (NULL, NULL, 0);]])], - [ac_cv_have_memcached_set_encoding_key="yes"], - [ac_cv_have_memcached_set_encoding_key="no"]) - ]) - - CFLAGS="$ORIG_CFLAGS" - LIBS="$ORIG_LIBS" - - if test "$ac_cv_have_memcached_set_encoding_key" = "yes"; then - AC_DEFINE(HAVE_MEMCACHED_SET_ENCODING_KEY, [1], [Whether memcached_set_encoding_key is defined]) - fi - - PHP_MEMCACHED_FILES="php_memcached.c php_libmemcached_compat.c g_fmt.c" - - if test "$PHP_SYSTEM_FASTLZ" != "no"; then - AC_CHECK_HEADERS([fastlz.h], [ac_cv_have_fastlz="yes"], [ac_cv_have_fastlz="no"]) - PHP_CHECK_LIBRARY(fastlz, fastlz_compress, - [PHP_ADD_LIBRARY(fastlz, 1, MEMCACHED_SHARED_LIBADD)], - [AC_MSG_ERROR(FastLZ library not found)]) - else - ac_cv_have_fastlz="no" - PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} fastlz/fastlz.c" - fi - - if test "$PHP_MEMCACHED_SESSION" != "no"; then - PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_session.c" - fi - - LIBEVENT_INCLUDES="" - AC_MSG_CHECKING([for memcached protocol support]) - if test "$PHP_MEMCACHED_PROTOCOL" != "no"; then - AC_MSG_RESULT([enabled]) - - AC_CACHE_CHECK([whether libmemcachedprotocol is usable], ac_cv_have_libmemcachedprotocol, [ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[memcached_binary_protocol_callback_st s_test_impl; - s_test_impl.interface.v1.delete_object = 0; - ]])], - [ac_cv_have_libmemcachedprotocol="yes"], - [ac_cv_have_libmemcachedprotocol="no"] - ) - ]) - - if test "$ac_cv_have_libmemcachedprotocol" != "yes"; then - AC_MSG_ERROR([Cannot enable libmemcached protocol]) - fi - - PHP_ADD_LIBRARY_WITH_PATH(memcachedprotocol, $PHP_LIBMEMCACHED_DIR/$PHP_LIBDIR, MEMCACHED_SHARED_LIBADD) - - AC_MSG_CHECKING([for libevent]) - if $PKG_CONFIG --exists libevent; then - PHP_MEMCACHED_LIBEVENT_VERSION=`$PKG_CONFIG libevent --modversion` - PHP_MEMCACHED_LIBEVENT_PREFIX=`$PKG_CONFIG libevent --variable=prefix` - - AC_MSG_RESULT([found version $PHP_MEMCACHED_LIBEVENT_VERSION, under $PHP_MEMCACHED_LIBEVENT_PREFIX]) - LIBEVENT_LIBS=`$PKG_CONFIG libevent --libs` - LIBEVENT_INCLUDES=`$PKG_CONFIG libevent --cflags` - - PHP_EVAL_LIBLINE($LIBEVENT_LIBS, MEMCACHED_SHARED_LIBADD) - PHP_EVAL_INCLINE($LIBEVENT_INCLUDES) - else - AC_MSG_ERROR(Unable to find libevent installation) - fi - PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_server.c" - AC_DEFINE(HAVE_MEMCACHED_PROTOCOL,1,[Whether memcached protocol is enabled]) - else - AC_MSG_RESULT([disabled]) - fi - - CFLAGS="$ORIG_CFLAGS" - - export PKG_CONFIG_PATH="$ORIG_PKG_CONFIG_PATH" - PHP_SUBST(MEMCACHED_SHARED_LIBADD) - - PHP_NEW_EXTENSION(memcached, $PHP_MEMCACHED_FILES, $ext_shared,,$SESSION_INCLUDES $IGBINARY_INCLUDES $LIBEVENT_INCLUDES $MSGPACK_INCLUDES) - if test "ac_cv_have_fastlz" != "yes"; then - PHP_ADD_BUILD_DIR($ext_builddir/fastlz, 1) - fi - - ifdef([PHP_ADD_EXTENSION_DEP], - [ - PHP_ADD_EXTENSION_DEP(memcached, spl, true) - ]) - fi -fi - diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/config.w32 php-memcached-3.1.4+2.2.0/memcached-3.1.3/config.w32 --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/config.w32 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/config.w32 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -// vim:ft=javascript - -ARG_ENABLE('memcached', 'libmemcached extension', 'no'); - -ARG_ENABLE('memcached-session', 'whether to enable memcached session handler support', 'no'); -ARG_ENABLE('memcached-igbinary', 'whether to enable memcached igbinary serializer support', 'no'); -ARG_ENABLE('memcached-json', 'whether to enable memcached json serializer support', 'no'); - -if (PHP_MEMCACHED == "yes") { - - if (!CHECK_LIB("memcached.lib", "memcached", PHP_MEMCACHED)) { - ERROR("memcached: library 'memcached' not found"); - } - - if (!CHECK_HEADER_ADD_INCLUDE("libmemcached/memcached.h", "CFLAGS_MEMCACHED")) { - ERROR("memcached: header 'libmemcached/memcached.h' not found"); - } - - if (PHP_MEMCACHED_JSON != "no"){ - AC_DEFINE("HAVE_JSON_API",1); - } - - var memcached_extra_src = ""; - - if (PHP_MEMCACHED_SESSION != "no"){ - AC_DEFINE("HAVE_MEMCACHED_SESSION",1); - ADD_EXTENSION_DEP("memcached", "session", true) - memcached_extra_src += " php_memcached_session.c"; - } - - if (PHP_MEMCACHED_IGBINARY != "no"){ - AC_DEFINE("HAVE_MEMCACHED_IGBINARY",1); - ADD_EXTENSION_DEP("memcached", "igbinary", true); - if (!CHECK_HEADER_ADD_INCLUDE("igbinary.h", "CFLAGS_MEMCACHED")) { - ERROR("memcached: header 'igbinary.h' not found"); - } - } - - EXTENSION("memcached", "php_memcached.c php_libmemcached_compat.c g_fmt.c"+memcached_extra_src); - ADD_SOURCES(configure_module_dirname+"\\fastlz", "fastlz.c", "memcached"); - AC_DEFINE("HAVE_MEMCACHED", 1, "memcached support"); - AC_DEFINE("MEMCACHED_EXPORTS", 1) -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/CREDITS php-memcached-3.1.4+2.2.0/memcached-3.1.3/CREDITS --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/CREDITS 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/CREDITS 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -memcached -Andrei Zmievski, Oleg Grenrus (igbinary support) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/fastlz/fastlz.c php-memcached-3.1.4+2.2.0/memcached-3.1.3/fastlz/fastlz.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/fastlz/fastlz.c 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/fastlz/fastlz.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,551 +0,0 @@ -/* - FastLZ - lightning-fast lossless compression library - - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) - -/* - * Always check for bound when decompressing. - * Generally it is best to leave it defined. - */ -#define FASTLZ_SAFE - -/* - * Give hints to the compiler for branch prediction optimization. - */ -#if defined(__GNUC__) && (__GNUC__ > 2) -#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1)) -#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0)) -#else -#define FASTLZ_EXPECT_CONDITIONAL(c) (c) -#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c) -#endif - -/* - * Use inlined functions for supported systems. - */ -#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C) -#define FASTLZ_INLINE inline -#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__) -#define FASTLZ_INLINE __inline -#else -#define FASTLZ_INLINE -#endif - -/* - * Prevent accessing more than 8-bit at once, except on x86 architectures. - */ -#if !defined(FASTLZ_STRICT_ALIGN) -#define FASTLZ_STRICT_ALIGN -#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(_M_IX86) /* Intel, MSVC */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__386) -#undef FASTLZ_STRICT_ALIGN -#elif defined(_X86_) /* MinGW */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__I86__) /* Digital Mars */ -#undef FASTLZ_STRICT_ALIGN -#endif -#endif - -/* - * FIXME: use preprocessor magic to set this on different platforms! - */ -typedef unsigned char flzuint8; -typedef unsigned short flzuint16; -typedef unsigned int flzuint32; - -/* prototypes */ -int fastlz_compress(const void* input, int length, void* output); -int fastlz_compress_level(int level, const void* input, int length, void* output); -int fastlz_decompress(const void* input, int length, void* output, int maxout); - -#define MAX_COPY 32 -#define MAX_LEN 264 /* 256 + 8 */ -#define MAX_DISTANCE 8192 - -#if !defined(FASTLZ_STRICT_ALIGN) -#define FASTLZ_READU16(p) *((const flzuint16*)(p)) -#else -#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) -#endif - -#define HASH_LOG 13 -#define HASH_SIZE (1<< HASH_LOG) -#define HASH_MASK (HASH_SIZE-1) -#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; } - -#undef FASTLZ_LEVEL -#define FASTLZ_LEVEL 1 - -#undef FASTLZ_COMPRESSOR -#undef FASTLZ_DECOMPRESSOR -#define FASTLZ_COMPRESSOR fastlz1_compress -#define FASTLZ_DECOMPRESSOR fastlz1_decompress -static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); -static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); -#include "fastlz.c" - -#undef FASTLZ_LEVEL -#define FASTLZ_LEVEL 2 - -#undef MAX_DISTANCE -#define MAX_DISTANCE 8191 -#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1) - -#undef FASTLZ_COMPRESSOR -#undef FASTLZ_DECOMPRESSOR -#define FASTLZ_COMPRESSOR fastlz2_compress -#define FASTLZ_DECOMPRESSOR fastlz2_decompress -static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); -static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); -#include "fastlz.c" - -int fastlz_compress(const void* input, int length, void* output) -{ - /* for short block, choose fastlz1 */ - if(length < 65536) - return fastlz1_compress(input, length, output); - - /* else... */ - return fastlz2_compress(input, length, output); -} - -int fastlz_decompress(const void* input, int length, void* output, int maxout) -{ - /* magic identifier for compression level */ - int level = ((*(const flzuint8*)input) >> 5) + 1; - - if(level == 1) - return fastlz1_decompress(input, length, output, maxout); - if(level == 2) - return fastlz2_decompress(input, length, output, maxout); - - /* unknown level, trigger error */ - return 0; -} - -int fastlz_compress_level(int level, const void* input, int length, void* output) -{ - if(level == 1) - return fastlz1_compress(input, length, output); - if(level == 2) - return fastlz2_compress(input, length, output); - - return 0; -} - -#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ - -static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output) -{ - const flzuint8* ip = (const flzuint8*) input; - const flzuint8* ip_bound = ip + length - 2; - const flzuint8* ip_limit = ip + length - 12; - flzuint8* op = (flzuint8*) output; - - const flzuint8* htab[HASH_SIZE]; - const flzuint8** hslot; - flzuint32 hval; - - flzuint32 copy; - - /* sanity check */ - if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4)) - { - if(length) - { - /* create literal copy only */ - *op++ = length-1; - ip_bound++; - while(ip <= ip_bound) - *op++ = *ip++; - return length+1; - } - else - return 0; - } - - /* initializes hash table */ - for (hslot = htab; hslot < htab + HASH_SIZE; hslot++) - *hslot = ip; - - /* we start with literal copy */ - copy = 2; - *op++ = MAX_COPY-1; - *op++ = *ip++; - *op++ = *ip++; - - /* main loop */ - while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) - { - const flzuint8* ref; - flzuint32 distance; - - /* minimum match length */ - flzuint32 len = 3; - - /* comparison starting-point */ - const flzuint8* anchor = ip; - - /* check for a run */ -#if FASTLZ_LEVEL==2 - if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1)) - { - distance = 1; - ip += 3; - ref = anchor - 1 + 3; - goto match; - } -#endif - - /* find potential match */ - HASH_FUNCTION(hval,ip); - hslot = htab + hval; - ref = htab[hval]; - - /* calculate distance to the match */ - distance = anchor - ref; - - /* update hash table */ - *hslot = anchor; - - /* is this a match? check the first 3 bytes */ - if(distance==0 || -#if FASTLZ_LEVEL==1 - (distance >= MAX_DISTANCE) || -#else - (distance >= MAX_FARDISTANCE) || -#endif - *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++) - goto literal; - -#if FASTLZ_LEVEL==2 - /* far, needs at least 5-byte match */ - if(distance >= MAX_DISTANCE) - { - if(*ip++ != *ref++ || *ip++!= *ref++) - goto literal; - len += 2; - } - - match: -#endif - - /* last matched byte */ - ip = anchor + len; - - /* distance is biased */ - distance--; - - if(!distance) - { - /* zero distance means a run */ - flzuint8 x = ip[-1]; - while(ip < ip_bound) - if(*ref++ != x) break; else ip++; - } - else - for(;;) - { - /* safe because the outer check against ip limit */ - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - if(*ref++ != *ip++) break; - while(ip < ip_bound) - if(*ref++ != *ip++) break; - break; - } - - /* if we have copied something, adjust the copy count */ - if(copy) - /* copy is biased, '0' means 1 byte copy */ - *(op-copy-1) = copy-1; - else - /* back, to overwrite the copy count */ - op--; - - /* reset literal counter */ - copy = 0; - - /* length is biased, '1' means a match of 3 bytes */ - ip -= 3; - len = ip - anchor; - - /* encode the match */ -#if FASTLZ_LEVEL==2 - if(distance < MAX_DISTANCE) - { - if(len < 7) - { - *op++ = (len << 5) + (distance >> 8); - *op++ = (distance & 255); - } - else - { - *op++ = (7 << 5) + (distance >> 8); - for(len-=7; len >= 255; len-= 255) - *op++ = 255; - *op++ = len; - *op++ = (distance & 255); - } - } - else - { - /* far away, but not yet in the another galaxy... */ - if(len < 7) - { - distance -= MAX_DISTANCE; - *op++ = (len << 5) + 31; - *op++ = 255; - *op++ = distance >> 8; - *op++ = distance & 255; - } - else - { - distance -= MAX_DISTANCE; - *op++ = (7 << 5) + 31; - for(len-=7; len >= 255; len-= 255) - *op++ = 255; - *op++ = len; - *op++ = 255; - *op++ = distance >> 8; - *op++ = distance & 255; - } - } -#else - - if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2)) - while(len > MAX_LEN-2) - { - *op++ = (7 << 5) + (distance >> 8); - *op++ = MAX_LEN - 2 - 7 -2; - *op++ = (distance & 255); - len -= MAX_LEN-2; - } - - if(len < 7) - { - *op++ = (len << 5) + (distance >> 8); - *op++ = (distance & 255); - } - else - { - *op++ = (7 << 5) + (distance >> 8); - *op++ = len - 7; - *op++ = (distance & 255); - } -#endif - - /* update the hash at match boundary */ - HASH_FUNCTION(hval,ip); - htab[hval] = ip++; - HASH_FUNCTION(hval,ip); - htab[hval] = ip++; - - /* assuming literal copy */ - *op++ = MAX_COPY-1; - - continue; - - literal: - *op++ = *anchor++; - ip = anchor; - copy++; - if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) - { - copy = 0; - *op++ = MAX_COPY-1; - } - } - - /* left-over as literal copy */ - ip_bound++; - while(ip <= ip_bound) - { - *op++ = *ip++; - copy++; - if(copy == MAX_COPY) - { - copy = 0; - *op++ = MAX_COPY-1; - } - } - - /* if we have copied something, adjust the copy length */ - if(copy) - *(op-copy-1) = copy-1; - else - op--; - -#if FASTLZ_LEVEL==2 - /* marker for fastlz2 */ - *(flzuint8*)output |= (1 << 5); -#endif - - return op - (flzuint8*)output; -} - -static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout) -{ - const flzuint8* ip = (const flzuint8*) input; - const flzuint8* ip_limit = ip + length; - flzuint8* op = (flzuint8*) output; - flzuint8* op_limit = op + maxout; - flzuint32 ctrl = (*ip++) & 31; - int loop = 1; - - do - { - const flzuint8* ref = op; - flzuint32 len = ctrl >> 5; - flzuint32 ofs = (ctrl & 31) << 8; - - if(ctrl >= 32) - { -#if FASTLZ_LEVEL==2 - flzuint8 code; -#endif - len--; - ref -= ofs; - if (len == 7-1) -#if FASTLZ_LEVEL==1 - len += *ip++; - ref -= *ip++; -#else - do - { - code = *ip++; - len += code; - } while (code==255); - code = *ip++; - ref -= code; - - /* match from 16-bit distance */ - if(FASTLZ_UNEXPECT_CONDITIONAL(code==255)) - if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8))) - { - ofs = (*ip++) << 8; - ofs += *ip++; - ref = op - ofs - MAX_DISTANCE; - } -#endif - -#ifdef FASTLZ_SAFE - if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit)) - return 0; - - if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output)) - return 0; -#endif - - if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) - ctrl = *ip++; - else - loop = 0; - - if(ref == op) - { - /* optimize copy for a run */ - flzuint8 b = ref[-1]; - *op++ = b; - *op++ = b; - *op++ = b; - for(; len; --len) - *op++ = b; - } - else - { -#if !defined(FASTLZ_STRICT_ALIGN) - const flzuint16* p; - flzuint16* q; -#endif - /* copy from reference */ - ref--; - *op++ = *ref++; - *op++ = *ref++; - *op++ = *ref++; - -#if !defined(FASTLZ_STRICT_ALIGN) - /* copy a byte, so that now it's word aligned */ - if(len & 1) - { - *op++ = *ref++; - len--; - } - - /* copy 16-bit at once */ - q = (flzuint16*) op; - op += len; - p = (const flzuint16*) ref; - for(len>>=1; len > 4; len-=4) - { - *q++ = *p++; - *q++ = *p++; - *q++ = *p++; - *q++ = *p++; - } - for(; len; --len) - *q++ = *p++; -#else - for(; len; --len) - *op++ = *ref++; -#endif - } - } - else - { - ctrl++; -#ifdef FASTLZ_SAFE - if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit)) - return 0; - if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit)) - return 0; -#endif - - *op++ = *ip++; - for(--ctrl; ctrl; ctrl--) - *op++ = *ip++; - - loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit); - if(loop) - ctrl = *ip++; - } - } - while(FASTLZ_EXPECT_CONDITIONAL(loop)); - - return op - (flzuint8*)output; -} - -#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/fastlz/fastlz.h php-memcached-3.1.4+2.2.0/memcached-3.1.3/fastlz/fastlz.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/fastlz/fastlz.h 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/fastlz/fastlz.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* - FastLZ - lightning-fast lossless compression library - - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef FASTLZ_H -#define FASTLZ_H - -#define FASTLZ_VERSION 0x000100 - -#define FASTLZ_VERSION_MAJOR 0 -#define FASTLZ_VERSION_MINOR 0 -#define FASTLZ_VERSION_REVISION 0 - -#define FASTLZ_VERSION_STRING "0.1.0" - -#if defined (__cplusplus) -extern "C" { -#endif - -/** - Compress a block of data in the input buffer and returns the size of - compressed block. The size of input buffer is specified by length. The - minimum input buffer size is 16. - - The output buffer must be at least 5% larger than the input buffer - and can not be smaller than 66 bytes. - - If the input is not compressible, the return value might be larger than - length (input buffer size). - - The input buffer and the output buffer can not overlap. -*/ - -int fastlz_compress(const void* input, int length, void* output); - -/** - Decompress a block of compressed data and returns the size of the - decompressed block. If error occurs, e.g. the compressed data is - corrupted or the output buffer is not large enough, then 0 (zero) - will be returned instead. - - The input buffer and the output buffer can not overlap. - - Decompression is memory safe and guaranteed not to write the output buffer - more than what is specified in maxout. - */ - -int fastlz_decompress(const void* input, int length, void* output, int maxout); - -/** - Compress a block of data in the input buffer and returns the size of - compressed block. The size of input buffer is specified by length. The - minimum input buffer size is 16. - - The output buffer must be at least 5% larger than the input buffer - and can not be smaller than 66 bytes. - - If the input is not compressible, the return value might be larger than - length (input buffer size). - - The input buffer and the output buffer can not overlap. - - Compression level can be specified in parameter level. At the moment, - only level 1 and level 2 are supported. - Level 1 is the fastest compression and generally useful for short data. - Level 2 is slightly slower but it gives better compression ratio. - - Note that the compressed data, regardless of the level, can always be - decompressed using the function fastlz_decompress above. -*/ - -int fastlz_compress_level(int level, const void* input, int length, void* output); - -#if defined (__cplusplus) -} -#endif - -#endif /* FASTLZ_H */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/fastlz/LICENSE php-memcached-3.1.4+2.2.0/memcached-3.1.3/fastlz/LICENSE --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/fastlz/LICENSE 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/fastlz/LICENSE 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -FastLZ - lightning-fast lossless compression library - -Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) -Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) -Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/g_fmt.c php-memcached-3.1.4+2.2.0/memcached-3.1.3/g_fmt.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/g_fmt.c 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/g_fmt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 1996 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* g_fmt(buf,x) stores the closest decimal approximation to x in buf; - * it suffices to declare buf - * char buf[32]; - */ - -/* Modified for use with php in the memcached client extension. - * - * // Teddy Grenman , 2010-05-18. - */ - -#include - -char *php_memcached_g_fmt(register char *b, double x) { - register int i, k; - register char *s; - int decpt, j, sign; - char *b0, *s0, *se; - - b0 = b; -#ifdef IGNORE_ZERO_SIGN - if (!x) { - *b++ = '0'; - *b = 0; - goto done; - } -#endif - - s = s0 = zend_dtoa(x, 0, 0, &decpt, &sign, &se); - if (sign) - *b++ = '-'; - if (decpt == 9999) /* Infinity or Nan */ { - while((*b++ = *s++)); - goto done0; - } - if (decpt <= -4 || decpt > se - s + 5) { - *b++ = *s++; - if (*s) { - *b++ = '.'; - while((*b = *s++)) - b++; - } - *b++ = 'e'; - /* sprintf(b, "%+.2d", decpt - 1); */ - if (--decpt < 0) { - *b++ = '-'; - decpt = -decpt; - } - else - *b++ = '+'; - for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10); - for(;;) { - i = decpt / k; - *b++ = i + '0'; - if (--j <= 0) - break; - decpt -= i*k; - decpt *= 10; - } - *b = 0; - } else if (decpt <= 0) { - *b++ = '.'; - for(; decpt < 0; decpt++) - *b++ = '0'; - while((*b++ = *s++)); - } else { - while((*b = *s++)) { - b++; - if (--decpt == 0 && *s) - *b++ = '.'; - } - for(; decpt > 0; decpt--) - *b++ = '0'; - *b = 0; - } - - done0: - zend_freedtoa(s0); -#ifdef IGNORE_ZERO_SIGN - done: -#endif - return b0; -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/g_fmt.h php-memcached-3.1.4+2.2.0/memcached-3.1.3/g_fmt.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/g_fmt.h 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/g_fmt.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 1996 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* g_fmt(buf,x) stores the closest decimal approximation to x in buf; - * it suffices to declare buf - * char buf[32]; - */ - -/* Modified for use with php in the memcached client - * extension by Teddy Grenman, 2010. - */ - -#ifndef MEMC_G_FMT_H -#define MEMC_G_FMT_H - -char *php_memcached_g_fmt(register char *b, double x); - -#endif diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/LICENSE php-memcached-3.1.4+2.2.0/memcached-3.1.3/LICENSE --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/LICENSE 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/LICENSE 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ --------------------------------------------------------------------- - The PHP License, version 3.01 -Copyright (c) 1999 - 2010 The PHP Group. All rights reserved. --------------------------------------------------------------------- - -Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. The name "PHP" must not be used to endorse or promote products - derived from this software without prior written permission. For - written permission, please contact group@php.net. - - 4. Products derived from this software may not be called "PHP", nor - may "PHP" appear in their name, without prior written permission - from group@php.net. You may indicate that your software works in - conjunction with PHP by saying "Foo for PHP" instead of calling - it "PHP Foo" or "phpfoo" - - 5. The PHP Group may publish revised and/or new versions of the - license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the terms - of that version. You may also choose to use such covered code - under the terms of any subsequent version of the license - published by the PHP Group. No one other than the PHP Group has - the right to modify the terms applicable to covered code created - under this License. - - 6. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes PHP software, freely available from - ". - -THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP -DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - --------------------------------------------------------------------- - -This software consists of voluntary contributions made by many -individuals on behalf of the PHP Group. - -The PHP Group can be contacted via Email at group@php.net. - -For more information on the PHP Group and the PHP project, -please see . - -PHP includes the Zend Engine, freely available at -. diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/memcached-api.php php-memcached-3.1.4+2.2.0/memcached-3.1.3/memcached-api.php --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/memcached-api.php 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/memcached-api.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,376 +0,0 @@ - comp_len * factor -; -; the default value is 1.3 (23% space saving) -;memcached.compression_factor = "1.3" - -; The compression threshold -; -; Do not compress serialized values below this threshold. -; the default is 2000 bytes -;memcached.compression_threshold = 2000 - -; Set the default serializer for new memcached objects. -; valid values are: php, igbinary, json, json_array, msgpack -; -; json - standard php JSON encoding. This serializer -; is fast and compact but only works on UTF-8 -; encoded data and does not fully implement -; serializing. See the JSON extension. -; json_array - as json, but decodes into arrays -; php - the standard php serializer -; igbinary - a binary serializer -; msgpack - a cross-language binary serializer -; -; The default is igbinary if available, then msgpack if available, then php otherwise. -;memcached.serializer = "igbinary" - -; The amount of retries for failed store commands. -; This mechanism allows transparent fail-over to secondary servers when -; set/increment/decrement/setMulti operations fail on the desired server in a multi-server -; environment. -; the default is 2 -;memcached.store_retry_count = 2 - -; Sets the default for consistent hashing for new connections. -; (To configure consistent hashing for session connections, -; use memcached.sess_consistent_hash instead) -; -; If set to On, consistent hashing (libketama) is used -; for session handling. -; When consistent hashing is used, one can add or remove cache -; node(s) without messing up too much with existing keys -; default is Off -;memcached.default_consistent_hash = Off - -; Sets the default memcached protocol for new connections. -; (To configure the memcached protocol for connections used by sessions, -; use memcached.sess_binary_protocol instead) -; -; If set to On, the memcached binary protocol is used by default. -; If set to Off, the memcached text protocol is used. -; Default is Off -;memcached.default_binary_protocol = Off - -; Sets the default memcached connection timeout for new connections. -; (To configure the memcached connection timeout for sessions, -; use memcached.sess_connect_timeout instead) -; In non-blocking mode this changes the value of the timeout. -; during socket connection in milliseconds. Specifying -1 means an infinite timeout. -; Specifying 0 means using the memcached library's default connection timeout. -; Default is 0. -;memcached.default_connect_timeout = 0 diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_libmemcached_compat.c php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_libmemcached_compat.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_libmemcached_compat.c 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_libmemcached_compat.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#include "php_memcached.h" -#include "php_memcached_private.h" -#include "php_libmemcached_compat.h" - -memcached_return php_memcached_exist(memcached_st *memc, zend_string *key) -{ -#ifdef HAVE_MEMCACHED_EXIST - return memcached_exist(memc, key->val, key->len); -#else - memcached_return rc = MEMCACHED_SUCCESS; - uint32_t flags = 0; - size_t value_length = 0; - char *value = NULL; - - value = memcached_get(memc, key->val, key->len, &value_length, &flags, &rc); - if (value) { - zend_bool *is_persistent = memcached_get_user_data(memc); - pefree(value, *is_persistent); - } - return rc; -#endif -} - -memcached_return php_memcached_touch(memcached_st *memc, const char *key, size_t key_len, time_t expiration) -{ -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 - if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { - php_error_docref(NULL, E_WARNING, "using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached"); - } -#endif - return memcached_touch(memc, key, key_len, expiration); -} - -memcached_return php_memcached_touch_by_key(memcached_st *memc, const char *server_key, size_t server_key_len, const char *key, size_t key_len, time_t expiration) -{ -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 - if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { - php_error_docref(NULL, E_WARNING, "using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached"); - } -#endif - return memcached_touch_by_key(memc, server_key, server_key_len, key, key_len, expiration); -} - diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_libmemcached_compat.h php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_libmemcached_compat.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_libmemcached_compat.h 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_libmemcached_compat.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#ifndef PHP_LIBMEMCACHED_COMPAT -#define PHP_LIBMEMCACHED_COMPAT - -/* this is the version(s) we support */ -#include - -memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); - -memcached_return php_memcached_touch(memcached_st *memc, const char *key, size_t key_len, time_t expiration); -memcached_return php_memcached_touch_by_key(memcached_st *memc, const char *server_key, size_t server_key_len, const char *key, size_t key_len, time_t expiration); - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000017 -typedef const memcached_instance_st * php_memcached_instance_st; -#else -typedef memcached_server_instance_st php_memcached_instance_st; -#endif - -#endif diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached.c php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached.c 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,4690 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009-2010 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -/* TODO - * - set LIBKETAMA_COMPATIBLE as the default? - * - fix unserialize(serialize($memc)) - */ - -#include "php_memcached.h" -#include "php_memcached_private.h" -#include "php_memcached_server.h" -#include "g_fmt.h" - -#include -#include - -#ifdef HAVE_MEMCACHED_SESSION -# include "php_memcached_session.h" -#endif -#ifdef HAVE_FASTLZ_H -#include -#else -#include "fastlz/fastlz.h" -#endif -#include - -#ifdef HAVE_JSON_API -# include "ext/json/php_json.h" -#endif - -#ifdef HAVE_MEMCACHED_IGBINARY -#ifdef PHP_WIN32 -//Windows extensions are generally built together, -//so it wont be in the installed location -#include "igbinary.h" -#else -# include "ext/igbinary/igbinary.h" -#endif -#endif - -#ifdef HAVE_MEMCACHED_MSGPACK -# include "ext/msgpack/php_msgpack.h" -#endif - -static int le_memc; - -static int php_memc_list_entry(void) { - return le_memc; -} - -/**************************************** - Protocol parameters -****************************************/ -#define MEMC_OBJECT_KEY_MAX_LENGTH 250 - -/**************************************** - Custom options -****************************************/ -#define MEMC_OPT_COMPRESSION -1001 -#define MEMC_OPT_PREFIX_KEY -1002 -#define MEMC_OPT_SERIALIZER -1003 -#define MEMC_OPT_COMPRESSION_TYPE -1004 -#define MEMC_OPT_STORE_RETRY_COUNT -1005 -#define MEMC_OPT_USER_FLAGS -1006 - -/**************************************** - Custom result codes -****************************************/ -#define MEMC_RES_PAYLOAD_FAILURE -1001 - -/**************************************** - Payload value flags -****************************************/ -#define MEMC_CREATE_MASK(start, n_bits) (((1 << n_bits) - 1) << start) - -#define MEMC_MASK_TYPE MEMC_CREATE_MASK(0, 4) -#define MEMC_MASK_INTERNAL MEMC_CREATE_MASK(4, 12) -#define MEMC_MASK_USER MEMC_CREATE_MASK(16, 16) - -#define MEMC_VAL_GET_TYPE(flags) ((flags) & MEMC_MASK_TYPE) -#define MEMC_VAL_SET_TYPE(flags, type) ((flags) |= ((type) & MEMC_MASK_TYPE)) - -#define MEMC_VAL_IS_STRING 0 -#define MEMC_VAL_IS_LONG 1 -#define MEMC_VAL_IS_DOUBLE 2 -#define MEMC_VAL_IS_BOOL 3 -#define MEMC_VAL_IS_SERIALIZED 4 -#define MEMC_VAL_IS_IGBINARY 5 -#define MEMC_VAL_IS_JSON 6 -#define MEMC_VAL_IS_MSGPACK 7 - -#define MEMC_VAL_COMPRESSED (1<<0) -#define MEMC_VAL_COMPRESSION_ZLIB (1<<1) -#define MEMC_VAL_COMPRESSION_FASTLZ (1<<2) - -#define MEMC_VAL_GET_FLAGS(internal_flags) (((internal_flags) & MEMC_MASK_INTERNAL) >> 4) -#define MEMC_VAL_SET_FLAG(internal_flags, internal_flag) ((internal_flags) |= (((internal_flag) << 4) & MEMC_MASK_INTERNAL)) -#define MEMC_VAL_HAS_FLAG(internal_flags, internal_flag) ((MEMC_VAL_GET_FLAGS(internal_flags) & (internal_flag)) == (internal_flag)) -#define MEMC_VAL_DEL_FLAG(internal_flags, internal_flag) (internal_flags &= (~(((internal_flag) << 4) & MEMC_MASK_INTERNAL))) - -/**************************************** - User-defined flags -****************************************/ -#define MEMC_VAL_GET_USER_FLAGS(flags) ((flags & MEMC_MASK_USER) >> 16) -#define MEMC_VAL_SET_USER_FLAGS(flags, udf_flags) ((flags) |= ((udf_flags << 16) & MEMC_MASK_USER)) -#define MEMC_VAL_USER_FLAGS_MAX ((1 << 16) - 1) - -/**************************************** - "get" operation flags -****************************************/ -#define MEMC_GET_PRESERVE_ORDER 1 -#define MEMC_GET_EXTENDED 2 - -/**************************************** - Helper macros -****************************************/ -#define RETURN_FROM_GET RETURN_FALSE - -/**************************************** - Structures and definitions -****************************************/ - -typedef enum { - MEMC_OP_SET, - MEMC_OP_TOUCH, - MEMC_OP_ADD, - MEMC_OP_REPLACE, - MEMC_OP_APPEND, - MEMC_OP_PREPEND -} php_memc_write_op; - -typedef struct { - - zend_bool is_persistent; - zend_bool compression_enabled; - zend_bool encoding_enabled; - - zend_long serializer; - zend_long compression_type; - - zend_long store_retry_count; - zend_long set_udf_flags; - -#ifdef HAVE_MEMCACHED_SASL - zend_bool has_sasl_data; -#endif -} php_memc_user_data_t; - -typedef struct { - memcached_st *memc; - zend_bool is_pristine; - int rescode; - int memc_errno; - zend_object zo; -} php_memc_object_t; - -typedef struct { - size_t num_valid_keys; - - const char **mkeys; - size_t *mkeys_len; - - zend_string **strings; - -} php_memc_keys_t; - -typedef struct { - zval *object; - zend_fcall_info fci; - zend_fcall_info_cache fcc; -} php_memc_result_callback_ctx_t; - -static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) { - return (php_memc_object_t *)((char *)obj - XtOffsetOf(php_memc_object_t, zo)); -} -#define Z_MEMC_OBJ_P(zv) php_memc_fetch_object(Z_OBJ_P(zv)); - -#define MEMC_METHOD_INIT_VARS \ - zval* object = getThis(); \ - php_memc_object_t* intern = NULL; \ - php_memc_user_data_t* memc_user_data = NULL; - -#define MEMC_METHOD_FETCH_OBJECT \ - intern = Z_MEMC_OBJ_P(object); \ - if (!intern->memc) { \ - php_error_docref(NULL, E_WARNING, "Memcached constructor was not called"); \ - return; \ - } \ - memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc); \ - (void)memc_user_data; /* avoid unused variable warning */ - -static -zend_bool s_memc_valid_key_binary(zend_string *key) -{ - return memchr(ZSTR_VAL(key), '\n', ZSTR_LEN(key)) == NULL; -} - -static -zend_bool s_memc_valid_key_ascii(zend_string *key) -{ - const char *str = ZSTR_VAL(key); - size_t i, len = ZSTR_LEN(key); - - for (i = 0; i < len; i++) { - if (iscntrl(str[i]) || isspace(str[i])) - return 0; - } - return 1; -} - -#define MEMC_CHECK_KEY(intern, key) \ - if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ - ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ - (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ - ? !s_memc_valid_key_binary(key) \ - : !s_memc_valid_key_ascii(key) \ - ))) { \ - intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \ - RETURN_FALSE; \ - } - -#ifdef HAVE_MEMCACHED_PROTOCOL -typedef struct { - php_memc_proto_handler_t *handler; - zend_object zo; -} php_memc_server_t; - -static inline php_memc_server_t *php_memc_server_fetch_object(zend_object *obj) { - return (php_memc_server_t *)((char *)obj - XtOffsetOf(php_memc_server_t, zo)); -} -#define Z_MEMC_SERVER_P(zv) php_memc_server_fetch_object(Z_OBJ_P(zv)) - -static zend_object_handlers memcached_server_object_handlers; -static zend_class_entry *memcached_server_ce = NULL; -#endif - -static zend_class_entry *memcached_ce = NULL; -static zend_class_entry *memcached_exception_ce = NULL; -static zend_object_handlers memcached_object_handlers; - -#ifdef HAVE_SPL -static zend_class_entry *spl_ce_RuntimeException = NULL; -#endif - -ZEND_DECLARE_MODULE_GLOBALS(php_memcached) - -#ifdef COMPILE_DL_MEMCACHED -ZEND_GET_MODULE(memcached) -#endif - -static PHP_INI_MH(OnUpdateCompressionType) -{ - if (!new_value) { - MEMC_G(compression_type) = COMPRESSION_TYPE_FASTLZ; - } else if (!strcmp(ZSTR_VAL(new_value), "fastlz")) { - MEMC_G(compression_type) = COMPRESSION_TYPE_FASTLZ; - } else if (!strcmp(ZSTR_VAL(new_value), "zlib")) { - MEMC_G(compression_type) = COMPRESSION_TYPE_ZLIB; - } else { - return FAILURE; - } - return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); -} - -static PHP_INI_MH(OnUpdateSerializer) -{ - if (!new_value) { - MEMC_G(serializer_type) = SERIALIZER_DEFAULT; - } else if (!strcmp(ZSTR_VAL(new_value), "php")) { - MEMC_G(serializer_type) = SERIALIZER_PHP; -#ifdef HAVE_MEMCACHED_IGBINARY - } else if (!strcmp(ZSTR_VAL(new_value), "igbinary")) { - MEMC_G(serializer_type) = SERIALIZER_IGBINARY; -#endif // IGBINARY -#ifdef HAVE_JSON_API - } else if (!strcmp(ZSTR_VAL(new_value), "json")) { - MEMC_G(serializer_type) = SERIALIZER_JSON; - } else if (!strcmp(ZSTR_VAL(new_value), "json_array")) { - MEMC_G(serializer_type) = SERIALIZER_JSON_ARRAY; -#endif // JSON -#ifdef HAVE_MEMCACHED_MSGPACK - } else if (!strcmp(ZSTR_VAL(new_value), "msgpack")) { - MEMC_G(serializer_type) = SERIALIZER_MSGPACK; -#endif // msgpack - } else { - return FAILURE; - } - - return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); -} - -#ifdef HAVE_MEMCACHED_SESSION -static -PHP_INI_MH(OnUpdateDeprecatedLockValue) -{ - if (ZSTR_LEN(new_value) > 0 && strcmp(ZSTR_VAL(new_value), "not set")) { - php_error_docref(NULL, E_DEPRECATED, "memcached.sess_lock_wait and memcached.sess_lock_max_wait are deprecated. Please update your configuration to use memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries"); - } - return FAILURE; -} - -static -PHP_INI_MH(OnUpdateSessionPrefixString) -{ - if (new_value && ZSTR_LEN(new_value) > 0) { - if (ZSTR_LEN(new_value) > MEMCACHED_MAX_KEY) { - php_error_docref(NULL, E_WARNING, "memcached.sess_prefix too long (max: %d)", MEMCACHED_MAX_KEY - 1); - return FAILURE; - } - if (!s_memc_valid_key_ascii(new_value)) { - php_error_docref(NULL, E_WARNING, "memcached.sess_prefix cannot contain whitespace or control characters"); - return FAILURE; - } - } - return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); -} - -static -PHP_INI_MH(OnUpdateConsistentHash) -{ - if (!new_value) { - MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; - } else if (!strcmp(ZSTR_VAL(new_value), "ketama")) { - MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; - } else if (!strcmp(ZSTR_VAL(new_value), "ketama_weighted")) { - MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED; - } else { - php_error_docref(NULL, E_WARNING, "memcached.sess_consistent_hash_type must be ketama or ketama_weighted"); - return FAILURE; - } - return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); -} -#endif // HAVE_MEMCACHED_SESSION - -#define MEMC_INI_ENTRY(key, default_value, update_fn, gkey) \ - STD_PHP_INI_ENTRY("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) - -#define MEMC_INI_BOOL(key, default_value, update_fn, gkey) \ - STD_PHP_INI_BOOLEAN("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) - -#define MEMC_INI_LINK(key, default_value, update_fn, gkey) \ - STD_PHP_INI_ENTRY_EX("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals, display_link_numbers) - -#define MEMC_SESSION_INI_ENTRY(key, default_value, update_fn, gkey) \ - STD_PHP_INI_ENTRY("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) - -#define MEMC_SESSION_INI_BOOL(key, default_value, update_fn, gkey) \ - STD_PHP_INI_BOOLEAN("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) - -#define MEMC_SESSION_INI_LINK(key, default_value, update_fn, gkey) \ - STD_PHP_INI_ENTRY_EX("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals, display_link_numbers) - - -/* {{{ INI entries */ -PHP_INI_BEGIN() - -#ifdef HAVE_MEMCACHED_SESSION - MEMC_SESSION_INI_BOOL ("locking", "1", OnUpdateBool, lock_enabled) - MEMC_SESSION_INI_ENTRY("lock_wait_min", "150", OnUpdateLongGEZero, lock_wait_min) - MEMC_SESSION_INI_ENTRY("lock_wait_max", "150", OnUpdateLongGEZero, lock_wait_max) - MEMC_SESSION_INI_ENTRY("lock_retries", "5", OnUpdateLong, lock_retries) - MEMC_SESSION_INI_ENTRY("lock_expire", "0", OnUpdateLongGEZero, lock_expiration) -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 - MEMC_SESSION_INI_BOOL ("binary_protocol", "0", OnUpdateBool, binary_protocol_enabled) -#else - MEMC_SESSION_INI_BOOL ("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled) -#endif - MEMC_SESSION_INI_BOOL ("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) - MEMC_SESSION_INI_ENTRY("consistent_hash_type", "ketama", OnUpdateConsistentHash, consistent_hash_name) - MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas) - MEMC_SESSION_INI_BOOL ("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) - MEMC_SESSION_INI_BOOL ("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) - MEMC_SESSION_INI_ENTRY("server_failure_limit", "0", OnUpdateLongGEZero, server_failure_limit) - MEMC_SESSION_INI_LINK ("connect_timeout", "0", OnUpdateLong, connect_timeout) - - MEMC_SESSION_INI_ENTRY("sasl_username", "", OnUpdateString, sasl_username) - MEMC_SESSION_INI_ENTRY("sasl_password", "", OnUpdateString, sasl_password) - MEMC_SESSION_INI_BOOL ("persistent", "0", OnUpdateBool, persistent_enabled) - MEMC_SESSION_INI_ENTRY("prefix", "memc.sess.key.", OnUpdateSessionPrefixString, prefix) - - /* Deprecated */ - STD_PHP_INI_ENTRY("memcached.sess_lock_wait", "not set", PHP_INI_ALL, OnUpdateDeprecatedLockValue, no_effect, zend_php_memcached_globals, php_memcached_globals) - STD_PHP_INI_ENTRY("memcached.sess_lock_max_wait", "not set", PHP_INI_ALL, OnUpdateDeprecatedLockValue, no_effect, zend_php_memcached_globals, php_memcached_globals) - -#endif - - MEMC_INI_ENTRY("compression_type", "fastlz", OnUpdateCompressionType, compression_name) - MEMC_INI_ENTRY("compression_factor", "1.3", OnUpdateReal, compression_factor) - MEMC_INI_ENTRY("compression_threshold", "2000", OnUpdateLong, compression_threshold) - MEMC_INI_ENTRY("serializer", SERIALIZER_DEFAULT_NAME, OnUpdateSerializer, serializer_name) - MEMC_INI_ENTRY("store_retry_count", "2", OnUpdateLong, store_retry_count) - - MEMC_INI_BOOL ("default_consistent_hash", "0", OnUpdateBool, default_behavior.consistent_hash_enabled) - MEMC_INI_BOOL ("default_binary_protocol", "0", OnUpdateBool, default_behavior.binary_protocol_enabled) - MEMC_INI_LINK ("default_connect_timeout", "0", OnUpdateLong, default_behavior.connect_timeout) - -PHP_INI_END() -/* }}} */ - -#undef MEMC_INI_BOOL -#undef MEMC_INI_LINK -#undef MEMC_INI_ENTRY -#undef MEMC_SESSION_INI_BOOL -#undef MEMC_SESSION_INI_LINK -#undef MEMC_SESSION_INI_ENTRY - -/**************************************** - Forward declarations -****************************************/ -static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); -static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); -static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool by_key); -static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); -static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); -static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); -static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); - -/* Invoke PHP functions */ -static zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_bool with_cas, zend_string *key, zval *value); - -/* Iterate result sets */ -typedef zend_bool (*php_memc_result_apply_fn)(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *context); - -static -memcached_return php_memc_result_apply(php_memc_object_t *intern, php_memc_result_apply_fn result_apply_fn, zend_bool fetch_delay, void *context); - -static -zend_bool php_memc_mget_apply(php_memc_object_t *intern, zend_string *server_key, - php_memc_keys_t *keys, php_memc_result_apply_fn result_apply_fn, - zend_bool with_cas, void *context); - - -/* Callback functions for different server list iterations */ -static - memcached_return s_server_cursor_list_servers_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context); - -static - memcached_return s_server_cursor_version_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context); - -static - zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, zend_string *server_key, zend_string *key, zval *value, time_t expiration); - -static - void php_memc_destroy(memcached_st *memc, php_memc_user_data_t *memc_user_data); - -static - zend_bool s_memcached_result_to_zval(memcached_st *memc, memcached_result_st *result, zval *return_value); - -static - zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t *flags); - -static - void s_hash_to_keys(php_memc_keys_t *keys_out, HashTable *hash_in, zend_bool preserve_order, zval *return_value); - -static - void s_clear_keys(php_memc_keys_t *keys); - - -/**************************************** - Exported helper functions -****************************************/ - -zend_bool php_memc_init_sasl_if_needed() -{ -#ifdef HAVE_MEMCACHED_SASL - if (MEMC_G(sasl_initialised)) { - return 1; - } - if (sasl_client_init(NULL) != SASL_OK) { - php_error_docref(NULL, E_ERROR, "Failed to initialize SASL library"); - return 0; - } - return 1; -#else - php_error_docref(NULL, E_ERROR, "Memcached not built with sasl support"); - return 0; -#endif -} - -char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) -{ - char *buffer = NULL; - - if (fci->object) { - spprintf (&buffer, 0, "%s::%s", ZSTR_VAL(fci->object->ce->name), ZSTR_VAL(fci_cache->function_handler->common.function_name)); - } else { - if (Z_TYPE (fci->function_name) == IS_OBJECT) { - spprintf (&buffer, 0, "%s", ZSTR_VAL(Z_OBJCE(fci->function_name)->name)); - } - else { - spprintf (&buffer, 0, "%s", Z_STRVAL(fci->function_name)); - } - } - return buffer; -} - - -/**************************************** - Handling error codes -****************************************/ - -static -zend_bool s_memcached_return_is_error(memcached_return status, zend_bool strict) -{ - zend_bool result = 0; - - switch (status) { - case MEMCACHED_SUCCESS: - case MEMCACHED_STORED: - case MEMCACHED_DELETED: - case MEMCACHED_STAT: - case MEMCACHED_END: - case MEMCACHED_BUFFERED: - result = 0; - break; - - case MEMCACHED_SOME_ERRORS: - result = strict; - break; - - default: - result = 1; - break; - } - return result; -} - -static -int s_memc_status_handle_result_code(php_memc_object_t *intern, memcached_return status) -{ - intern->rescode = status; - intern->memc_errno = 0; - - if (s_memcached_return_is_error(status, 1)) { - intern->memc_errno = memcached_last_error_errno(intern->memc); - return FAILURE; - } - return SUCCESS; -} - -static -void s_memc_set_status(php_memc_object_t *intern, memcached_return status, int memc_errno) -{ - intern->rescode = status; - intern->memc_errno = memc_errno; -} - -static -zend_bool s_memc_status_has_error(php_memc_object_t *intern) -{ - return s_memcached_return_is_error(intern->rescode, 1); -} - -static -zend_bool s_memc_status_has_result_code(php_memc_object_t *intern, memcached_return status) -{ - return intern->rescode == status; -} - -/**************************************** - Marshall cas tokens -****************************************/ - -static -void s_uint64_to_zval (zval *target, uint64_t value) -{ - if (value >= ((uint64_t) LONG_MAX)) { - zend_string *buffer; -#ifdef PRIu64 - buffer = strpprintf (0, "%" PRIu64, value); -#else - /* Best effort */ - buffer = strpprintf (0, "%llu", value); -#endif - ZVAL_STR(target, buffer); - } - else { - ZVAL_LONG (target, (zend_long) value); - } -} - -static -uint64_t s_zval_to_uint64 (zval *cas) -{ - switch (Z_TYPE_P (cas)) { - case IS_LONG: - return (uint64_t) zval_get_long (cas); - break; - - case IS_DOUBLE: - if (Z_DVAL_P (cas) < 0.0) - return 0; - - return (uint64_t) zval_get_double (cas); - break; - - case IS_STRING: - { - uint64_t val; - char *end; - - errno = 0; - val = (uint64_t) strtoull (Z_STRVAL_P (cas), &end, 0); - - if (*end || (errno == ERANGE && val == UINT64_MAX) || (errno != 0 && val == 0)) { - php_error_docref(NULL, E_ERROR, "Failed to unmarshall cas token"); - return 0; - } - return val; - } - break; - } - return 0; -} - - -/**************************************** - Iterate over memcached results and mget -****************************************/ - -static -memcached_return php_memc_result_apply(php_memc_object_t *intern, php_memc_result_apply_fn result_apply_fn, zend_bool fetch_delay, void *context) -{ - memcached_result_st result, *result_ptr; - memcached_return rc, status = MEMCACHED_SUCCESS; - - memcached_result_create(intern->memc, &result); - - do { - result_ptr = memcached_fetch_result(intern->memc, &result, &rc); - - if (s_memcached_return_is_error(rc, 0)) { - status = rc; - } - - /* nothing returned */ - if (!result_ptr) { - break; - } - else { - zend_string *key; - zval val, zcas; - zend_bool retval; - - uint64_t cas; - uint32_t flags; - - const char *res_key; - size_t res_key_len; - - if (!s_memcached_result_to_zval(intern->memc, &result, &val)) { - if (EG(exception)) { - status = MEMC_RES_PAYLOAD_FAILURE; - memcached_quit(intern->memc); - break; - } - status = MEMCACHED_SOME_ERRORS; - continue; - } - - res_key = memcached_result_key_value(&result); - res_key_len = memcached_result_key_length(&result); - cas = memcached_result_cas(&result); - flags = memcached_result_flags(&result); - - s_uint64_to_zval(&zcas, cas); - - key = zend_string_init (res_key, res_key_len, 0); - retval = result_apply_fn(intern, key, &val, &zcas, flags, context); - - zend_string_release(key); - zval_ptr_dtor(&val); - zval_ptr_dtor(&zcas); - - /* Stop iterating on false */ - if (!retval) { - if (!fetch_delay) { - /* Make sure we clear our results */ - while (memcached_fetch_result(intern->memc, &result, &rc)) {} - } - break; - } - } - } while (result_ptr != NULL); - - memcached_result_free(&result); - return status; -} - -static -zend_bool php_memc_mget_apply(php_memc_object_t *intern, zend_string *server_key, php_memc_keys_t *keys, - php_memc_result_apply_fn result_apply_fn, zend_bool with_cas, void *context) -{ - memcached_return status; - int mget_status; - uint64_t orig_cas_flag = 0; - - // Reset status code - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - if (!keys->num_valid_keys) { - intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; - return 0; - } - - if (with_cas) { - orig_cas_flag = memcached_behavior_get (intern->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS); - - if (!orig_cas_flag) { - memcached_behavior_set (intern->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1); - } - } - - if (server_key) { - status = memcached_mget_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), keys->mkeys, keys->mkeys_len, keys->num_valid_keys); - } else { - status = memcached_mget(intern->memc, keys->mkeys, keys->mkeys_len, keys->num_valid_keys); - } - - /* Need to handle result code before restoring cas flags, would mess up errno */ - mget_status = s_memc_status_handle_result_code(intern, status); - - if (with_cas && !orig_cas_flag) { - memcached_behavior_set (intern->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag); - } - - /* Return on failure codes */ - if (mget_status == FAILURE) { - return 0; - } - - if (!result_apply_fn) { - /* no callback, for example getDelayed */ - return 1; - } - - status = php_memc_result_apply(intern, result_apply_fn, 0, context); - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - return 0; - } - - return 1; -} - -/**************************************** - Invoke callbacks -****************************************/ - -static -zend_bool s_invoke_new_instance_cb(zval *object, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, zend_string *persistent_id) -{ - zend_bool ret = 1; - zval retval; - zval params[2]; - - ZVAL_COPY(¶ms[0], object); - if (persistent_id) { - ZVAL_STR(¶ms[1], zend_string_copy(persistent_id)); - } else { - ZVAL_NULL(¶ms[1]); - } - - fci->retval = &retval; - fci->params = params; - fci->param_count = 2; - - if (zend_call_function(fci, fci_cache) == FAILURE) { - char *buf = php_memc_printable_func (fci, fci_cache); - php_error_docref(NULL, E_WARNING, "Failed to invoke 'on_new' callback %s()", buf); - efree (buf); - ret = 0; - } - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(&retval); - - return ret; -} - -static -zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_bool with_cas, zend_string *key, zval *value) -{ - zend_bool status = 0; - zval params[4]; - zval retval; - php_memc_object_t *intern = Z_MEMC_OBJ_P(zobject); - - /* Prepare params */ - ZVAL_COPY(¶ms[0], zobject); - ZVAL_STR_COPY(¶ms[1], key); /* key */ - ZVAL_NEW_REF(¶ms[2], value); /* value */ - - if (with_cas) { - fci->param_count = 3; - } else { - ZVAL_NEW_EMPTY_REF(¶ms[3]); /* expiration */ - ZVAL_NULL(Z_REFVAL(params[3])); - fci->param_count = 4; - } - - fci->retval = &retval; - fci->params = params; - - if (zend_call_function(fci, fcc) == SUCCESS) { - if (zend_is_true(&retval)) { - time_t expiration; - zval *val = Z_REFVAL(params[2]); - - if (with_cas) { - if (Z_TYPE_P(val) == IS_ARRAY) { - zval *rv = zend_hash_str_find(Z_ARRVAL_P(val), "value", sizeof("value") - 1); - if (rv) { - zval *cas = zend_hash_str_find(Z_ARRVAL_P(val), "cas", sizeof("cas") -1); - expiration = cas? Z_LVAL_P(cas) : 0; - status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, rv, expiration); - } - /* memleak? zval_ptr_dtor(value); */ - ZVAL_COPY(value, val); - } - } else { - expiration = zval_get_long(Z_REFVAL(params[3])); - status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, val, expiration); - /* memleak? zval_ptr_dtor(value); */ - ZVAL_COPY(value, val); - } - } - } - else { - s_memc_set_status(intern, MEMCACHED_NOTFOUND, 0); - } - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - if (!with_cas) { - zval_ptr_dtor(¶ms[3]); - } - zval_ptr_dtor(&retval); - - return status; -} - -/**************************************** - Wrapper for setting from zval -****************************************/ - -static -zend_bool s_compress_value (php_memc_compression_type compression_type, zend_string **payload_in, uint32_t *flags) -{ - /* status */ - zend_bool compress_status = 0; - zend_string *payload = *payload_in; - uint32_t compression_type_flag = 0; - - /* Additional 5% for the data */ - size_t buffer_size = (size_t) (((double) ZSTR_LEN(payload) * 1.05) + 1.0); - char *buffer = emalloc(buffer_size); - - /* Store compressed size here */ - size_t compressed_size = 0; - uint32_t original_size = ZSTR_LEN(payload); - - switch (compression_type) { - - case COMPRESSION_TYPE_FASTLZ: - { - compressed_size = fastlz_compress(ZSTR_VAL(payload), ZSTR_LEN(payload), buffer); - - if (compressed_size > 0) { - compress_status = 1; - compression_type_flag = MEMC_VAL_COMPRESSION_FASTLZ; - } - } - break; - - case COMPRESSION_TYPE_ZLIB: - { - compressed_size = buffer_size; - int status = compress((Bytef *) buffer, &compressed_size, (Bytef *) ZSTR_VAL(payload), ZSTR_LEN(payload)); - - if (status == Z_OK) { - compress_status = 1; - compression_type_flag = MEMC_VAL_COMPRESSION_ZLIB; - } - } - break; - - default: - compress_status = 0; - break; - } - - /* This means the value was too small to be compressed and ended up larger */ - if (ZSTR_LEN(payload) <= (compressed_size * MEMC_G(compression_factor))) { - compress_status = 0; - } - - /* Replace the payload with the compressed copy */ - if (compress_status) { - MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED | compression_type_flag); - payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0); - - /* Copy the uin32_t at the beginning */ - memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t)); - memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size); - efree(buffer); - - zend_string_forget_hash_val(payload); - *payload_in = payload; - - return 1; - } - - /* Original payload was not modified */ - efree(buffer); - return 0; -} - -static -zend_bool s_serialize_value (php_memc_serializer_type serializer, zval *value, smart_str *buf, uint32_t *flags) -{ - switch (serializer) { - - /* - Igbinary serialization - */ -#ifdef HAVE_MEMCACHED_IGBINARY - case SERIALIZER_IGBINARY: - { - uint8_t *buffer; - size_t buffer_len; - - if (igbinary_serialize(&buffer, &buffer_len, value) != 0) { - php_error_docref(NULL, E_WARNING, "could not serialize value with igbinary"); - return 0; - } - smart_str_appendl (buf, (char *)buffer, buffer_len); - efree(buffer); - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_IGBINARY); - } - break; -#endif - - /* - JSON serialization - */ -#ifdef HAVE_JSON_API - case SERIALIZER_JSON: - case SERIALIZER_JSON_ARRAY: - { - php_json_encode(buf, value, 0); - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_JSON); - } - break; -#endif - - /* - msgpack serialization - */ -#ifdef HAVE_MEMCACHED_MSGPACK - case SERIALIZER_MSGPACK: - php_msgpack_serialize(buf, value); - if (!buf->s) { - php_error_docref(NULL, E_WARNING, "could not serialize value with msgpack"); - return 0; - } - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_MSGPACK); - break; -#endif - - /* - PHP serialization - */ - default: - { - php_serialize_data_t var_hash; - PHP_VAR_SERIALIZE_INIT(var_hash); - php_var_serialize(buf, value, &var_hash); - PHP_VAR_SERIALIZE_DESTROY(var_hash); - - if (!buf->s) { - php_error_docref(NULL, E_WARNING, "could not serialize value"); - return 0; - } - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_SERIALIZED); - } - break; - } - - /* Check for exceptions caused by serializers */ - if (EG(exception) && buf->s->len) { - return 0; - } - return 1; -} - -static -zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t *flags) -{ - zend_string *payload; - php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); - zend_bool should_compress = memc_user_data->compression_enabled; - - switch (Z_TYPE_P(value)) { - - case IS_STRING: - payload = zval_get_string(value); - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_STRING); - break; - - case IS_LONG: - { - smart_str buffer = {0}; - smart_str_append_long (&buffer, Z_LVAL_P(value)); - smart_str_0(&buffer); - payload = buffer.s; - - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG); - should_compress = 0; - } - break; - - case IS_DOUBLE: - { - char buffer[40]; - php_memcached_g_fmt(buffer, Z_DVAL_P(value)); - payload = zend_string_init (buffer, strlen (buffer), 0); - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE); - should_compress = 0; - } - break; - - case IS_TRUE: - payload = zend_string_init ("1", 1, 0); - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL); - should_compress = 0; - break; - - case IS_FALSE: - payload = zend_string_alloc (0, 0); - MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL); - should_compress = 0; - break; - - default: - { - smart_str buffer = {0}; - - if (!s_serialize_value (memc_user_data->serializer, value, &buffer, flags)) { - smart_str_free(&buffer); - return NULL; - } - payload = buffer.s; - } - break; - } - - /* turn off compression for values below the threshold */ - if (ZSTR_LEN(payload) == 0 || ZSTR_LEN(payload) < MEMC_G(compression_threshold)) { - should_compress = 0; - } - - /* If we have compression flag, compress the value */ - if (should_compress) { - /* s_compress_value() will always leave a valid payload, even if that payload - * did not actually get compressed. The flags will be set according to the - * to the compression type or no compression. - * - * No need to check the return value because the payload is always valid. - */ - (void)s_compress_value (memc_user_data->compression_type, &payload, flags); - } - - if (memc_user_data->set_udf_flags >= 0) { - MEMC_VAL_SET_USER_FLAGS(*flags, ((uint32_t) memc_user_data->set_udf_flags)); - } - - return payload; -} - -static -zend_bool s_should_retry_write (php_memc_object_t *intern, memcached_return status) -{ - if (memcached_server_count (intern->memc) == 0) { - return 0; - } - - return s_memcached_return_is_error (status, 1); -} - -static -zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, zend_string *server_key, zend_string *key, zval *value, time_t expiration) -{ - uint32_t flags = 0; - zend_string *payload = NULL; - memcached_return status = 0; - php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); - zend_long retries = memc_user_data->store_retry_count; - - if (value) { - payload = s_zval_to_payload(intern, value, &flags); - - if (!payload) { - s_memc_set_status(intern, MEMC_RES_PAYLOAD_FAILURE, 0); - return 0; - } - } - -#define memc_write_using_fn(fn_name) payload ? fn_name(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags) : MEMC_RES_PAYLOAD_FAILURE; -#define memc_write_using_fn_by_key(fn_name) payload ? fn_name(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags) : MEMC_RES_PAYLOAD_FAILURE; - - if (server_key) { - switch (op) { - case MEMC_OP_SET: - status = memc_write_using_fn_by_key(memcached_set_by_key); - break; - - case MEMC_OP_TOUCH: - status = php_memcached_touch_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), expiration); - break; - - case MEMC_OP_ADD: - status = memc_write_using_fn_by_key(memcached_add_by_key); - break; - - case MEMC_OP_REPLACE: - status = memc_write_using_fn_by_key(memcached_replace_by_key); - break; - - case MEMC_OP_APPEND: - status = memc_write_using_fn_by_key(memcached_append_by_key); - break; - - case MEMC_OP_PREPEND: - status = memc_write_using_fn_by_key(memcached_prepend_by_key); - break; - } - - if (status == MEMCACHED_END) { - status = MEMCACHED_SUCCESS; - } - } - else { -retry: - switch (op) { - case MEMC_OP_SET: - status = memc_write_using_fn(memcached_set); - break; - - case MEMC_OP_TOUCH: - status = php_memcached_touch(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), expiration); - break; - - case MEMC_OP_ADD: - status = memc_write_using_fn(memcached_add); - break; - - case MEMC_OP_REPLACE: - status = memc_write_using_fn(memcached_replace); - break; - - case MEMC_OP_APPEND: - status = memc_write_using_fn(memcached_append); - break; - - case MEMC_OP_PREPEND: - status = memc_write_using_fn(memcached_prepend); - break; - } - if (status == MEMCACHED_END) { - status = MEMCACHED_SUCCESS; - } - } - - if (s_should_retry_write (intern, status) && retries-- > 0) { - goto retry; - } - -#undef memc_write_using_fn -#undef memc_write_using_fn_by_key - - if (payload) { - zend_string_release(payload); - } - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - return 0; - } - return 1; -} - - -/**************************************** - Methods -****************************************/ - - -/* {{{ Memcached::__construct([string persistent_id[, callback on_new[, string connection_str]]])) - Creates a Memcached object, optionally using persistent memcache connection */ -static PHP_METHOD(Memcached, __construct) -{ - php_memc_object_t *intern; - php_memc_user_data_t *memc_user_data; - - zend_string *persistent_id = NULL; - zend_string *conn_str = NULL; - zend_string *plist_key = NULL; - zend_fcall_info fci = {0}; - zend_fcall_info_cache fci_cache; - - zend_bool is_persistent = 0; - - /* "|S!f!S" */ - ZEND_PARSE_PARAMETERS_START(0, 3) - Z_PARAM_OPTIONAL - Z_PARAM_STR_EX(persistent_id, 1, 0) - Z_PARAM_FUNC_EX(fci, fci_cache, 1, 0) - Z_PARAM_STR(conn_str) - ZEND_PARSE_PARAMETERS_END(); - - intern = Z_MEMC_OBJ_P(getThis()); - intern->is_pristine = 1; - - if (persistent_id && persistent_id->len) { - zend_resource *le; - - plist_key = zend_string_alloc(sizeof("memcached:id=") + persistent_id->len - 1, 0); - snprintf(ZSTR_VAL(plist_key), plist_key->len + 1, "memcached:id=%s", ZSTR_VAL(persistent_id)); - - if ((le = zend_hash_find_ptr(&EG(persistent_list), plist_key)) != NULL) { - if (le->type == php_memc_list_entry()) { - intern->memc = le->ptr; - intern->is_pristine = 0; - zend_string_release (plist_key); - return; - } - } - is_persistent = 1; - } - - if (conn_str && conn_str->len > 0) { - intern->memc = memcached (ZSTR_VAL(conn_str), ZSTR_LEN(conn_str)); - } - else { - intern->memc = memcached (NULL, 0); - } - - if (!intern->memc) { - php_error_docref(NULL, E_ERROR, "Failed to allocate memory for memcached structure"); - /* never reached */ - } - - memc_user_data = pecalloc (1, sizeof(*memc_user_data), is_persistent); - memc_user_data->serializer = MEMC_G(serializer_type); - memc_user_data->compression_type = MEMC_G(compression_type); - memc_user_data->compression_enabled = 1; - memc_user_data->encoding_enabled = 0; - memc_user_data->store_retry_count = MEMC_G(store_retry_count); - memc_user_data->set_udf_flags = -1; - memc_user_data->is_persistent = is_persistent; - - memcached_set_user_data(intern->memc, memc_user_data); - - /* Set default behaviors */ - if (MEMC_G(default_behavior.consistent_hash_enabled)) { - memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT); - if (rc != MEMCACHED_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Failed to turn on consistent hash: %s", memcached_strerror(intern->memc, rc)); - } - } - - if (MEMC_G(default_behavior.binary_protocol_enabled)) { - memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); - if (rc != MEMCACHED_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Failed to turn on binary protocol: %s", memcached_strerror(intern->memc, rc)); - } - } - - if (MEMC_G(default_behavior.connect_timeout)) { - memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, MEMC_G(default_behavior.connect_timeout)); - if (rc != MEMCACHED_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Failed to set connect timeout: %s", memcached_strerror(intern->memc, rc)); - } - } - - if (fci.size) { - if (!s_invoke_new_instance_cb(getThis(), &fci, &fci_cache, persistent_id) || EG(exception)) { - /* error calling or exception thrown from callback */ - if (plist_key) { - zend_string_release(plist_key); - } - /* - Setting intern->memc null prevents object destruction from freeing the memcached_st - We free it manually here because it might be persistent and has not been - registered to persistent_list yet - */ - php_memc_destroy(intern->memc, memc_user_data); - intern->memc = NULL; - return; - } - } - - if (plist_key) { - zend_resource le; - - le.type = php_memc_list_entry(); - le.ptr = intern->memc; - - GC_SET_REFCOUNT(&le, 1); - - /* plist_key is not a persistent allocated key, thus we use str_update here */ - if (zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(plist_key), ZSTR_LEN(plist_key), &le, sizeof(le)) == NULL) { - zend_string_release(plist_key); - php_error_docref(NULL, E_ERROR, "could not register persistent entry"); - /* not reached */ - } - zend_string_release(plist_key); - } -} -/* }}} */ - - - -static -void s_hash_to_keys(php_memc_keys_t *keys_out, HashTable *hash_in, zend_bool preserve_order, zval *return_value) -{ - size_t idx = 0, alloc_count; - zval *zv; - - keys_out->num_valid_keys = 0; - - alloc_count = zend_hash_num_elements(hash_in); - if (!alloc_count) { - return; - } - keys_out->mkeys = ecalloc (alloc_count, sizeof (char *)); - keys_out->mkeys_len = ecalloc (alloc_count, sizeof (size_t)); - keys_out->strings = ecalloc (alloc_count, sizeof (zend_string *)); - - ZEND_HASH_FOREACH_VAL(hash_in, zv) { - zend_string *key = zval_get_string(zv); - - if (preserve_order && return_value) { - add_assoc_null_ex(return_value, ZSTR_VAL(key), ZSTR_LEN(key)); - } - - if (ZSTR_LEN(key) > 0 && ZSTR_LEN(key) < MEMCACHED_MAX_KEY) { - keys_out->mkeys[idx] = ZSTR_VAL(key); - keys_out->mkeys_len[idx] = ZSTR_LEN(key); - - keys_out->strings[idx] = key; - idx++; - } - else { - zend_string_release (key); - } - - } ZEND_HASH_FOREACH_END(); - - if (!idx) { - efree (keys_out->mkeys); - efree (keys_out->mkeys_len); - efree (keys_out->strings); - } - keys_out->num_valid_keys = idx; -} - -static -void s_key_to_keys(php_memc_keys_t *keys_out, zend_string *key) -{ - zval zv_keys; - - array_init(&zv_keys); - add_next_index_str(&zv_keys, zend_string_copy(key)); - - s_hash_to_keys(keys_out, Z_ARRVAL(zv_keys), 0, NULL); - zval_ptr_dtor(&zv_keys); -} - -static -void s_clear_keys(php_memc_keys_t *keys) -{ - size_t i; - - if (!keys->num_valid_keys) { - return; - } - - for (i = 0; i < keys->num_valid_keys; i++) { - zend_string_release (keys->strings[i]); - } - efree(keys->strings); - efree(keys->mkeys); - efree(keys->mkeys_len); -} - -typedef struct { - zend_bool extended; - zval *return_value; -} php_memc_get_ctx_t; - -static -zend_bool s_get_apply_fn(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) -{ - php_memc_get_ctx_t *context = (php_memc_get_ctx_t *) in_context; - - if (context->extended) { - Z_TRY_ADDREF_P(value); - Z_TRY_ADDREF_P(cas); - - array_init (context->return_value); - add_assoc_zval (context->return_value, "value", value); - add_assoc_zval (context->return_value, "cas", cas); - add_assoc_long (context->return_value, "flags", (zend_long) MEMC_VAL_GET_USER_FLAGS(flags)); - } - else { - ZVAL_COPY(context->return_value, value); - } - return 0; /* Stop after one */ -} - -static -void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) -{ - php_memc_get_ctx_t context = {0}; - php_memc_keys_t keys = {0}; - zend_long get_flags = 0; - zend_string *key; - zend_string *server_key = NULL; - zend_bool mget_status; - memcached_return status = MEMCACHED_SUCCESS; - zend_fcall_info fci = empty_fcall_info; - zend_fcall_info_cache fcc = empty_fcall_info_cache; - MEMC_METHOD_INIT_VARS; - - if (by_key) { - /* "SS|f!l" */ - ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_STR(server_key) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_FUNC_EX(fci, fcc, 1, 0) - Z_PARAM_LONG(get_flags) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "S|f!l" */ - ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_FUNC_EX(fci, fcc, 1, 0) - Z_PARAM_LONG(get_flags) - ZEND_PARSE_PARAMETERS_END(); - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - MEMC_CHECK_KEY(intern, key); - - context.extended = (get_flags & MEMC_GET_EXTENDED); - - context.return_value = return_value; - - s_key_to_keys(&keys, key); - mget_status = php_memc_mget_apply(intern, server_key, &keys, s_get_apply_fn, context.extended, &context); - s_clear_keys(&keys); - - if (!mget_status) { - if (s_memc_status_has_result_code(intern, MEMCACHED_NOTFOUND) && fci.size > 0) { - status = s_invoke_cache_callback(object, &fci, &fcc, context.extended, key, return_value); - - if (!status) { - zval_ptr_dtor(return_value); - RETURN_FROM_GET; - } - } - } - - if (s_memc_status_has_error(intern)) { - zval_ptr_dtor(return_value); - RETURN_FROM_GET; - } -} - -/* {{{ Memcached::get(string key [, mixed callback [, int get_flags = 0]) - Returns a value for the given key or false */ -PHP_METHOD(Memcached, get) -{ - php_memc_get_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ Memcached::getByKey(string server_key, string key [, mixed callback [, int get_flags = 0]) - Returns a value for key from the server identified by the server key or false */ -PHP_METHOD(Memcached, getByKey) -{ - php_memc_get_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -static -zend_bool s_get_multi_apply_fn(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) -{ - php_memc_get_ctx_t *context = (php_memc_get_ctx_t *) in_context; - - Z_TRY_ADDREF_P(value); - - if (context->extended) { - zval node; - - Z_TRY_ADDREF_P(cas); - - array_init(&node); - add_assoc_zval(&node, "value", value); - add_assoc_zval(&node, "cas", cas); - add_assoc_long(&node, "flags", (zend_long) MEMC_VAL_GET_USER_FLAGS(flags)); - - zend_symtable_update(Z_ARRVAL_P(context->return_value), key, &node); - } - else { - zend_symtable_update(Z_ARRVAL_P(context->return_value), key, value); - } - return 1; -} - -/* {{{ -- php_memc_getMulti_impl */ -static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) -{ - php_memc_get_ctx_t context; - php_memc_keys_t keys_out; - - zval *keys = NULL; - zend_string *server_key = NULL; - zend_long flags = 0; - MEMC_METHOD_INIT_VARS; - zend_bool retval, preserve_order; - - if (by_key) { - /* "Sa|l" */ - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STR(server_key) - Z_PARAM_ARRAY(keys) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(flags) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "a|l" */ - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY(keys) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(flags) - ZEND_PARSE_PARAMETERS_END(); - } - - MEMC_METHOD_FETCH_OBJECT; - - array_init(return_value); - if (zend_hash_num_elements(Z_ARRVAL_P(keys)) == 0) { - /* BC compatible */ - s_memc_set_status(intern, MEMCACHED_NOTFOUND, 0); - return; - } - - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - preserve_order = (flags & MEMC_GET_PRESERVE_ORDER); - s_hash_to_keys(&keys_out, Z_ARRVAL_P(keys), preserve_order, return_value); - - context.extended = (flags & MEMC_GET_EXTENDED); - context.return_value = return_value; - - retval = php_memc_mget_apply(intern, server_key, &keys_out, s_get_multi_apply_fn, context.extended, &context); - - s_clear_keys(&keys_out); - - if (!retval && (s_memc_status_has_result_code(intern, MEMCACHED_NOTFOUND) || s_memc_status_has_result_code(intern, MEMCACHED_SOME_ERRORS))) { - return; - } - - if (!retval || EG(exception)) { - zval_dtor(return_value); - RETURN_FROM_GET; - } -} -/* }}} */ - -/* {{{ Memcached::getMulti(array keys[, long flags = 0 ]) - Returns values for the given keys or false */ -PHP_METHOD(Memcached, getMulti) -{ - php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ Memcached::getMultiByKey(string server_key, array keys[, long flags = 0 ]) - Returns values for the given keys from the server identified by the server key or false */ -PHP_METHOD(Memcached, getMultiByKey) -{ - php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ Memcached::getDelayed(array keys [, bool with_cas [, mixed callback ] ]) - Sends a request for the given keys and returns immediately */ -PHP_METHOD(Memcached, getDelayed) -{ - php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ Memcached::getDelayedByKey(string server_key, array keys [, bool with_cas [, mixed callback ] ]) - Sends a request for the given keys from the server identified by the server key and returns immediately */ -PHP_METHOD(Memcached, getDelayedByKey) -{ - php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - - -static -void s_create_result_array(zend_string *key, zval *value, zval *cas, uint32_t flags, zval *return_value) -{ - Z_TRY_ADDREF_P(value); - Z_TRY_ADDREF_P(cas); - - add_assoc_str_ex(return_value, ZEND_STRL("key"), zend_string_copy(key)); - add_assoc_zval_ex(return_value, ZEND_STRL("value"), value); - - if (Z_LVAL_P(cas)) { - /* BC compatible */ - add_assoc_zval_ex(return_value, ZEND_STRL("cas"), cas); - add_assoc_long_ex(return_value, ZEND_STRL("flags"), MEMC_VAL_GET_USER_FLAGS(flags)); - } -} - -static -zend_bool s_result_callback_apply(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) -{ - zend_bool status = 1; - zval params[2]; - zval retval; - php_memc_result_callback_ctx_t *context = (php_memc_result_callback_ctx_t *) in_context; - - ZVAL_COPY(¶ms[0], context->object); - array_init(¶ms[1]); - - s_create_result_array(key, value, cas, flags, ¶ms[1]); - - context->fci.retval = &retval; - context->fci.params = params; - context->fci.param_count = 2; - - if (zend_call_function(&context->fci, &context->fcc) == FAILURE) { - php_error_docref(NULL, E_WARNING, "could not invoke result callback"); - status = 0; - } - - zval_ptr_dtor(&retval); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - - return status; -} - -/* {{{ -- php_memc_getDelayed_impl */ -static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) -{ - php_memc_keys_t keys_out = {0}; - - zval *keys = NULL; - zend_string *server_key = NULL; - zend_bool with_cas = 0; - - zend_fcall_info fci = empty_fcall_info; - zend_fcall_info_cache fcc = empty_fcall_info_cache; - memcached_return status = MEMCACHED_SUCCESS; - MEMC_METHOD_INIT_VARS; - - - if (by_key) { - /* "Sa/|bf!" */ - ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_STR(server_key) - Z_PARAM_ARRAY_EX(keys, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(with_cas) - Z_PARAM_FUNC_EX(fci, fcc, 1, 0) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "a/|bf!" */ - ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_ARRAY_EX(keys, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(with_cas) - Z_PARAM_FUNC_EX(fci, fcc, 1, 0) - ZEND_PARSE_PARAMETERS_END(); - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - s_hash_to_keys(&keys_out, Z_ARRVAL_P(keys), 0, NULL); - - if (fci.size > 0) { - php_memc_result_callback_ctx_t context = { - getThis(), fci, fcc - }; - status = php_memc_mget_apply(intern, server_key, &keys_out, &s_result_callback_apply, with_cas, (void *) &context); - } - else { - status = php_memc_mget_apply(intern, server_key, &keys_out, NULL, with_cas, NULL); - } - - s_clear_keys(&keys_out); - RETURN_BOOL(status); -} -/* }}} */ - -static -zend_bool s_fetch_apply(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) -{ - zval *return_value = (zval *) in_context; - s_create_result_array(key, value, cas, flags, return_value); - - return 0; // stop iterating after one -} - -/* {{{ Memcached::fetch() - Returns the next result from a previous delayed request */ -PHP_METHOD(Memcached, fetch) -{ - memcached_return status = MEMCACHED_SUCCESS; - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - array_init(return_value); - status = php_memc_result_apply(intern, s_fetch_apply, 1, return_value); - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - zval_ptr_dtor(return_value); - RETURN_FROM_GET; - } -} -/* }}} */ - -static -zend_bool s_fetch_all_apply(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) -{ - zval zv; - zval *return_value = (zval *) in_context; - - array_init (&zv); - s_create_result_array(key, value, cas, flags, &zv); - - add_next_index_zval(return_value, &zv); - return 1; -} - -/* {{{ Memcached::fetchAll() - Returns all the results from a previous delayed request */ -PHP_METHOD(Memcached, fetchAll) -{ - memcached_return status = MEMCACHED_SUCCESS; - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - array_init(return_value); - status = php_memc_result_apply(intern, s_fetch_all_apply, 0, return_value); - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - zval_dtor(return_value); - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ Memcached::set(string key, mixed value [, int expiration ]) - Sets the value for the given key */ -PHP_METHOD(Memcached, set) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_SET, 0); -} -/* }}} */ - -/* {{{ Memcached::setByKey(string server_key, string key, mixed value [, int expiration ]) - Sets the value for the given key on the server identified by the server key */ -PHP_METHOD(Memcached, setByKey) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_SET, 1); -} -/* }}} */ - -/* {{{ Memcached::touch(string key, [, int expiration ]) - Sets a new expiration for the given key */ -PHP_METHOD(Memcached, touch) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 0); -} -/* }}} */ - -/* {{{ Memcached::touchbyKey(string key, [, int expiration ]) - Sets a new expiration for the given key */ -PHP_METHOD(Memcached, touchByKey) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 1); -} -/* }}} */ - -/* {{{ Memcached::setMulti(array items [, int expiration ]) - Sets the keys/values specified in the items array */ -PHP_METHOD(Memcached, setMulti) -{ - php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ Memcached::setMultiByKey(string server_key, array items [, int expiration ]) - Sets the keys/values specified in the items array on the server identified by the given server key */ -PHP_METHOD(Memcached, setMultiByKey) -{ - php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ -- php_memc_setMulti_impl */ -static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) -{ - zval *entries; - zend_string *server_key = NULL; - zend_long expiration = 0, ignored; - zval *value; - zend_string *skey; - zend_ulong num_key; - int tmp_len = 0; - MEMC_METHOD_INIT_VARS; - - if (by_key) { - /* "Sa|ll" */ - ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_STR(server_key) - Z_PARAM_ARRAY(entries) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "a|ll" */ - ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_ARRAY(entries) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) - ZEND_PARSE_PARAMETERS_END(); - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P(entries), num_key, skey, value) { - zend_string *str_key = NULL; - - if (skey) { - str_key = skey; - } - else { - char tmp_key[64]; - - tmp_len = snprintf(tmp_key, sizeof(tmp_key) - 1, "%ld", (long)num_key); - str_key = zend_string_init(tmp_key, tmp_len, 0); - } - - if (!s_memc_write_zval (intern, MEMC_OP_SET, server_key, str_key, value, expiration)) { - php_error_docref(NULL, E_WARNING, "failed to set key %s", ZSTR_VAL(str_key)); - } - - if (!skey) { - zend_string_release (str_key); - } - - } ZEND_HASH_FOREACH_END(); - - RETURN_BOOL(!s_memc_status_has_error(intern)); -} -/* }}} */ - -/* {{{ Memcached::add(string key, mixed value [, int expiration ]) - Sets the value for the given key, failing if the key already exists */ -PHP_METHOD(Memcached, add) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_ADD, 0); -} -/* }}} */ - -/* {{{ Memcached::addByKey(string server_key, string key, mixed value [, int expiration ]) - Sets the value for the given key on the server identified by the sever key, failing if the key already exists */ -PHP_METHOD(Memcached, addByKey) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_ADD, 1); -} -/* }}} */ - -/* {{{ Memcached::append(string key, mixed value) - Appends the value to existing one for the key */ -PHP_METHOD(Memcached, append) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_APPEND, 0); -} -/* }}} */ - -/* {{{ Memcached::appendByKey(string server_key, string key, mixed value) - Appends the value to existing one for the key on the server identified by the server key */ -PHP_METHOD(Memcached, appendByKey) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_APPEND, 1); -} -/* }}} */ - -/* {{{ Memcached::prepend(string key, mixed value) - Prepends the value to existing one for the key */ -PHP_METHOD(Memcached, prepend) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_PREPEND, 0); -} -/* }}} */ - -/* {{{ Memcached::prependByKey(string server_key, string key, mixed value) - Prepends the value to existing one for the key on the server identified by the server key */ -PHP_METHOD(Memcached, prependByKey) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_PREPEND, 1); -} -/* }}} */ - -/* {{{ Memcached::replace(string key, mixed value [, int expiration ]) - Replaces the value for the given key, failing if the key doesn't exist */ -PHP_METHOD(Memcached, replace) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_REPLACE, 0); -} -/* }}} */ - -/* {{{ Memcached::replaceByKey(string server_key, string key, mixed value [, int expiration ]) - Replaces the value for the given key on the server identified by the server key, failing if the key doesn't exist */ -PHP_METHOD(Memcached, replaceByKey) -{ - php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_REPLACE, 1); -} -/* }}} */ - -/* {{{ -- php_memc_store_impl */ -static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool by_key) -{ - zend_string *key; - zend_string *server_key = NULL; - zend_string *s_value; - zval s_zvalue; - zval *value = NULL; - zend_long expiration = 0; - MEMC_METHOD_INIT_VARS; - - if (by_key) { - if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { - /* "SSS" */ - ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_STR(server_key) - Z_PARAM_STR(key) - Z_PARAM_STR(s_value) - ZEND_PARSE_PARAMETERS_END(); - value = &s_zvalue; - ZVAL_STR(value, s_value); - } else if (op == MEMC_OP_TOUCH) { - /* "SS|l" */ - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STR(server_key) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "SSz|l" */ - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_STR(server_key) - Z_PARAM_STR(key) - Z_PARAM_ZVAL(value) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - } - } else { - if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { - /* "SS" */ - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STR(key) - Z_PARAM_STR(s_value) - ZEND_PARSE_PARAMETERS_END(); - value = &s_zvalue; - ZVAL_STR(value, s_value); - } else if (op == MEMC_OP_TOUCH) { - /* "S|l */ - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "Sz|l" */ - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STR(key) - Z_PARAM_ZVAL(value) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - } - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - MEMC_CHECK_KEY(intern, key); - - if (memc_user_data->compression_enabled) { - /* - * When compression is enabled, we cannot do appends/prepends because that would - * corrupt the compressed values. It is up to the user to fetch the value, - * append/prepend new data, and store it again. - */ - if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { - php_error_docref(NULL, E_WARNING, "cannot append/prepend with compression turned on"); - RETURN_NULL(); - } - } - - if (!s_memc_write_zval (intern, op, server_key, key, value, expiration)) { - RETURN_FALSE; - } - RETURN_TRUE; -} -/* }}} */ - -/* {{{ -- php_memc_cas_impl */ -static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) -{ - zval *zv_cas; - uint64_t cas; - zend_string *key; - zend_string *server_key = NULL; - zval *value; - zend_long expiration = 0; - zend_long ignored; - zend_string *payload; - uint32_t flags = 0; - memcached_return status; - MEMC_METHOD_INIT_VARS; - - if (by_key) { - /* "zSSz|ll" */ - ZEND_PARSE_PARAMETERS_START(4, 6) - Z_PARAM_ZVAL(zv_cas) - Z_PARAM_STR(server_key) - Z_PARAM_STR(key) - Z_PARAM_ZVAL(value) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "zSz|ll" */ - ZEND_PARSE_PARAMETERS_START(3, 5) - Z_PARAM_ZVAL(zv_cas) - Z_PARAM_STR(key) - Z_PARAM_ZVAL(value) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) - ZEND_PARSE_PARAMETERS_END(); - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - MEMC_CHECK_KEY(intern, key); - - cas = s_zval_to_uint64(zv_cas); - - payload = s_zval_to_payload(intern, value, &flags); - if (payload == NULL) { - intern->rescode = MEMC_RES_PAYLOAD_FAILURE; - RETURN_FALSE; - } - - if (by_key) { - status = memcached_cas_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags, cas); - } else { - status = memcached_cas(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags, cas); - } - - zend_string_release(payload); - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Memcached::cas(double cas_token, string key, mixed value [, int expiration ]) - Sets the value for the given key, failing if the cas_token doesn't match the one in memcache */ -PHP_METHOD(Memcached, cas) -{ - php_memc_cas_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ Memcached::casByKey(double cas_token, string server_key, string key, mixed value [, int expiration ]) - Sets the value for the given key on the server identified by the server_key, failing if the cas_token doesn't match the one in memcache */ -PHP_METHOD(Memcached, casByKey) -{ - php_memc_cas_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ Memcached::delete(string key [, int time ]) - Deletes the given key */ -PHP_METHOD(Memcached, delete) -{ - php_memc_delete_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ Memcached::deleteMulti(array keys [, int time ]) - Deletes the given keys */ -PHP_METHOD(Memcached, deleteMulti) -{ - php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ Memcached::deleteByKey(string server_key, string key [, int time ]) - Deletes the given key from the server identified by the server key */ -PHP_METHOD(Memcached, deleteByKey) -{ - php_memc_delete_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ Memcached::deleteMultiByKey(array keys [, int time ]) - Deletes the given key from the server identified by the server key */ -PHP_METHOD(Memcached, deleteMultiByKey) -{ - php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ -- php_memc_delete_impl */ -static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) -{ - zend_string *key, *server_key; - zend_long expiration = 0; - memcached_return status; - MEMC_METHOD_INIT_VARS; - - if (by_key) { - /* "SS|l" */ - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STR(server_key) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "S|l" */ - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - server_key = key; - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - MEMC_CHECK_KEY(intern, key); - - if (by_key) { - status = memcached_delete_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), - ZSTR_LEN(key), expiration); - } else { - status = memcached_delete(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), expiration); - } - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ -- php_memc_deleteMulti_impl */ -static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) -{ - zval *entries, *zv, ret; - zend_string *server_key = NULL; - zend_long expiration = 0; - zend_string *entry; - - memcached_return status; - MEMC_METHOD_INIT_VARS; - - if (by_key) { - /* "Sa/|l" */ - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STR(server_key) - Z_PARAM_ARRAY_EX(entries, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "a/|l" */ - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY_EX(entries, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(expiration) - ZEND_PARSE_PARAMETERS_END(); - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - array_init(return_value); - ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P(entries), zv) { - entry = zval_get_string(zv); - - if (ZSTR_LEN(entry) == 0) { - zend_string_release(entry); - continue; - } - - if (by_key) { - status = memcached_delete_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(entry), ZSTR_LEN(entry), expiration); - } else { - status = memcached_delete_by_key(intern->memc, ZSTR_VAL(entry), ZSTR_LEN(entry), ZSTR_VAL(entry), ZSTR_LEN(entry), expiration); - } - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - ZVAL_LONG(&ret, status); - } else { - ZVAL_TRUE(&ret); - } - zend_symtable_update(Z_ARRVAL_P(return_value), entry, &ret); - zend_string_release(entry); - } ZEND_HASH_FOREACH_END(); - - return; -} -/* }}} */ - -/* {{{ -- php_memc_incdec_impl */ -static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, zend_bool incr) -{ - zend_string *key, *server_key = NULL; - zend_long offset = 1; - zend_long expiry = 0; - zend_long initial = 0; - uint64_t value = UINT64_MAX; - memcached_return status; - int n_args = ZEND_NUM_ARGS(); - - MEMC_METHOD_INIT_VARS; - - if (!by_key) { - /* "S|lll" */ - ZEND_PARSE_PARAMETERS_START(1, 4) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(offset) - Z_PARAM_LONG(initial) - Z_PARAM_LONG(expiry) - ZEND_PARSE_PARAMETERS_END(); - } else { - /* "SS|lll" */ - ZEND_PARSE_PARAMETERS_START(2, 5) - Z_PARAM_STR(server_key) - Z_PARAM_STR(key) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(offset) - Z_PARAM_LONG(initial) - Z_PARAM_LONG(expiry) - ZEND_PARSE_PARAMETERS_END(); - } - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - MEMC_CHECK_KEY(intern, key); - - if (offset < 0) { - php_error_docref(NULL, E_WARNING, "offset cannot be a negative value"); - RETURN_FALSE; - } - - if ((!by_key && n_args < 3) || (by_key && n_args < 4)) { - if (by_key) { - if (incr) { - status = memcached_increment_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); - } else { - status = memcached_decrement_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); - } - } else { - /* The libmemcached API has a quirk that memcached_increment() takes only a 32-bit - * offset, but memcached_increment_by_key() and all other increment and decrement - * functions take a 64-bit offset. The memcached protocol allows increment/decrement - * greater than UINT_MAX, so we just work around memcached_increment() here. - */ - if (incr) { - status = memcached_increment_by_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); - } else { - status = memcached_decrement_by_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); - } - } - - } else { - zend_long retries = memc_user_data->store_retry_count; - -retry_inc_dec: - if (!memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { - php_error_docref(NULL, E_WARNING, "Initial value is only supported with binary protocol"); - RETURN_FALSE; - } - if (by_key) { - if (incr) { - status = memcached_increment_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); - } else { - status = memcached_decrement_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); - } - } else { - if (incr) { - status = memcached_increment_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); - } else { - status = memcached_decrement_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); - } - } - if (s_should_retry_write(intern, status) && retries-- > 0) { - goto retry_inc_dec; - } - } - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - if (value == UINT64_MAX) { - RETURN_FALSE; - } - - RETURN_LONG((long)value); -} -/* }}} */ - -/* {{{ Memcached::increment(string key [, int delta [, initial_value [, expiry time ] ] ]) - Increments the value for the given key by delta, defaulting to 1 */ -PHP_METHOD(Memcached, increment) -{ - php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1); -} -/* }}} */ - -/* {{{ Memcached::decrement(string key [, int delta [, initial_value [, expiry time ] ] ]) - Decrements the value for the given key by delta, defaulting to 1 */ -PHP_METHOD(Memcached, decrement) -{ - php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0); -} -/* }}} */ - -/* {{{ Memcached::decrementByKey(string server_key, string key [, int delta [, initial_value [, expiry time ] ] ]) - Decrements by server the value for the given key by delta, defaulting to 1 */ -PHP_METHOD(Memcached, decrementByKey) -{ - php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0); -} -/* }}} */ - -/* {{{ Memcached::increment(string server_key, string key [, int delta [, initial_value [, expiry time ] ] ]) - Increments by server the value for the given key by delta, defaulting to 1 */ -PHP_METHOD(Memcached, incrementByKey) -{ - php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 1); -} -/* }}} */ - -/* {{{ Memcached::addServer(string hostname, int port [, int weight ]) - Adds the given memcache server to the list */ -PHP_METHOD(Memcached, addServer) -{ - zend_string *host; - zend_long port, weight = 0; - memcached_return status; - MEMC_METHOD_INIT_VARS; - - /* "Sa/|l" */ - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STR(host) - Z_PARAM_LONG(port) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(weight) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - status = memcached_server_add_with_weight(intern->memc, ZSTR_VAL(host), port, weight); - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Memcached::addServers(array servers) - Adds the given memcache servers to the server list */ -PHP_METHOD(Memcached, addServers) -{ - zval *servers; - zval *entry; - zval *z_host, *z_port, *z_weight = NULL; - HashPosition pos; - int entry_size, i = 0; - memcached_server_st *list = NULL; - memcached_return status; - MEMC_METHOD_INIT_VARS; - - /* "a/" */ - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY_EX(servers, 0, 1) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P(servers), entry) { - if (Z_TYPE_P(entry) != IS_ARRAY) { - php_error_docref(NULL, E_WARNING, "server list entry #%d is not an array", i+1); - i++; - continue; - } - - entry_size = zend_hash_num_elements(Z_ARRVAL_P(entry)); - - if (entry_size > 1) { - zend_string *host; - zend_long port; - uint32_t weight; - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos); - - /* Check that we have a host */ - if ((z_host = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) == NULL) { - php_error_docref(NULL, E_WARNING, "could not get server host for entry #%d", i+1); - i++; - continue; - } - - /* Check that we have a port */ - if (zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos) == FAILURE || - (z_port = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) == NULL) { - php_error_docref(NULL, E_WARNING, "could not get server port for entry #%d", i+1); - i++; - continue; - } - - host = zval_get_string(z_host); - port = zval_get_long(z_port); - - weight = 0; - if (entry_size > 2) { - /* Try to get weight */ - if (zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos) == FAILURE || - (z_weight = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) == NULL) { - php_error_docref(NULL, E_WARNING, "could not get server weight for entry #%d", i+1); - } - - weight = zval_get_long(z_weight); - } - - list = memcached_server_list_append_with_weight(list, ZSTR_VAL(host), port, weight, &status); - - zend_string_release(host); - - if (s_memc_status_handle_result_code(intern, status) == SUCCESS) { - i++; - continue; - } - } - i++; - /* catch-all for all errors */ - php_error_docref(NULL, E_WARNING, "could not add entry #%d to the server list", i + 1); - } ZEND_HASH_FOREACH_END(); - - status = memcached_server_push(intern->memc, list); - memcached_server_list_free(list); - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Memcached::getServerList() - Returns the list of the memcache servers in use */ -PHP_METHOD(Memcached, getServerList) -{ - memcached_server_function callbacks[1]; - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - callbacks[0] = s_server_cursor_list_servers_cb; - array_init(return_value); - memcached_server_cursor(intern->memc, callbacks, return_value, 1); -} -/* }}} */ - -/* {{{ Memcached::getServerByKey(string server_key) - Returns the server identified by the given server key */ -PHP_METHOD(Memcached, getServerByKey) -{ - zend_string *server_key; - php_memcached_instance_st server_instance; - memcached_return error; - MEMC_METHOD_INIT_VARS; - - /* "S" */ - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(server_key) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - server_instance = memcached_server_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), &error); - if (server_instance == NULL) { - s_memc_status_handle_result_code(intern, error); - RETURN_FALSE; - } - - array_init(return_value); - add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance)); - add_assoc_long(return_value, "port", memcached_server_port(server_instance)); - add_assoc_long(return_value, "weight", 0); -} -/* }}} */ - -/* {{{ Memcached::resetServerList() - Reset the server list in use */ -PHP_METHOD(Memcached, resetServerList) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - memcached_servers_reset(intern->memc); - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Memcached::quit() - Close any open connections */ -PHP_METHOD(Memcached, quit) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - memcached_quit(intern->memc); - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Memcached::flushBuffers() - Flush and senf buffered commands */ -PHP_METHOD(Memcached, flushBuffers) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - RETURN_BOOL(memcached_flush_buffers(intern->memc) == MEMCACHED_SUCCESS); -} -/* }}} */ - -/* {{{ Memcached::getLastErrorMessage() - Returns the last error message that occurred */ -PHP_METHOD(Memcached, getLastErrorMessage) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - RETURN_STRING(memcached_last_error_message(intern->memc)); -} -/* }}} */ - -/* {{{ Memcached::getLastErrorCode() - Returns the last error code that occurred */ -PHP_METHOD(Memcached, getLastErrorCode) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - RETURN_LONG(memcached_last_error(intern->memc)); -} -/* }}} */ - -/* {{{ Memcached::getLastErrorErrno() - Returns the last error errno that occurred */ -PHP_METHOD(Memcached, getLastErrorErrno) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - RETURN_LONG(memcached_last_error_errno(intern->memc)); -} -/* }}} */ - -/* {{{ Memcached::getLastDisconnectedServer() - Returns the last disconnected server - Was added in 0.34 according to libmemcached's Changelog */ -PHP_METHOD(Memcached, getLastDisconnectedServer) -{ - php_memcached_instance_st server_instance; - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - server_instance = memcached_server_get_last_disconnect(intern->memc); - if (server_instance == NULL) { - RETURN_FALSE; - } - - array_init(return_value); - add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance)); - add_assoc_long(return_value, "port", memcached_server_port(server_instance)); -} -/* }}} */ - - - -static -zend_bool s_long_value(const char *str, zend_long *value) -{ - char *end = (char *) str; - - errno = 0; - *value = strtol(str, &end, 10); - - if (errno || str == end || *end != '\0') { - return 0; - } - return 1; -} - -static -zend_bool s_double_value(const char *str, double *value) -{ - char *end = (char *) str; - - errno = 0; - *value = strtod(str, &end); - - if (errno || str == end || *end != '\0') { - return 0; - } - return 1; -} - -static -memcached_return s_stat_execute_cb (php_memcached_instance_st instance, const char *key, size_t key_length, const char *value, size_t value_length, void *context) -{ - zend_string *server_key; - zend_long long_val; - double d_val; - char *buffer; - - zval *return_value = (zval *) context; - zval *server_values; - - server_key = strpprintf(0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance)); - server_values = zend_hash_find(Z_ARRVAL_P(return_value), server_key); - - if (!server_values) { - zval zv; - array_init(&zv); - - server_values = zend_hash_add(Z_ARRVAL_P(return_value), server_key, &zv); - } - - spprintf (&buffer, 0, "%.*s", (int)value_length, value); - - /* Check type */ - if (s_long_value (buffer, &long_val)) { - add_assoc_long(server_values, key, long_val); - } - else if (s_double_value (buffer, &d_val)) { - add_assoc_double(server_values, key, d_val); - } - else { - add_assoc_stringl_ex(server_values, key, key_length, (char*)value, value_length); - } - efree (buffer); - zend_string_release(server_key); - - return MEMCACHED_SUCCESS; -} - -/* {{{ Memcached::getStats() - Returns statistics for the memcache servers */ -PHP_METHOD(Memcached, getStats) -{ - memcached_return status; - char *args = NULL; - zend_string *args_string = NULL; - uint64_t orig_no_block, orig_protocol; - MEMC_METHOD_INIT_VARS; - - /* "|S!" */ - ZEND_PARSE_PARAMETERS_START(0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_STR_EX(args_string, 1, 0) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - - if (args_string) - args = ZSTR_VAL(args_string); - - /* stats hangs in nonblocking mode, turn off during the call. Only change the - * value if needed, because libmemcached reconnects for this behavior_set. */ - orig_no_block = memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK); - orig_protocol = memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL); - if (orig_no_block && orig_protocol) - memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0); - - array_init(return_value); - status = memcached_stat_execute(intern->memc, args, s_stat_execute_cb, return_value); - - if (orig_no_block && orig_protocol) - memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK, orig_no_block); - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - zval_ptr_dtor(return_value); - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ Memcached::getVersion() - Returns the version of each memcached server in the pool */ -PHP_METHOD(Memcached, getVersion) -{ - memcached_return status; - memcached_server_function callbacks[1]; - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - status = memcached_version(intern->memc); - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - callbacks[0] = s_server_cursor_version_cb; - - array_init(return_value); - status = memcached_server_cursor(intern->memc, callbacks, return_value, 1); - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - zval_dtor(return_value); - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ Memcached::getAllKeys() - Returns the keys stored on all the servers */ -static -memcached_return s_dump_keys_cb(const memcached_st *ptr, const char *key, size_t key_length, void *in_context) -{ - zval *return_value = (zval*) in_context; - add_next_index_stringl(return_value, key, key_length); - - return MEMCACHED_SUCCESS; -} - -PHP_METHOD(Memcached, getAllKeys) -{ - memcached_return rc; - memcached_dump_func callback[1]; - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - callback[0] = s_dump_keys_cb; - MEMC_METHOD_FETCH_OBJECT; - - array_init(return_value); - - rc = memcached_dump(intern->memc, callback, return_value, 1); - - /* Ignore two errors. libmemcached has a hardcoded loop of 200 slab - * classes that matches memcached < 1.4.24, at which version the server - * has only 63 slabs and throws an error when requesting the 64th slab. - * - * In multi-server some non-deterministic number of elements will be dropped. - */ - if (rc != MEMCACHED_CLIENT_ERROR && rc != MEMCACHED_SERVER_ERROR - && s_memc_status_handle_result_code(intern, rc) == FAILURE) { - zval_dtor(return_value); - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ Memcached::flush([ int delay ]) - Flushes the data on all the servers */ -static PHP_METHOD(Memcached, flush) -{ - zend_long delay = 0; - memcached_return status; - MEMC_METHOD_INIT_VARS; - - /* "|l" */ - ZEND_PARSE_PARAMETERS_START(0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(delay) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); - - status = memcached_flush(intern->memc, delay); - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Memcached::getOption(int option) - Returns the value for the given option constant */ -static PHP_METHOD(Memcached, getOption) -{ - zend_long option; - uint64_t result; - memcached_behavior flag; - MEMC_METHOD_INIT_VARS; - - /* "l" */ - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(option) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - - switch (option) { - case MEMC_OPT_COMPRESSION_TYPE: - RETURN_LONG(memc_user_data->compression_type); - - case MEMC_OPT_COMPRESSION: - RETURN_BOOL(memc_user_data->compression_enabled); - - case MEMC_OPT_PREFIX_KEY: - { - memcached_return retval; - char *result; - - result = memcached_callback_get(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval); - if (retval == MEMCACHED_SUCCESS && result) { - RETURN_STRING(result); - } else { - RETURN_EMPTY_STRING(); - } - } - - case MEMC_OPT_SERIALIZER: - RETURN_LONG((long)memc_user_data->serializer); - break; - - case MEMC_OPT_USER_FLAGS: - RETURN_LONG(memc_user_data->set_udf_flags); - break; - - case MEMC_OPT_STORE_RETRY_COUNT: - RETURN_LONG((long)memc_user_data->store_retry_count); - break; - - case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: - case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: - if (memcached_server_count(intern->memc) == 0) { - php_error_docref(NULL, E_WARNING, "no servers defined"); - return; - } - - default: - /* - * Assume that it's a libmemcached behavior option. - */ - flag = (memcached_behavior) option; - result = memcached_behavior_get(intern->memc, flag); - RETURN_LONG((long)result); - } -} -/* }}} */ - -static -int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) -{ - zend_long lval; - memcached_return rc = MEMCACHED_FAILURE; - memcached_behavior flag; - php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); - - switch (option) { - case MEMC_OPT_COMPRESSION: - memc_user_data->compression_enabled = zval_get_long(value) ? 1 : 0; - break; - - case MEMC_OPT_COMPRESSION_TYPE: - lval = zval_get_long(value); - if (lval == COMPRESSION_TYPE_FASTLZ || - lval == COMPRESSION_TYPE_ZLIB) { - memc_user_data->compression_type = lval; - } else { - /* invalid compression type */ - intern->rescode = MEMCACHED_INVALID_ARGUMENTS; - return 0; - } - break; - - case MEMC_OPT_PREFIX_KEY: - { - zend_string *str; - char *key; - str = zval_get_string(value); - if (ZSTR_LEN(str) == 0) { - key = NULL; - } else { - key = ZSTR_VAL(str); - } - if (memcached_callback_set(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, key) == MEMCACHED_BAD_KEY_PROVIDED) { - zend_string_release(str); - intern->rescode = MEMCACHED_INVALID_ARGUMENTS; - php_error_docref(NULL, E_WARNING, "bad key provided"); - return 0; - } - zend_string_release(str); - } - break; - - case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED: - flag = (memcached_behavior) option; - - lval = zval_get_long(value); - rc = memcached_behavior_set(intern->memc, flag, (uint64_t)lval); - - if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { - php_error_docref(NULL, E_WARNING, "error setting memcached option: %s", memcached_strerror (intern->memc, rc)); - return 0; - } - - /* - * This is necessary because libmemcached does not reset hash/distribution - * options on false case, like it does for MEMCACHED_BEHAVIOR_KETAMA - * (non-weighted) case. We have to clean up ourselves. - */ - if (!lval) { - (void)memcached_behavior_set_key_hash(intern->memc, MEMCACHED_HASH_DEFAULT); - (void)memcached_behavior_set_distribution_hash(intern->memc, MEMCACHED_HASH_DEFAULT); - (void)memcached_behavior_set_distribution(intern->memc, MEMCACHED_DISTRIBUTION_MODULA); - } - break; - - case MEMC_OPT_SERIALIZER: - { - lval = zval_get_long(value); - /* igbinary serializer */ -#ifdef HAVE_MEMCACHED_IGBINARY - if (lval == SERIALIZER_IGBINARY) { - memc_user_data->serializer = SERIALIZER_IGBINARY; - } else -#endif -#ifdef HAVE_JSON_API - if (lval == SERIALIZER_JSON) { - memc_user_data->serializer = SERIALIZER_JSON; - } else if (lval == SERIALIZER_JSON_ARRAY) { - memc_user_data->serializer = SERIALIZER_JSON_ARRAY; - } else -#endif - /* msgpack serializer */ -#ifdef HAVE_MEMCACHED_MSGPACK - if (lval == SERIALIZER_MSGPACK) { - memc_user_data->serializer = SERIALIZER_MSGPACK; - } else -#endif - /* php serializer */ - if (lval == SERIALIZER_PHP) { - memc_user_data->serializer = SERIALIZER_PHP; - } else { - memc_user_data->serializer = SERIALIZER_PHP; - intern->rescode = MEMCACHED_INVALID_ARGUMENTS; - php_error_docref(NULL, E_WARNING, "invalid serializer provided"); - return 0; - } - break; - } - - case MEMC_OPT_USER_FLAGS: - lval = zval_get_long(value); - - if (lval < 0) { - memc_user_data->set_udf_flags = -1; - return 1; - } - - if (lval > MEMC_VAL_USER_FLAGS_MAX) { - php_error_docref(NULL, E_WARNING, "MEMC_OPT_USER_FLAGS must be < %u", MEMC_VAL_USER_FLAGS_MAX); - return 0; - } - memc_user_data->set_udf_flags = lval; - break; - - case MEMC_OPT_STORE_RETRY_COUNT: - lval = zval_get_long(value); - memc_user_data->store_retry_count = lval; - break; - - default: - /* - * Assume that it's a libmemcached behavior option. - */ - if (option < 0) { - rc = MEMCACHED_INVALID_ARGUMENTS; - } - else { - flag = (memcached_behavior) option; - lval = zval_get_long(value); - - if (flag < MEMCACHED_BEHAVIOR_MAX) { - rc = memcached_behavior_set(intern->memc, flag, (uint64_t)lval); - } - else { - rc = MEMCACHED_INVALID_ARGUMENTS; - } - } - - if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { - php_error_docref(NULL, E_WARNING, "error setting memcached option: %s", memcached_strerror (intern->memc, rc)); - return 0; - } - break; - } - return 1; -} - -static -uint32_t *s_zval_to_uint32_array (zval *input, size_t *num_elements) -{ - zval *pzval; - uint32_t *retval; - size_t i = 0; - - *num_elements = zend_hash_num_elements(Z_ARRVAL_P(input)); - - if (!*num_elements) { - return NULL; - } - - retval = ecalloc(*num_elements, sizeof(uint32_t)); - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), pzval) { - zend_long value = 0; - - value = zval_get_long(pzval); - if (value < 0) { - php_error_docref(NULL, E_WARNING, "the map must contain positive integers"); - efree (retval); - *num_elements = 0; - return NULL; - } - retval [i] = (uint32_t) value; - i++; - } ZEND_HASH_FOREACH_END(); - return retval; -} - -/* {{{ Memcached::setBucket(array host_map, array forward_map, integer replicas) - Sets the memcached virtual buckets */ - -PHP_METHOD(Memcached, setBucket) -{ - zval *zserver_map; - zval *zforward_map = NULL; - zend_long replicas = 0; - zend_bool retval = 1; - - uint32_t *server_map = NULL, *forward_map = NULL; - size_t server_map_len = 0, forward_map_len = 0; - memcached_return rc; - MEMC_METHOD_INIT_VARS; - - /* "aa!l" */ - ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_ARRAY(zserver_map) - Z_PARAM_ARRAY_EX(zforward_map, 1, 0) - Z_PARAM_LONG(replicas) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - - if (zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) == 0) { - php_error_docref(NULL, E_WARNING, "server map cannot be empty"); - RETURN_FALSE; - } - - if (zforward_map && zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) != zend_hash_num_elements (Z_ARRVAL_P(zforward_map))) { - php_error_docref(NULL, E_WARNING, "forward_map length must match the server_map length"); - RETURN_FALSE; - } - - if (replicas < 0) { - php_error_docref(NULL, E_WARNING, "replicas must be larger than zero"); - RETURN_FALSE; - } - - server_map = s_zval_to_uint32_array (zserver_map, &server_map_len); - - if (!server_map) { - RETURN_FALSE; - } - - if (zforward_map) { - forward_map = s_zval_to_uint32_array (zforward_map, &forward_map_len); - - if (!forward_map) { - efree (server_map); - RETURN_FALSE; - } - } - - rc = memcached_bucket_set (intern->memc, server_map, forward_map, (uint32_t) server_map_len, replicas); - - if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { - retval = 0; - } - - efree(server_map); - - if (forward_map) { - efree(forward_map); - } - RETURN_BOOL(retval); -} -/* }}} */ - -/* {{{ Memcached::setOptions(array options) - Sets the value for the given option constant */ -static PHP_METHOD(Memcached, setOptions) -{ - zval *options; - zend_bool ok = 1; - zend_string *key; - ulong key_index; - zval *value; - - MEMC_METHOD_INIT_VARS; - - /* "a" */ - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY(options) - ZEND_PARSE_PARAMETERS_END(); - - - MEMC_METHOD_FETCH_OBJECT; - - ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(options), key_index, key, value) { - if (key) { - php_error_docref(NULL, E_WARNING, "invalid configuration option"); - ok = 0; - } else { - if (!php_memc_set_option(intern, (long) key_index, value)) { - ok = 0; - } - } - } ZEND_HASH_FOREACH_END(); - - RETURN_BOOL(ok); -} -/* }}} */ - -/* {{{ Memcached::setOption(int option, mixed value) - Sets the value for the given option constant */ -static PHP_METHOD(Memcached, setOption) -{ - zend_long option; - zval *value; - MEMC_METHOD_INIT_VARS; - - /* "lz/" */ - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_LONG(option) - Z_PARAM_ZVAL_EX(value, 0, 1) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - - RETURN_BOOL(php_memc_set_option(intern, option, value)); -} -/* }}} */ - -#ifdef HAVE_MEMCACHED_SASL -/* {{{ Memcached::setSaslAuthData(string user, string pass) - Sets sasl credentials */ -static PHP_METHOD(Memcached, setSaslAuthData) -{ - MEMC_METHOD_INIT_VARS; - memcached_return status; - zend_string *user, *pass; - - /* "SS/" */ - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STR(user) - Z_PARAM_STR(pass) - ZEND_PARSE_PARAMETERS_END(); - - if (!php_memc_init_sasl_if_needed()) { - RETURN_FALSE; - } - - MEMC_METHOD_FETCH_OBJECT; - - if (!memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { - php_error_docref(NULL, E_WARNING, "SASL is only supported with binary protocol"); - RETURN_FALSE; - } - memc_user_data->has_sasl_data = 1; - status = memcached_set_sasl_auth_data(intern->memc, ZSTR_VAL(user), ZSTR_VAL(pass)); - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - RETURN_TRUE; -} -/* }}} */ -#endif /* HAVE_MEMCACHED_SASL */ - -#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY -/* {{{ Memcached::setEncodingKey(string key) - Sets AES encryption key (libmemcached 1.0.6 and higher) */ -static PHP_METHOD(Memcached, setEncodingKey) -{ - MEMC_METHOD_INIT_VARS; - memcached_return status; - zend_string *key; - - /* "S" */ - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(key) - ZEND_PARSE_PARAMETERS_END(); - - MEMC_METHOD_FETCH_OBJECT; - - // libmemcached < 1.0.18 cannot handle a change of encoding key. Warn about this and return false. -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 - if (memc_user_data->encoding_enabled) { - php_error_docref(NULL, E_WARNING, "libmemcached versions less than 1.0.18 cannot change encoding key"); - RETURN_FALSE; - } -#endif - - status = memcached_set_encoding_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key)); - - if (s_memc_status_handle_result_code(intern, status) == FAILURE) { - RETURN_FALSE; - } - - memc_user_data->encoding_enabled = 1; - RETURN_TRUE; -} -/* }}} */ -#endif /* HAVE_MEMCACHED_SET_ENCODING_KEY */ - -/* {{{ Memcached::getResultCode() - Returns the result code from the last operation */ -static PHP_METHOD(Memcached, getResultCode) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - RETURN_LONG(intern->rescode); -} -/* }}} */ - -/* {{{ Memcached::getResultMessage() - Returns the result message from the last operation */ -static PHP_METHOD(Memcached, getResultMessage) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - switch (intern->rescode) { - case MEMC_RES_PAYLOAD_FAILURE: - RETURN_STRING("PAYLOAD FAILURE"); - break; - - case MEMCACHED_ERRNO: - case MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE: - case MEMCACHED_UNKNOWN_READ_FAILURE: - if (intern->memc_errno) { - zend_string *str = strpprintf(0, "%s: %s", - memcached_strerror(intern->memc, (memcached_return)intern->rescode), strerror(intern->memc_errno)); - RETURN_STR(str); - } - /* Fall through */ - default: - RETURN_STRING(memcached_strerror(intern->memc, (memcached_return)intern->rescode)); - break; - } - -} -/* }}} */ - -/* {{{ Memcached::isPersistent() - Returns the true if instance uses a persistent connection */ -static PHP_METHOD(Memcached, isPersistent) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - RETURN_BOOL(memc_user_data->is_persistent); -} -/* }}} */ - -/* {{{ Memcached::isPristine() - Returns the true if instance is recently created */ -static PHP_METHOD(Memcached, isPristine) -{ - MEMC_METHOD_INIT_VARS; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - MEMC_METHOD_FETCH_OBJECT; - - RETURN_BOOL(intern->is_pristine); -} -/* }}} */ - -/**************************************** - Internal support code -****************************************/ - -/* {{{ constructor/destructor */ -static -void php_memc_destroy(memcached_st *memc, php_memc_user_data_t *memc_user_data) -{ -#ifdef HAVE_MEMCACHED_SASL - if (memc_user_data->has_sasl_data) { - memcached_destroy_sasl_auth_data(memc); - } -#endif - - memcached_free(memc); - pefree(memc_user_data, memc_user_data->is_persistent); -} - -static -void php_memc_object_free_storage(zend_object *object) -{ - php_memc_object_t *intern = php_memc_fetch_object(object); - - if (intern->memc) { - php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); - - if (!memc_user_data->is_persistent) { - php_memc_destroy(intern->memc, memc_user_data); - } - } - - intern->memc = NULL; - zend_object_std_dtor(&intern->zo); -} - -static -zend_object *php_memc_object_new(zend_class_entry *ce) -{ - php_memc_object_t *intern = ecalloc(1, sizeof(php_memc_object_t) + zend_object_properties_size(ce)); - - zend_object_std_init(&intern->zo, ce); - object_properties_init(&intern->zo, ce); - - intern->zo.handlers = &memcached_object_handlers; - return &intern->zo; -} - -#ifdef HAVE_MEMCACHED_PROTOCOL -static -void php_memc_server_free_storage(zend_object *object) -{ - php_memc_server_t *intern = php_memc_server_fetch_object(object); - zend_object_std_dtor(&intern->zo); -} - -zend_object *php_memc_server_new(zend_class_entry *ce) -{ - php_memc_server_t *intern; - - intern = ecalloc(1, sizeof(php_memc_server_t) + zend_object_properties_size(ce)); - - zend_object_std_init(&intern->zo, ce); - object_properties_init(&intern->zo, ce); - - intern->zo.handlers = &memcached_server_object_handlers; - - return &intern->zo; -} -#endif - -ZEND_RSRC_DTOR_FUNC(php_memc_dtor) -{ - if (res->ptr) { - memcached_st *memc = (memcached_st *) res->ptr; - php_memc_destroy(memc, memcached_get_user_data(memc)); - res->ptr = NULL; - } -} - -/* }}} */ - -/* {{{ internal API functions */ -static -memcached_return s_server_cursor_list_servers_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context) -{ - zval array; - zval *return_value = (zval *) in_context; - - array_init(&array); - add_assoc_string(&array, "host", (char*)memcached_server_name(instance)); - add_assoc_long(&array, "port", memcached_server_port(instance)); - add_assoc_string(&array, "type", (char*)memcached_server_type(instance)); - /* - * API does not allow to get at this field. - add_assoc_long(array, "weight", instance->weight); - */ - - add_next_index_zval(return_value, &array); - return MEMCACHED_SUCCESS; -} - -static -memcached_return s_server_cursor_version_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context) -{ - zend_string *address, *version; - zval rv, *return_value = (zval *)in_context; - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 - version = strpprintf(0, "%d.%d.%d", - memcached_server_major_version(instance), - memcached_server_minor_version(instance), - memcached_server_micro_version(instance)); -#else - version = strpprintf(0, "%d.%d.%d", - instance->major_version, - instance->minor_version, - instance->micro_version); -#endif - - address = strpprintf(0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance)); - - ZVAL_STR(&rv, version); - zend_hash_add(Z_ARRVAL_P(return_value), address, &rv); - - zend_string_release(address); - - return MEMCACHED_SUCCESS; -} - - -static -zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32_t flags) -{ - zend_string *buffer; - - uint32_t stored_length; - unsigned long length; - zend_bool decompress_status = 0; - zend_bool is_fastlz = 0, is_zlib = 0; - - if (payload_len < sizeof (uint32_t)) { - return NULL; - } - - is_fastlz = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_FASTLZ); - is_zlib = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_ZLIB); - - if (!is_fastlz && !is_zlib) { - php_error_docref(NULL, E_WARNING, "could not decompress value: unrecognised compression type"); - return NULL; - } - - memcpy(&stored_length, payload, sizeof (uint32_t)); - - payload += sizeof (uint32_t); - payload_len -= sizeof (uint32_t); - - buffer = zend_string_alloc (stored_length, 0); - - if (is_fastlz) { - decompress_status = ((length = fastlz_decompress(payload, payload_len, &buffer->val, buffer->len)) > 0); - } - else if (is_zlib) { - decompress_status = (uncompress((Bytef *) buffer->val, &buffer->len, (Bytef *)payload, payload_len) == Z_OK); - } - - ZSTR_VAL(buffer)[stored_length] = '\0'; - - if (!decompress_status) { - php_error_docref(NULL, E_WARNING, "could not decompress value"); - zend_string_release (buffer); - return NULL; - } - - zend_string_forget_hash_val(buffer); - return buffer; -} - -static -zend_bool s_unserialize_value (memcached_st *memc, int val_type, zend_string *payload, zval *return_value) -{ - switch (val_type) { - case MEMC_VAL_IS_SERIALIZED: - { - php_unserialize_data_t var_hash; - const unsigned char *p, *max; - - p = (const unsigned char *) ZSTR_VAL(payload); - max = p + ZSTR_LEN(payload); - - PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (!php_var_unserialize(return_value, &p, max, &var_hash)) { - zval_ptr_dtor(return_value); - ZVAL_FALSE(return_value); - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - php_error_docref(NULL, E_WARNING, "could not unserialize value"); - return 0; - } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - } - break; - - case MEMC_VAL_IS_IGBINARY: -#ifdef HAVE_MEMCACHED_IGBINARY - if (igbinary_unserialize((uint8_t *) ZSTR_VAL(payload), ZSTR_LEN(payload), return_value)) { - ZVAL_FALSE(return_value); - php_error_docref(NULL, E_WARNING, "could not unserialize value with igbinary"); - return 0; - } -#else - ZVAL_FALSE(return_value); - php_error_docref(NULL, E_WARNING, "could not unserialize value, no igbinary support"); - return 0; -#endif - break; - - case MEMC_VAL_IS_JSON: -#ifdef HAVE_JSON_API - { - php_memc_user_data_t *memc_user_data = memcached_get_user_data(memc); - php_json_decode(return_value, ZSTR_VAL(payload), ZSTR_LEN(payload), (memc_user_data->serializer == SERIALIZER_JSON_ARRAY), PHP_JSON_PARSER_DEFAULT_DEPTH); - } -#else - ZVAL_FALSE(return_value); - php_error_docref(NULL, E_WARNING, "could not unserialize value, no json support"); - return 0; -#endif - break; - - case MEMC_VAL_IS_MSGPACK: -#ifdef HAVE_MEMCACHED_MSGPACK - php_msgpack_unserialize(return_value, ZSTR_VAL(payload), ZSTR_LEN(payload)); -#else - ZVAL_FALSE(return_value); - php_error_docref(NULL, E_WARNING, "could not unserialize value, no msgpack support"); - return 0; -#endif - break; - } - return 1; -} - -static -zend_bool s_memcached_result_to_zval(memcached_st *memc, memcached_result_st *result, zval *return_value) -{ - zend_string *data; - const char *payload; - size_t payload_len; - uint32_t flags; - zend_bool retval = 1; - - payload = memcached_result_value(result); - payload_len = memcached_result_length(result); - flags = memcached_result_flags(result); - - if (!payload && payload_len > 0) { - php_error_docref(NULL, E_WARNING, "Could not handle non-existing value of length %zu", payload_len); - return 0; - } - - if (MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSED)) { - data = s_decompress_value (payload, payload_len, flags); - if (!data) { - return 0; - } - } else { - data = zend_string_init(payload, payload_len, 0); - } - - switch (MEMC_VAL_GET_TYPE(flags)) { - - case MEMC_VAL_IS_STRING: - ZVAL_STR_COPY(return_value, data); - break; - - case MEMC_VAL_IS_LONG: - ZVAL_LONG(return_value, strtol(ZSTR_VAL(data), NULL, 10)); - break; - - case MEMC_VAL_IS_DOUBLE: - { - if (zend_string_equals_literal(data, "Infinity")) { - ZVAL_DOUBLE(return_value, php_get_inf()); - } - else if (zend_string_equals_literal(data, "-Infinity")) { - ZVAL_DOUBLE(return_value, -php_get_inf()); - } - else if (zend_string_equals_literal(data, "NaN")) { - ZVAL_DOUBLE(return_value, php_get_nan()); - } - else { - ZVAL_DOUBLE(return_value, zend_strtod(ZSTR_VAL(data), NULL)); - } - } - break; - - case MEMC_VAL_IS_BOOL: - ZVAL_BOOL(return_value, payload_len > 0 && ZSTR_VAL(data)[0] == '1'); - break; - - case MEMC_VAL_IS_SERIALIZED: - case MEMC_VAL_IS_IGBINARY: - case MEMC_VAL_IS_JSON: - case MEMC_VAL_IS_MSGPACK: - retval = s_unserialize_value (memc, MEMC_VAL_GET_TYPE(flags), data, return_value); - break; - - default: - php_error_docref(NULL, E_WARNING, "unknown payload type"); - break; - } - zend_string_release(data); - - return retval; -} - - -PHP_MEMCACHED_API -zend_class_entry *php_memc_get_ce(void) -{ - return memcached_ce; -} - -PHP_MEMCACHED_API -zend_class_entry *php_memc_get_exception(void) -{ - return memcached_exception_ce; -} - -PHP_MEMCACHED_API -zend_class_entry *php_memc_get_exception_base(int root) -{ -#ifdef HAVE_SPL - if (!root) { - if (!spl_ce_RuntimeException) { - zend_class_entry *pce; - zval *pce_z; - - if ((pce_z = zend_hash_str_find(CG(class_table), - "runtimeexception", - sizeof("RuntimeException") - 1)) != NULL) { - pce = Z_CE_P(pce_z); - spl_ce_RuntimeException = pce; - return pce; - } - } else { - return spl_ce_RuntimeException; - } - } -#endif - return zend_exception_get_default(); -} - - -#ifdef HAVE_MEMCACHED_PROTOCOL - -static -void s_destroy_cb (zend_fcall_info *fci) -{ - if (fci->size > 0) { - zval_ptr_dtor(&fci->function_name); - if (fci->object) { - OBJ_RELEASE(fci->object); - } - } -} - -static -PHP_METHOD(MemcachedServer, run) -{ - int i; - zend_bool rc; - zend_string *address; - - php_memc_server_t *intern; - intern = Z_MEMC_SERVER_P(getThis()); - - /* "S" */ - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(address) - ZEND_PARSE_PARAMETERS_END(); - - rc = php_memc_proto_handler_run(intern->handler, address); - - for (i = MEMC_SERVER_ON_MIN + 1; i < MEMC_SERVER_ON_MAX; i++) { - s_destroy_cb(&MEMC_SERVER_G(callbacks) [i].fci); - } - - RETURN_BOOL(rc); -} - -static -PHP_METHOD(MemcachedServer, on) -{ - zend_long event; - zend_fcall_info fci; - zend_fcall_info_cache fci_cache; - zend_bool rc = 0; - - /* "lf!" */ - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_LONG(event) - Z_PARAM_FUNC_EX(fci, fci_cache, 1, 0) - ZEND_PARSE_PARAMETERS_END(); - - if (event <= MEMC_SERVER_ON_MIN || event >= MEMC_SERVER_ON_MAX) { - RETURN_FALSE; - } - - if (fci.size > 0) { - s_destroy_cb (&MEMC_SERVER_G(callbacks) [event].fci); - - MEMC_SERVER_G(callbacks) [event].fci = fci; - MEMC_SERVER_G(callbacks) [event].fci_cache = fci_cache; - - Z_TRY_ADDREF(fci.function_name); - if (fci.object) { - GC_ADDREF(fci.object); - } - } - RETURN_BOOL(rc); -} - -#endif - -/* {{{ methods arginfo */ -ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0) - ZEND_ARG_INFO(0, persistent_id) - ZEND_ARG_INFO(0, callback) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getResultCode, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getResultMessage, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_get, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, cache_cb) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, cache_cb) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getMulti, 0, 0, 1) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getMultiByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getDelayed, 0, 0, 1) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, with_cas) - ZEND_ARG_INFO(0, value_cb) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getDelayedByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, with_cas) - ZEND_ARG_INFO(0, value_cb) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_fetch, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_fetchAll, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_set, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_setByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_touch, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_touchByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_setMulti, 0, 0, 1) - ZEND_ARG_ARRAY_INFO(0, items, 0) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_setMultiByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_ARRAY_INFO(0, items, 0) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_add, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_addByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_replace, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_replaceByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_appendByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_prepend, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_prependByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_cas, 0, 0, 3) - ZEND_ARG_INFO(0, cas_token) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_casByKey, 0, 0, 4) - ZEND_ARG_INFO(0, cas_token) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_delete, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteMulti, 0, 0, 1) - ZEND_ARG_INFO(0, keys) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteMultiByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, keys) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_increment, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_decrement, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_incrementByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_decrementByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_flush, 0, 0, 0) - ZEND_ARG_INFO(0, delay) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_addServer, 0, 0, 2) - ZEND_ARG_INFO(0, host) - ZEND_ARG_INFO(0, port) - ZEND_ARG_INFO(0, weight) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getStats, 0, 0, 0) - ZEND_ARG_INFO(0, type) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_addServers, 0) - ZEND_ARG_ARRAY_INFO(0, servers, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getServerList, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_resetServerList, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_quit, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_flushBuffers, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getServerByKey, 0) - ZEND_ARG_INFO(0, server_key) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorMessage, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorCode, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorErrno, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastDisconnectedServer, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getOption, 0) - ZEND_ARG_INFO(0, option) -ZEND_END_ARG_INFO() - -#ifdef HAVE_MEMCACHED_SASL -ZEND_BEGIN_ARG_INFO(arginfo_setSaslAuthData, 0) - ZEND_ARG_INFO(0, username) - ZEND_ARG_INFO(0, password) -ZEND_END_ARG_INFO() -#endif - -#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY -ZEND_BEGIN_ARG_INFO(arginfo_setEncodingKey, 0) - ZEND_ARG_INFO(0, key) -ZEND_END_ARG_INFO() -#endif - -ZEND_BEGIN_ARG_INFO(arginfo_setOption, 0) - ZEND_ARG_INFO(0, option) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_setOptions, 0) - ZEND_ARG_INFO(0, options) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 3) - ZEND_ARG_INFO(0, host_map) - ZEND_ARG_INFO(0, forward_map) - ZEND_ARG_INFO(0, replicas) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getVersion, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_isPersistent, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_isPristine, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getAllKeys, 0) -ZEND_END_ARG_INFO() -/* }}} */ - -/* {{{ memcached_class_methods */ -#define MEMC_ME(name, args) PHP_ME(Memcached, name, args, ZEND_ACC_PUBLIC) -static zend_function_entry memcached_class_methods[] = { - MEMC_ME(__construct, arginfo___construct) - - MEMC_ME(getResultCode, arginfo_getResultCode) - MEMC_ME(getResultMessage, arginfo_getResultMessage) - - MEMC_ME(get, arginfo_get) - MEMC_ME(getByKey, arginfo_getByKey) - MEMC_ME(getMulti, arginfo_getMulti) - MEMC_ME(getMultiByKey, arginfo_getMultiByKey) - MEMC_ME(getDelayed, arginfo_getDelayed) - MEMC_ME(getDelayedByKey, arginfo_getDelayedByKey) - MEMC_ME(fetch, arginfo_fetch) - MEMC_ME(fetchAll, arginfo_fetchAll) - - MEMC_ME(set, arginfo_set) - MEMC_ME(setByKey, arginfo_setByKey) - - MEMC_ME(touch, arginfo_touch) - MEMC_ME(touchByKey, arginfo_touchByKey) - - MEMC_ME(setMulti, arginfo_setMulti) - MEMC_ME(setMultiByKey, arginfo_setMultiByKey) - - MEMC_ME(cas, arginfo_cas) - MEMC_ME(casByKey, arginfo_casByKey) - MEMC_ME(add, arginfo_add) - MEMC_ME(addByKey, arginfo_addByKey) - MEMC_ME(append, arginfo_append) - MEMC_ME(appendByKey, arginfo_appendByKey) - MEMC_ME(prepend, arginfo_prepend) - MEMC_ME(prependByKey, arginfo_prependByKey) - MEMC_ME(replace, arginfo_replace) - MEMC_ME(replaceByKey, arginfo_replaceByKey) - MEMC_ME(delete, arginfo_delete) - MEMC_ME(deleteMulti, arginfo_deleteMulti) - MEMC_ME(deleteByKey, arginfo_deleteByKey) - MEMC_ME(deleteMultiByKey, arginfo_deleteMultiByKey) - - MEMC_ME(increment, arginfo_increment) - MEMC_ME(decrement, arginfo_decrement) - MEMC_ME(incrementByKey, arginfo_incrementByKey) - MEMC_ME(decrementByKey, arginfo_decrementByKey) - - MEMC_ME(addServer, arginfo_addServer) - MEMC_ME(addServers, arginfo_addServers) - MEMC_ME(getServerList, arginfo_getServerList) - MEMC_ME(getServerByKey, arginfo_getServerByKey) - MEMC_ME(resetServerList, arginfo_resetServerList) - MEMC_ME(quit, arginfo_quit) - MEMC_ME(flushBuffers, arginfo_flushBuffers) - - MEMC_ME(getLastErrorMessage, arginfo_getLastErrorMessage) - MEMC_ME(getLastErrorCode, arginfo_getLastErrorCode) - MEMC_ME(getLastErrorErrno, arginfo_getLastErrorErrno) - MEMC_ME(getLastDisconnectedServer, arginfo_getLastDisconnectedServer) - - MEMC_ME(getStats, arginfo_getStats) - MEMC_ME(getVersion, arginfo_getVersion) - MEMC_ME(getAllKeys, arginfo_getAllKeys) - - MEMC_ME(flush, arginfo_flush) - - MEMC_ME(getOption, arginfo_getOption) - MEMC_ME(setOption, arginfo_setOption) - MEMC_ME(setOptions, arginfo_setOptions) - MEMC_ME(setBucket, arginfo_setBucket) -#ifdef HAVE_MEMCACHED_SASL - MEMC_ME(setSaslAuthData, arginfo_setSaslAuthData) -#endif -#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY - MEMC_ME(setEncodingKey, arginfo_setEncodingKey) -#endif - MEMC_ME(isPersistent, arginfo_isPersistent) - MEMC_ME(isPristine, arginfo_isPristine) - { NULL, NULL, NULL } -}; -#undef MEMC_ME -/* }}} */ - -#ifdef HAVE_MEMCACHED_PROTOCOL -/* {{{ */ -#define MEMC_SE_ME(name, args) PHP_ME(MemcachedServer, name, args, ZEND_ACC_PUBLIC) -static -zend_function_entry memcached_server_class_methods[] = { - MEMC_SE_ME(run, NULL) - MEMC_SE_ME(on, NULL) - { NULL, NULL, NULL } -}; -#undef MEMC_SE_ME -/* }}} */ -#endif - -/* {{{ memcached_module_entry - */ - -#if ZEND_MODULE_API_NO >= 20050922 -static const zend_module_dep memcached_deps[] = { -#ifdef HAVE_MEMCACHED_SESSION - ZEND_MOD_REQUIRED("session") -#endif -#ifdef HAVE_MEMCACHED_IGBINARY - ZEND_MOD_REQUIRED("igbinary") -#endif -#ifdef HAVE_MEMCACHED_MSGPACK - ZEND_MOD_REQUIRED("msgpack") -#endif -#ifdef HAVE_SPL - ZEND_MOD_REQUIRED("spl") -#endif - {NULL, NULL, NULL} -}; -#endif - -static -PHP_GINIT_FUNCTION(php_memcached) -{ -#ifdef HAVE_MEMCACHED_SESSION - - php_memcached_globals->session.lock_enabled = 0; - php_memcached_globals->session.lock_wait_max = 150; - php_memcached_globals->session.lock_wait_min = 150; - php_memcached_globals->session.lock_retries = 200; - php_memcached_globals->session.lock_expiration = 30; - php_memcached_globals->session.binary_protocol_enabled = 1; - php_memcached_globals->session.consistent_hash_enabled = 1; - php_memcached_globals->session.consistent_hash_type = MEMCACHED_BEHAVIOR_KETAMA; - php_memcached_globals->session.consistent_hash_name = NULL; - php_memcached_globals->session.number_of_replicas = 0; - php_memcached_globals->session.server_failure_limit = 1; - php_memcached_globals->session.randomize_replica_read_enabled = 1; - php_memcached_globals->session.remove_failed_servers_enabled = 1; - php_memcached_globals->session.connect_timeout = 1000; - php_memcached_globals->session.prefix = NULL; - php_memcached_globals->session.persistent_enabled = 0; - php_memcached_globals->session.sasl_username = NULL; - php_memcached_globals->session.sasl_password = NULL; - -#endif - php_memcached_globals->memc.serializer_name = NULL; - php_memcached_globals->memc.serializer_type = SERIALIZER_DEFAULT; - php_memcached_globals->memc.compression_name = NULL; - php_memcached_globals->memc.compression_threshold = 2000; - php_memcached_globals->memc.compression_type = COMPRESSION_TYPE_FASTLZ; - php_memcached_globals->memc.compression_factor = 1.30; - php_memcached_globals->memc.store_retry_count = 2; - - php_memcached_globals->memc.sasl_initialised = 0; - php_memcached_globals->no_effect = 0; - - /* Defaults for certain options */ - php_memcached_globals->memc.default_behavior.consistent_hash_enabled = 0; - php_memcached_globals->memc.default_behavior.binary_protocol_enabled = 0; - php_memcached_globals->memc.default_behavior.connect_timeout = 0; -} - -zend_module_entry memcached_module_entry = { - STANDARD_MODULE_HEADER_EX, NULL, - memcached_deps, - "memcached", - NULL, - PHP_MINIT(memcached), - PHP_MSHUTDOWN(memcached), - NULL, - NULL, - PHP_MINFO(memcached), - PHP_MEMCACHED_VERSION, - PHP_MODULE_GLOBALS(php_memcached), - PHP_GINIT(php_memcached), - NULL, - NULL, - STANDARD_MODULE_PROPERTIES_EX -}; -/* }}} */ - - -/* {{{ php_memc_register_constants */ -static void php_memc_register_constants(INIT_FUNC_ARGS) -{ - #define REGISTER_MEMC_CLASS_CONST_LONG(name, value) zend_declare_class_constant_long(php_memc_get_ce() , ZEND_STRS( #name ) - 1, value) - #define REGISTER_MEMC_CLASS_CONST_BOOL(name, value) zend_declare_class_constant_bool(php_memc_get_ce() , ZEND_STRS( #name ) - 1, value) - #define REGISTER_MEMC_CLASS_CONST_NULL(name) zend_declare_class_constant_null(php_memc_get_ce() , ZEND_STRS( #name ) - 1) - - /* - * Class options - */ - REGISTER_MEMC_CLASS_CONST_LONG(LIBMEMCACHED_VERSION_HEX, LIBMEMCACHED_VERSION_HEX); - - REGISTER_MEMC_CLASS_CONST_LONG(OPT_COMPRESSION, MEMC_OPT_COMPRESSION); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_COMPRESSION_TYPE, MEMC_OPT_COMPRESSION_TYPE); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_PREFIX_KEY, MEMC_OPT_PREFIX_KEY); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERIALIZER, MEMC_OPT_SERIALIZER); - - REGISTER_MEMC_CLASS_CONST_LONG(OPT_USER_FLAGS, MEMC_OPT_USER_FLAGS); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_STORE_RETRY_COUNT, MEMC_OPT_STORE_RETRY_COUNT); - - /* - * Indicate whether igbinary serializer is available - */ -#ifdef HAVE_MEMCACHED_IGBINARY - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_IGBINARY, 1); -#else - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_IGBINARY, 0); -#endif - - /* - * Indicate whether json serializer is available - */ -#ifdef HAVE_JSON_API - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_JSON, 1); -#else - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_JSON, 0); -#endif - - /* - * Indicate whether msgpack serializer is available - */ -#ifdef HAVE_MEMCACHED_MSGPACK - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_MSGPACK, 1); -#else - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_MSGPACK, 0); -#endif - - /* - * Indicate whether set_encoding_key is available - */ -#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ENCODING, 1); -#else - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ENCODING, 0); -#endif - -#ifdef HAVE_MEMCACHED_SESSION - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SESSION, 1); -#else - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SESSION, 0); -#endif - -#ifdef HAVE_MEMCACHED_SASL - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SASL, 1); -#else - REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SASL, 0); -#endif - - /* - * libmemcached behavior options - */ - - REGISTER_MEMC_CLASS_CONST_LONG(OPT_HASH, MEMCACHED_BEHAVIOR_HASH); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_DEFAULT, MEMCACHED_HASH_DEFAULT); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_MD5, MEMCACHED_HASH_MD5); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_CRC, MEMCACHED_HASH_CRC); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1_64, MEMCACHED_HASH_FNV1_64); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1A_64, MEMCACHED_HASH_FNV1A_64); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1_32, MEMCACHED_HASH_FNV1_32); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1A_32, MEMCACHED_HASH_FNV1A_32); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_HSIEH, MEMCACHED_HASH_HSIEH); - REGISTER_MEMC_CLASS_CONST_LONG(HASH_MURMUR, MEMCACHED_HASH_MURMUR); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_DISTRIBUTION, MEMCACHED_BEHAVIOR_DISTRIBUTION); - REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_MODULA, MEMCACHED_DISTRIBUTION_MODULA); - REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_CONSISTENT, MEMCACHED_DISTRIBUTION_CONSISTENT); - REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_VIRTUAL_BUCKET, MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_COMPATIBLE, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_HASH, MEMCACHED_BEHAVIOR_KETAMA_HASH); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_KEEPALIVE, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_BUFFER_WRITES, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_BINARY_PROTOCOL, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_NO_BLOCK, MEMCACHED_BEHAVIOR_NO_BLOCK); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_NODELAY, MEMCACHED_BEHAVIOR_TCP_NODELAY); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_SOCKET_SEND_SIZE, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_SOCKET_RECV_SIZE, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_CONNECT_TIMEOUT, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_RETRY_TIMEOUT, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT); -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000003 - REGISTER_MEMC_CLASS_CONST_LONG(OPT_DEAD_TIMEOUT, MEMCACHED_BEHAVIOR_DEAD_TIMEOUT); -#endif - REGISTER_MEMC_CLASS_CONST_LONG(OPT_SEND_TIMEOUT, MEMCACHED_BEHAVIOR_SND_TIMEOUT); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_RECV_TIMEOUT, MEMCACHED_BEHAVIOR_RCV_TIMEOUT); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_POLL_TIMEOUT, MEMCACHED_BEHAVIOR_POLL_TIMEOUT); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_CACHE_LOOKUPS, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERVER_FAILURE_LIMIT, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_AUTO_EJECT_HOSTS, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_HASH_WITH_PREFIX_KEY, MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_NOREPLY, MEMCACHED_BEHAVIOR_NOREPLY); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_SORT_HOSTS, MEMCACHED_BEHAVIOR_SORT_HOSTS); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_VERIFY_KEY, MEMCACHED_BEHAVIOR_VERIFY_KEY); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_USE_UDP, MEMCACHED_BEHAVIOR_USE_UDP); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_NUMBER_OF_REPLICAS, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_RANDOMIZE_REPLICA_READ, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_REMOVE_FAILED_SERVERS, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS); -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000018 - REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERVER_TIMEOUT_LIMIT, MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT); -#endif - - /* - * libmemcached result codes - */ - - REGISTER_MEMC_CLASS_CONST_LONG(RES_SUCCESS, MEMCACHED_SUCCESS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_FAILURE, MEMCACHED_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_HOST_LOOKUP_FAILURE, MEMCACHED_HOST_LOOKUP_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_READ_FAILURE, MEMCACHED_UNKNOWN_READ_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_PROTOCOL_ERROR, MEMCACHED_PROTOCOL_ERROR); - REGISTER_MEMC_CLASS_CONST_LONG(RES_CLIENT_ERROR, MEMCACHED_CLIENT_ERROR); - REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_ERROR, MEMCACHED_SERVER_ERROR); - REGISTER_MEMC_CLASS_CONST_LONG(RES_WRITE_FAILURE, MEMCACHED_WRITE_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_DATA_EXISTS, MEMCACHED_DATA_EXISTS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTSTORED, MEMCACHED_NOTSTORED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTFOUND, MEMCACHED_NOTFOUND); - REGISTER_MEMC_CLASS_CONST_LONG(RES_PARTIAL_READ, MEMCACHED_PARTIAL_READ); - REGISTER_MEMC_CLASS_CONST_LONG(RES_SOME_ERRORS, MEMCACHED_SOME_ERRORS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NO_SERVERS, MEMCACHED_NO_SERVERS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_END, MEMCACHED_END); - REGISTER_MEMC_CLASS_CONST_LONG(RES_ERRNO, MEMCACHED_ERRNO); - REGISTER_MEMC_CLASS_CONST_LONG(RES_BUFFERED, MEMCACHED_BUFFERED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_TIMEOUT, MEMCACHED_TIMEOUT); - REGISTER_MEMC_CLASS_CONST_LONG(RES_BAD_KEY_PROVIDED, MEMCACHED_BAD_KEY_PROVIDED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_STORED, MEMCACHED_STORED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_DELETED, MEMCACHED_DELETED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_STAT, MEMCACHED_STAT); - REGISTER_MEMC_CLASS_CONST_LONG(RES_ITEM, MEMCACHED_ITEM); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NOT_SUPPORTED, MEMCACHED_NOT_SUPPORTED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_FETCH_NOTFINISHED, MEMCACHED_FETCH_NOTFINISHED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_MARKED_DEAD, MEMCACHED_SERVER_MARKED_DEAD); - REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_STAT_KEY, MEMCACHED_UNKNOWN_STAT_KEY); - REGISTER_MEMC_CLASS_CONST_LONG(RES_INVALID_HOST_PROTOCOL, MEMCACHED_INVALID_HOST_PROTOCOL); - REGISTER_MEMC_CLASS_CONST_LONG(RES_MEMORY_ALLOCATION_FAILURE, MEMCACHED_MEMORY_ALLOCATION_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_CONNECTION_SOCKET_CREATE_FAILURE, MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE); - - REGISTER_MEMC_CLASS_CONST_LONG(RES_E2BIG, MEMCACHED_E2BIG); - REGISTER_MEMC_CLASS_CONST_LONG(RES_KEY_TOO_BIG, MEMCACHED_KEY_TOO_BIG); - REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_TEMPORARILY_DISABLED, MEMCACHED_SERVER_TEMPORARILY_DISABLED); - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000008 - REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_MEMORY_ALLOCATION_FAILURE, MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE); -#endif - -#ifdef HAVE_MEMCACHED_SASL - REGISTER_MEMC_CLASS_CONST_LONG(RES_AUTH_PROBLEM, MEMCACHED_AUTH_PROBLEM); - REGISTER_MEMC_CLASS_CONST_LONG(RES_AUTH_FAILURE, MEMCACHED_AUTH_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_AUTH_CONTINUE, MEMCACHED_AUTH_CONTINUE); -#endif - - /* - * Our result codes. - */ - - REGISTER_MEMC_CLASS_CONST_LONG(RES_PAYLOAD_FAILURE, MEMC_RES_PAYLOAD_FAILURE); - - /* - * Serializer types. - */ - REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_PHP, SERIALIZER_PHP); - REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_IGBINARY, SERIALIZER_IGBINARY); - REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_JSON, SERIALIZER_JSON); - REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_JSON_ARRAY, SERIALIZER_JSON_ARRAY); - REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_MSGPACK, SERIALIZER_MSGPACK); - - /* - * Compression types - */ - REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_FASTLZ, COMPRESSION_TYPE_FASTLZ); - REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_ZLIB, COMPRESSION_TYPE_ZLIB); - - /* - * Flags. - */ - REGISTER_MEMC_CLASS_CONST_LONG(GET_PRESERVE_ORDER, MEMC_GET_PRESERVE_ORDER); - REGISTER_MEMC_CLASS_CONST_LONG(GET_EXTENDED, MEMC_GET_EXTENDED); - -#ifdef HAVE_MEMCACHED_PROTOCOL - /* - * Server callbacks - */ - REGISTER_MEMC_CLASS_CONST_LONG(ON_CONNECT, MEMC_SERVER_ON_CONNECT); - REGISTER_MEMC_CLASS_CONST_LONG(ON_ADD, MEMC_SERVER_ON_ADD); - REGISTER_MEMC_CLASS_CONST_LONG(ON_APPEND, MEMC_SERVER_ON_APPEND); - REGISTER_MEMC_CLASS_CONST_LONG(ON_DECREMENT, MEMC_SERVER_ON_DECREMENT); - REGISTER_MEMC_CLASS_CONST_LONG(ON_DELETE, MEMC_SERVER_ON_DELETE); - REGISTER_MEMC_CLASS_CONST_LONG(ON_FLUSH, MEMC_SERVER_ON_FLUSH); - REGISTER_MEMC_CLASS_CONST_LONG(ON_GET, MEMC_SERVER_ON_GET); - REGISTER_MEMC_CLASS_CONST_LONG(ON_INCREMENT, MEMC_SERVER_ON_INCREMENT); - REGISTER_MEMC_CLASS_CONST_LONG(ON_NOOP, MEMC_SERVER_ON_NOOP); - REGISTER_MEMC_CLASS_CONST_LONG(ON_PREPEND, MEMC_SERVER_ON_PREPEND); - REGISTER_MEMC_CLASS_CONST_LONG(ON_QUIT, MEMC_SERVER_ON_QUIT); - REGISTER_MEMC_CLASS_CONST_LONG(ON_REPLACE, MEMC_SERVER_ON_REPLACE); - REGISTER_MEMC_CLASS_CONST_LONG(ON_SET, MEMC_SERVER_ON_SET); - REGISTER_MEMC_CLASS_CONST_LONG(ON_STAT, MEMC_SERVER_ON_STAT); - REGISTER_MEMC_CLASS_CONST_LONG(ON_VERSION, MEMC_SERVER_ON_VERSION); - - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_SUCCESS, PROTOCOL_BINARY_RESPONSE_SUCCESS); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_KEY_ENOENT, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_KEY_EEXISTS, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_E2BIG, PROTOCOL_BINARY_RESPONSE_E2BIG); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_EINVAL, PROTOCOL_BINARY_RESPONSE_EINVAL); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_NOT_STORED, PROTOCOL_BINARY_RESPONSE_NOT_STORED); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_DELTA_BADVAL, PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_NOT_MY_VBUCKET, PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_AUTH_ERROR, PROTOCOL_BINARY_RESPONSE_AUTH_ERROR); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_AUTH_CONTINUE, PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_UNKNOWN_COMMAND, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_ENOMEM, PROTOCOL_BINARY_RESPONSE_ENOMEM); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_NOT_SUPPORTED, PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_EINTERNAL, PROTOCOL_BINARY_RESPONSE_EINTERNAL); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_EBUSY, PROTOCOL_BINARY_RESPONSE_EBUSY); - REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_ETMPFAIL, PROTOCOL_BINARY_RESPONSE_ETMPFAIL); -#endif - - /* - * Return value from simple get errors - */ - REGISTER_MEMC_CLASS_CONST_BOOL(GET_ERROR_RETURN_VALUE, 0); - - #undef REGISTER_MEMC_CLASS_CONST_LONG - #undef REGISTER_MEMC_CLASS_CONST_BOOL - #undef REGISTER_MEMC_CLASS_CONST_NULL - -} -/* }}} */ - -/* {{{ PHP_MINIT_FUNCTION */ -PHP_MINIT_FUNCTION(memcached) -{ - zend_class_entry ce; - - memcpy(&memcached_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - memcached_object_handlers.offset = XtOffsetOf(php_memc_object_t, zo); - memcached_object_handlers.clone_obj = NULL; - memcached_object_handlers.free_obj = php_memc_object_free_storage; - - le_memc = zend_register_list_destructors_ex(NULL, php_memc_dtor, "Memcached persistent connection", module_number); - - INIT_CLASS_ENTRY(ce, "Memcached", memcached_class_methods); - memcached_ce = zend_register_internal_class(&ce); - memcached_ce->create_object = php_memc_object_new; - -#ifdef HAVE_MEMCACHED_PROTOCOL - memcpy(&memcached_server_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - memcached_server_object_handlers.offset = XtOffsetOf(php_memc_server_t, zo); - memcached_server_object_handlers.clone_obj = NULL; - memcached_server_object_handlers.free_obj = php_memc_server_free_storage; - - INIT_CLASS_ENTRY(ce, "MemcachedServer", memcached_server_class_methods); - memcached_server_ce = zend_register_internal_class(&ce); - memcached_server_ce->create_object = php_memc_server_new; -#endif - - INIT_CLASS_ENTRY(ce, "MemcachedException", NULL); - memcached_exception_ce = zend_register_internal_class_ex(&ce, php_memc_get_exception_base(0)); - /* TODO - * possibly declare custom exception property here - */ - - php_memc_register_constants(INIT_FUNC_ARGS_PASSTHRU); - REGISTER_INI_ENTRIES(); - -#ifdef HAVE_MEMCACHED_SESSION - php_memc_session_minit(module_number); -#endif - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MSHUTDOWN_FUNCTION */ -PHP_MSHUTDOWN_FUNCTION(memcached) -{ -#ifdef HAVE_MEMCACHED_SASL - if (MEMC_G(sasl_initialised)) { - sasl_done(); - } -#endif - - UNREGISTER_INI_ENTRIES(); - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MINFO_FUNCTION */ -PHP_MINFO_FUNCTION(memcached) -{ - php_info_print_table_start(); - php_info_print_table_header(2, "memcached support", "enabled"); - php_info_print_table_row(2, "Version", PHP_MEMCACHED_VERSION); - php_info_print_table_row(2, "libmemcached version", memcached_lib_version()); - -#ifdef HAVE_MEMCACHED_SASL - php_info_print_table_row(2, "SASL support", "yes"); -#else - php_info_print_table_row(2, "SASL support", "no"); -#endif - -#ifdef HAVE_MEMCACHED_SESSION - php_info_print_table_row(2, "Session support", "yes"); -#else - php_info_print_table_row(2, "Session support ", "no"); -#endif - -#ifdef HAVE_MEMCACHED_IGBINARY - php_info_print_table_row(2, "igbinary support", "yes"); -#else - php_info_print_table_row(2, "igbinary support", "no"); -#endif - -#ifdef HAVE_JSON_API - php_info_print_table_row(2, "json support", "yes"); -#else - php_info_print_table_row(2, "json support", "no"); -#endif - -#ifdef HAVE_MEMCACHED_MSGPACK - php_info_print_table_row(2, "msgpack support", "yes"); -#else - php_info_print_table_row(2, "msgpack support", "no"); -#endif - - php_info_print_table_end(); - - DISPLAY_INI_ENTRIES(); -} -/* }}} */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim: noet sw=4 ts=4 fdm=marker: - */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached.h php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached.h 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#ifndef PHP_MEMCACHED_H -#define PHP_MEMCACHED_H - -#include "php.h" -#include "Zend/zend_smart_str.h" - -#ifdef PHP_WIN32 -#include "main/config.w32.h" -#else -#include "main/php_config.h" -#endif - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#define PHP_MEMCACHED_VERSION "3.1.3" - -#if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) -#define PHP_MEMCACHED_API __declspec(dllexport) -#else -#define PHP_MEMCACHED_API PHPAPI -#endif - -PHP_MEMCACHED_API zend_class_entry *php_memc_get_ce(void); -PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception(void); -PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception_base(int root); - -extern zend_module_entry memcached_module_entry; -#define phpext_memcached_ptr &memcached_module_entry - -#endif /* PHP_MEMCACHED_H */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_private.h php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_private.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_private.h 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_private.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#ifndef PHP_MEMCACHED_PRIVATE_H -#define PHP_MEMCACHED_PRIVATE_H - -#ifdef PHP_WIN32 -#include "main/config.w32.h" -#else -#include "main/php_config.h" -#endif - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "php_libmemcached_compat.h" - -#include -#include -#include -#include - -#ifdef ZTS -# include "TSRM.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef PHP_WIN32 -# include "win32/php_stdint.h" -#else -/* Used to store the size of the block */ -# if defined(HAVE_INTTYPES_H) -# include -# elif defined(HAVE_STDINT_H) -# include -# endif -#endif - -#ifndef HAVE_INT32_T -# if SIZEOF_INT == 4 -typedef int int32_t; -# elif SIZEOF_LONG == 4 -typedef long int int32_t; -# endif -#endif - -#ifndef HAVE_UINT32_T -# if SIZEOF_INT == 4 -typedef unsigned int uint32_t; -# elif SIZEOF_LONG == 4 -typedef unsigned long int uint32_t; -# endif -#endif - -/* Backwards compatibility for GC API change in PHP 7.3 */ -#if PHP_VERSION_ID < 70300 -# define GC_ADDREF(p) ++GC_REFCOUNT(p) -# define GC_DELREF(p) --GC_REFCOUNT(p) -# define GC_SET_REFCOUNT(p, rc) GC_REFCOUNT(p) = rc -#endif - -/**************************************** - Structures and definitions -****************************************/ -typedef enum { - SERIALIZER_PHP = 1, - SERIALIZER_IGBINARY = 2, - SERIALIZER_JSON = 3, - SERIALIZER_JSON_ARRAY = 4, - SERIALIZER_MSGPACK = 5 -} php_memc_serializer_type; - -typedef enum { - COMPRESSION_TYPE_ZLIB = 1, - COMPRESSION_TYPE_FASTLZ = 2 -} php_memc_compression_type; - -typedef struct { - const char *name; - php_memc_serializer_type type; -} php_memc_serializer; - -#if defined(HAVE_MEMCACHED_IGBINARY) -# define SERIALIZER_DEFAULT SERIALIZER_IGBINARY -# define SERIALIZER_DEFAULT_NAME "igbinary" -#elif defined(HAVE_MEMCACHED_MSGPACK) -# define SERIALIZER_DEFAULT SERIALIZER_MSGPACK -# define SERIALIZER_DEFAULT_NAME "msgpack" -#else -# define SERIALIZER_DEFAULT SERIALIZER_PHP -# define SERIALIZER_DEFAULT_NAME "php" -#endif /* HAVE_MEMCACHED_IGBINARY / HAVE_MEMCACHED_MSGPACK */ - -#ifdef HAVE_MEMCACHED_SASL -# include -#endif - -#ifdef HAVE_MEMCACHED_PROTOCOL -typedef enum { - MEMC_SERVER_ON_MIN = -1, - MEMC_SERVER_ON_CONNECT = 0, - MEMC_SERVER_ON_ADD = 1, - MEMC_SERVER_ON_APPEND = 2, - MEMC_SERVER_ON_DECREMENT = 3, - MEMC_SERVER_ON_DELETE = 4, - MEMC_SERVER_ON_FLUSH = 5, - MEMC_SERVER_ON_GET = 6, - MEMC_SERVER_ON_INCREMENT = 7, - MEMC_SERVER_ON_NOOP = 8, - MEMC_SERVER_ON_PREPEND = 9, - MEMC_SERVER_ON_QUIT = 10, - MEMC_SERVER_ON_REPLACE = 11, - MEMC_SERVER_ON_SET = 12, - MEMC_SERVER_ON_STAT = 13, - MEMC_SERVER_ON_VERSION = 14, - MEMC_SERVER_ON_MAX -} php_memc_event_t; - - -typedef struct { - zend_fcall_info fci; - zend_fcall_info_cache fci_cache; -} php_memc_server_cb_t; -#endif - -ZEND_BEGIN_MODULE_GLOBALS(php_memcached) - -#ifdef HAVE_MEMCACHED_SESSION - /* Session related variables */ - struct { - zend_bool lock_enabled; - zend_long lock_wait_max; - zend_long lock_wait_min; - zend_long lock_retries; - zend_long lock_expiration; - - zend_bool binary_protocol_enabled; - zend_bool consistent_hash_enabled; - char *consistent_hash_name; - int consistent_hash_type; - - zend_long server_failure_limit; - zend_long number_of_replicas; - zend_bool randomize_replica_read_enabled; - zend_bool remove_failed_servers_enabled; - - zend_long connect_timeout; - - char *prefix; - zend_bool persistent_enabled; - - char *sasl_username; - char *sasl_password; - } session; -#endif - - struct { - char *serializer_name; - char *compression_name; - zend_long compression_threshold; - double compression_factor; - zend_long store_retry_count; - - /* Converted values*/ - php_memc_serializer_type serializer_type; - php_memc_compression_type compression_type; - - /* Whether we have initialised sasl for this process */ - zend_bool sasl_initialised; - - struct { - - zend_bool consistent_hash_enabled; - zend_bool binary_protocol_enabled; - zend_long connect_timeout; - - } default_behavior; - - } memc; - - /* For deprecated values */ - zend_long no_effect; - -#ifdef HAVE_MEMCACHED_PROTOCOL - struct { - php_memc_server_cb_t callbacks [MEMC_SERVER_ON_MAX]; - } server; -#endif - -ZEND_END_MODULE_GLOBALS(php_memcached) - -/* Globals accessor macros */ -#ifdef ZTS -# define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) -# define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) -# define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v) -#else -# define MEMC_G(v) (php_memcached_globals.memc.v) -# define MEMC_SERVER_G(v) (php_memcached_globals.server.v) -# define MEMC_SESS_INI(v) (php_memcached_globals.session.v) -#endif - -#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL) - -PHP_RINIT_FUNCTION(memcached); -PHP_RSHUTDOWN_FUNCTION(memcached); -PHP_MINIT_FUNCTION(memcached); -PHP_MSHUTDOWN_FUNCTION(memcached); -PHP_MINFO_FUNCTION(memcached); - -char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache); - -memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); - -zend_bool php_memc_init_sasl_if_needed(); - -#endif /* PHP_MEMCACHED_PRIVATE_H */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_server.c php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_server.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_server.c 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_server.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,820 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Mikko Koppanen | - +----------------------------------------------------------------------+ -*/ - -#include "php_memcached.h" -#include "php_memcached_private.h" -#include "php_memcached_server.h" - -#include - -#undef NDEBUG -#undef _NDEBUG -#include - -#define MEMC_GET_CB(cb_type) (MEMC_SERVER_G(callbacks)[cb_type]) -#define MEMC_HAS_CB(cb_type) (MEMC_GET_CB(cb_type).fci.size > 0) - -#define MEMC_MAKE_ZVAL_COOKIE(my_zcookie, my_ptr) \ - do { \ - zend_string *cookie_buf; \ - cookie_buf = strpprintf(0, "%p", my_ptr); \ - ZVAL_STR(&my_zcookie, cookie_buf); \ - } while (0) - -#define MEMC_MAKE_RESULT_CAS(my_zresult_cas, my_result_cas) \ - do { \ - my_result_cas = 0; \ - my_result_cas = zval_get_double(&my_zresult_cas); \ - } while (0) - - -ZEND_EXTERN_MODULE_GLOBALS(php_memcached) - -struct _php_memc_proto_handler_t { - memcached_binary_protocol_callback_st callbacks; - struct memcached_protocol_st *protocol_handle; - struct event_base *event_base; -}; - -typedef struct { - struct memcached_protocol_client_st *protocol_client; - struct event_base *event_base; - zend_bool on_connect_invoked; -} php_memc_client_t; - -static -long s_invoke_php_callback (php_memc_server_cb_t *cb, zval *params, ssize_t param_count) -{ - zval *retval = NULL; - - cb->fci.retval = retval; - cb->fci.params = params; - cb->fci.param_count = param_count; - cb->fci.no_separation = 1; - - if (zend_call_function(&(cb->fci), &(cb->fci_cache)) == FAILURE) { - char *buf = php_memc_printable_func(&(cb->fci), &(cb->fci_cache)); - php_error_docref(NULL, E_WARNING, "Failed to invoke callback %s()", buf); - efree (buf); - } - - return retval == NULL ? PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND : zval_get_long(retval); -} - -// memcached protocol callbacks -static -protocol_binary_response_status s_add_handler(const void *cookie, const void *key, uint16_t key_len, const void *data, - uint32_t data_len, uint32_t flags, uint32_t exptime, uint64_t *result_cas) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zvalue, zflags, zexptime, zresult_cas; - zval params[6]; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_ADD)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_STRINGL(&zvalue, data, data_len); - ZVAL_LONG(&zflags, flags); - ZVAL_LONG(&zexptime, exptime); - ZVAL_NULL(&zresult_cas); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zvalue); - ZVAL_COPY(¶ms[3], &zflags); - ZVAL_COPY(¶ms[4], &zexptime); - ZVAL_COPY(¶ms[5], &zresult_cas); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_ADD), params, 6); - - MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor(¶ms[3]); - zval_ptr_dtor(¶ms[4]); - zval_ptr_dtor(¶ms[5]); - zval_ptr_dtor (&zcookie); - zval_ptr_dtor (&zkey); - zval_ptr_dtor (&zvalue); - zval_ptr_dtor (&zflags); - zval_ptr_dtor (&zexptime); - zval_ptr_dtor (&zresult_cas); - - return retval; -} - -static -protocol_binary_response_status s_append_prepend_handler (php_memc_event_t event, const void *cookie, const void *key, uint16_t key_len, - const void *data, uint32_t data_len, uint64_t cas, uint64_t *result_cas) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zvalue, zcas, zresult_cas; - zval params[5]; - - if (!MEMC_HAS_CB(event)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_STRINGL(&zvalue, data, data_len); - ZVAL_DOUBLE(&zcas, cas); - ZVAL_NULL(&zresult_cas); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zvalue); - ZVAL_COPY(¶ms[3], &zcas); - ZVAL_COPY(¶ms[4], &zresult_cas); - - retval = s_invoke_php_callback (&MEMC_GET_CB(event), params, 5); - - MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor(¶ms[3]); - zval_ptr_dtor(¶ms[4]); - zval_ptr_dtor (&zcookie); - zval_ptr_dtor (&zkey); - zval_ptr_dtor (&zvalue); - zval_ptr_dtor (&zcas); - zval_ptr_dtor (&zresult_cas); - - return retval; -} - -static -protocol_binary_response_status s_append_handler (const void *cookie, const void *key, uint16_t key_len, - const void *data, uint32_t data_len, uint64_t cas, uint64_t *result_cas) -{ - return - s_append_prepend_handler (MEMC_SERVER_ON_APPEND, cookie, key, key_len, data, data_len, cas, result_cas); -} - -static -protocol_binary_response_status s_prepend_handler (const void *cookie, const void *key, uint16_t key_len, - const void *data, uint32_t data_len, uint64_t cas, uint64_t *result_cas) -{ - return - s_append_prepend_handler (MEMC_SERVER_ON_PREPEND, cookie, key, key_len, data, data_len, cas, result_cas); -} - -static -protocol_binary_response_status s_incr_decr_handler (php_memc_event_t event, const void *cookie, const void *key, uint16_t key_len, uint64_t delta, - uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zdelta, zinital, zexpiration, zresult, zresult_cas; - zval params[7]; - - if (!MEMC_HAS_CB(event)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_LONG(&zdelta, (long) delta); - ZVAL_LONG(&zinital, (long) initial); - ZVAL_LONG(&zexpiration, (long) expiration); - ZVAL_LONG(&zresult, 0); - ZVAL_NULL(&zresult_cas); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zdelta); - ZVAL_COPY(¶ms[3], &zinital); - ZVAL_COPY(¶ms[4], &zexpiration); - ZVAL_COPY(¶ms[5], &zresult); - ZVAL_COPY(¶ms[6], &zresult_cas); - - retval = s_invoke_php_callback (&MEMC_GET_CB(event), params, 7); - - *result = (uint64_t)zval_get_long(&zresult); - - MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor(¶ms[3]); - zval_ptr_dtor(¶ms[4]); - zval_ptr_dtor(¶ms[5]); - zval_ptr_dtor(¶ms[6]); - zval_ptr_dtor (&zcookie); - zval_ptr_dtor (&zkey); - zval_ptr_dtor (&zdelta); - zval_ptr_dtor (&zinital); - zval_ptr_dtor (&zexpiration); - zval_ptr_dtor (&zresult); - zval_ptr_dtor (&zresult_cas); - - return retval; -} - -static -protocol_binary_response_status s_increment_handler (const void *cookie, const void *key, uint16_t key_len, uint64_t delta, - uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) -{ - return - s_incr_decr_handler (MEMC_SERVER_ON_INCREMENT, cookie, key, key_len, delta, initial, expiration, result, result_cas); -} - -static -protocol_binary_response_status s_decrement_handler (const void *cookie, const void *key, uint16_t key_len, uint64_t delta, - uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) -{ - return - s_incr_decr_handler (MEMC_SERVER_ON_DECREMENT, cookie, key, key_len, delta, initial, expiration, result, result_cas); -} - -static -protocol_binary_response_status s_delete_handler (const void *cookie, const void *key, - uint16_t key_len, uint64_t cas) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zcas; - zval params[3]; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_DELETE)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_DOUBLE(&zcas, (double) cas); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zcas); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_DELETE), params, 3); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor(&zcookie); - zval_ptr_dtor(&zkey); - zval_ptr_dtor(&zcas); - return retval; -} - -static -protocol_binary_response_status s_flush_handler(const void *cookie, uint32_t when) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zwhen; - zval params[2]; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_FLUSH)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zwhen); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_FLUSH), params, 2); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(&zcookie); - zval_ptr_dtor(&zwhen); - return retval; -} - -static -protocol_binary_response_status s_get_handler (const void *cookie, const void *key, uint16_t key_len, - memcached_binary_protocol_get_response_handler response_handler) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zvalue, zflags, zresult_cas; - zval params[5]; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_GET)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zvalue); - ZVAL_COPY(¶ms[3], &zflags); - ZVAL_COPY(¶ms[4], &zresult_cas); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_GET), params, 5); - - /* Succeeded in getting the key */ - if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { - uint32_t flags = 0; - uint64_t result_cas = 0; - - if (Z_TYPE(zvalue) == IS_NULL) { - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor(¶ms[3]); - zval_ptr_dtor(¶ms[4]); - zval_ptr_dtor(&zcookie); - zval_ptr_dtor(&zkey); - zval_ptr_dtor(&zvalue); - zval_ptr_dtor(&zflags); - zval_ptr_dtor(&zresult_cas); - return PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; - } - - if (Z_TYPE(zvalue) != IS_STRING) { - convert_to_string (&zvalue); - } - - if (Z_TYPE(zflags) == IS_LONG) { - flags = Z_LVAL(zflags); - } - - MEMC_MAKE_RESULT_CAS(zresult_cas, result_cas); - retval = response_handler(cookie, key, key_len, Z_STRVAL(zvalue), Z_STRLEN(zvalue), flags, result_cas); - } - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor(¶ms[3]); - zval_ptr_dtor(¶ms[4]); - zval_ptr_dtor (&zcookie); - zval_ptr_dtor (&zkey); - zval_ptr_dtor (&zvalue); - zval_ptr_dtor (&zflags); - zval_ptr_dtor (&zresult_cas); - return retval; -} - -static -protocol_binary_response_status s_noop_handler(const void *cookie) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie; - zval params[1]; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_NOOP)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_COPY(¶ms[0], &zcookie); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_NOOP), params, 1); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor (&zcookie); - return retval; -} - -static -protocol_binary_response_status s_quit_handler(const void *cookie) -{ - zval params[1]; - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_QUIT)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_COPY(¶ms[0], &zcookie); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_QUIT), params, 1); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor (&zcookie); - return retval; -} - - - -static -protocol_binary_response_status s_set_replace_handler (php_memc_event_t event, const void *cookie, const void *key, uint16_t key_len, const void *data, - uint32_t data_len, uint32_t flags, uint32_t expiration, uint64_t cas, uint64_t *result_cas) -{ - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zdata, zflags, zexpiration, zcas, zresult_cas; - zval params[7]; - - if (!MEMC_HAS_CB(event)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_STRINGL(&zdata, ((char *) data), (int) data_len); - ZVAL_LONG(&zflags, (long) flags); - ZVAL_LONG(&zexpiration, (long) expiration); - ZVAL_DOUBLE(&zcas, (double) cas); - ZVAL_NULL(&zresult_cas); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zdata); - ZVAL_COPY(¶ms[3], &zflags); - ZVAL_COPY(¶ms[4], &zexpiration); - ZVAL_COPY(¶ms[5], &zcas); - ZVAL_COPY(¶ms[6], &zresult_cas); - - retval = s_invoke_php_callback (&MEMC_GET_CB(event), params, 7); - - MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor(¶ms[3]); - zval_ptr_dtor(¶ms[4]); - zval_ptr_dtor(¶ms[5]); - zval_ptr_dtor(¶ms[6]); - zval_ptr_dtor (&zcookie); - zval_ptr_dtor (&zkey); - zval_ptr_dtor (&zdata); - zval_ptr_dtor (&zflags); - zval_ptr_dtor (&zexpiration); - zval_ptr_dtor (&zcas); - zval_ptr_dtor (&zresult_cas); - - return retval; -} - -static -protocol_binary_response_status s_replace_handler (const void *cookie, const void *key, uint16_t key_len, const void *data, - uint32_t data_len, uint32_t flags, uint32_t expiration, uint64_t cas, uint64_t *result_cas) -{ - return - s_set_replace_handler (MEMC_SERVER_ON_REPLACE, cookie, key, key_len, data, data_len, flags, expiration, cas, result_cas); -} - -static -protocol_binary_response_status s_set_handler (const void *cookie, const void *key, uint16_t key_len, const void *data, - uint32_t data_len, uint32_t flags, uint32_t expiration, uint64_t cas, uint64_t *result_cas) -{ - return - s_set_replace_handler (MEMC_SERVER_ON_SET, cookie, key, key_len, data, data_len, flags, expiration, cas, result_cas); -} - -static -protocol_binary_response_status s_stat_handler (const void *cookie, const void *key, uint16_t key_len, - memcached_binary_protocol_stat_response_handler response_handler) -{ - zval params[3]; - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zbody; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_STAT)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_NULL(&zbody); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zbody); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_STAT), params, 3); - - if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { - if (Z_TYPE(zbody) == IS_NULL) { - retval = response_handler(cookie, NULL, 0, NULL, 0); - } - else { - if (Z_TYPE(zbody) != IS_STRING) { - convert_to_string(&zbody); - } - retval = response_handler(cookie, key, key_len, Z_STRVAL(zbody), (uint32_t) Z_STRLEN(zbody)); - } - } - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(¶ms[2]); - zval_ptr_dtor (&zcookie); - zval_ptr_dtor (&zkey); - zval_ptr_dtor (&zbody); - return retval; -} - -static -protocol_binary_response_status s_version_handler (const void *cookie, - memcached_binary_protocol_version_response_handler response_handler) -{ - zval params[2]; - protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zversion; - - if (!MEMC_HAS_CB(MEMC_SERVER_ON_VERSION)) { - return retval; - } - - MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - - ZVAL_NULL(&zversion); - - ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zversion); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_VERSION), params, 2); - - if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { - if (Z_TYPE(zversion) != IS_STRING) { - convert_to_string(&zversion); - } - - retval = response_handler (cookie, Z_STRVAL(zversion), (uint32_t) Z_STRLEN(zversion)); - } - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor (&zcookie); - zval_ptr_dtor (&zversion); - return retval; -} - - -// libevent callbacks - -static -void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg) -{ - int rc; - short flags = 0; - php_memc_client_t *client = (php_memc_client_t *) arg; - memcached_protocol_event_t events; - - if (!client->on_connect_invoked) { - if (MEMC_HAS_CB(MEMC_SERVER_ON_CONNECT)) { - zval zremoteip, zremoteport; - zval params[2]; - protocol_binary_response_status retval; - - struct sockaddr_in addr_in; - socklen_t addr_in_len = sizeof(addr_in); - - if (getpeername (fd, (struct sockaddr *) &addr_in, &addr_in_len) == 0) { - ZVAL_STRING(&zremoteip, inet_ntoa (addr_in.sin_addr)); - ZVAL_LONG(&zremoteport, ntohs (addr_in.sin_port)); - } else { - php_error_docref(NULL, E_WARNING, "getpeername failed: %s", strerror (errno)); - ZVAL_NULL(&zremoteip); - ZVAL_NULL(&zremoteport); - } - - ZVAL_COPY(¶ms[0], &zremoteip); - ZVAL_COPY(¶ms[1], &zremoteport); - - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_CONNECT), params, 2); - - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(&zremoteip); - zval_ptr_dtor(&zremoteport); - - if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS) { - memcached_protocol_client_destroy (client->protocol_client); - efree (client); - evutil_closesocket (fd); - return; - } - } - client->on_connect_invoked = 1; - } - - events = memcached_protocol_client_work (client->protocol_client); - - if (events & MEMCACHED_PROTOCOL_ERROR_EVENT) { - memcached_protocol_client_destroy (client->protocol_client); - efree (client); - evutil_closesocket (fd); - return; - } - - if (events & MEMCACHED_PROTOCOL_WRITE_EVENT) { - flags = EV_WRITE; - } - - if (events & MEMCACHED_PROTOCOL_READ_EVENT) { - flags |= EV_READ; - } - - rc = event_base_once (client->event_base, fd, flags, s_handle_memcached_event, client, NULL); - if (rc != 0) { - php_error_docref (NULL, E_WARNING, "Failed to schedule events"); - } -} - -static -void s_accept_cb (evutil_socket_t fd, short what, void *arg) -{ - int rc; - php_memc_client_t *client; - struct sockaddr_storage addr; - socklen_t addr_len; - evutil_socket_t sock; - - php_memc_proto_handler_t *handler = (php_memc_proto_handler_t *) arg; - - /* Accept the connection */ - addr_len = sizeof (addr); - sock = accept (fd, (struct sockaddr *) &addr, &addr_len); - - if (sock == -1) { - php_error_docref (NULL, E_WARNING, "Failed to accept the client: %s", strerror (errno)); - return; - } - - client = ecalloc (1, sizeof (php_memc_client_t)); - client->protocol_client = memcached_protocol_create_client (handler->protocol_handle, sock); - client->event_base = handler->event_base; - client->on_connect_invoked = 0; - - if (!client->protocol_client) { - php_error_docref (NULL, E_WARNING, "Failed to allocate protocol client"); - efree (client); - evutil_closesocket (sock); - return; - } - - // TODO: this should timeout - rc = event_base_once (handler->event_base, sock, EV_READ, s_handle_memcached_event, client, NULL); - - if (rc != 0) { - php_error_docref (NULL, E_WARNING, "Failed to add event for client"); - memcached_protocol_client_destroy (client->protocol_client); - efree (client); - evutil_closesocket (sock); - return; - } -} - -php_memc_proto_handler_t *php_memc_proto_handler_new () -{ - php_memc_proto_handler_t *handler = ecalloc (1, sizeof (php_memc_proto_handler_t)); - - handler->protocol_handle = memcached_protocol_create_instance (); - assert (handler->protocol_handle); - - memset (&handler->callbacks, 0, sizeof (memcached_binary_protocol_callback_st)); - - handler->callbacks.interface_version = MEMCACHED_PROTOCOL_HANDLER_V1; - handler->callbacks.interface.v1.add = s_add_handler; - handler->callbacks.interface.v1.append = s_append_handler; - handler->callbacks.interface.v1.decrement = s_decrement_handler; - handler->callbacks.interface.v1.delete_object = s_delete_handler; - handler->callbacks.interface.v1.flush_object = s_flush_handler; - handler->callbacks.interface.v1.get = s_get_handler; - handler->callbacks.interface.v1.increment = s_increment_handler; - handler->callbacks.interface.v1.noop = s_noop_handler; - handler->callbacks.interface.v1.prepend = s_prepend_handler; - handler->callbacks.interface.v1.quit = s_quit_handler; - handler->callbacks.interface.v1.replace = s_replace_handler; - handler->callbacks.interface.v1.set = s_set_handler; - handler->callbacks.interface.v1.stat = s_stat_handler; - handler->callbacks.interface.v1.version = s_version_handler; - - memcached_binary_protocol_set_callbacks(handler->protocol_handle, &handler->callbacks); - return handler; -} - -static -evutil_socket_t s_create_listening_socket (const char *spec) -{ - evutil_socket_t sock; - struct sockaddr_storage addr; - int addr_len; - - int rc; - - addr_len = sizeof (struct sockaddr); - rc = evutil_parse_sockaddr_port (spec, (struct sockaddr *) &addr, &addr_len); - if (rc != 0) { - php_error_docref(NULL, E_WARNING, "Failed to parse bind address"); - return -1; - } - - sock = socket (AF_INET, SOCK_STREAM, 0); - if (sock < 0) { - php_error_docref(NULL, E_WARNING, "socket failed: %s", strerror (errno)); - return -1; - } - - rc = bind (sock, (struct sockaddr *) &addr, addr_len); - if (rc < 0) { - php_error_docref(NULL, E_WARNING, "bind failed: %s", strerror (errno)); - return -1; - } - - rc = listen (sock, 1024); - if (rc < 0) { - php_error_docref(NULL, E_WARNING, "listen failed: %s", strerror (errno)); - return -1; - } - - rc = evutil_make_socket_nonblocking (sock); - if (rc != 0) { - php_error_docref(NULL, E_WARNING, "failed to make socket non-blocking: %s", strerror (errno)); - return -1; - } - - rc = evutil_make_listen_socket_reuseable (sock); - if (rc != 0) { - php_error_docref(NULL, E_WARNING, "failed to make socket reuseable: %s", strerror (errno)); - return -1; - } - - rc = evutil_make_socket_closeonexec (sock); - if (rc != 0) { - php_error_docref(NULL, E_WARNING, "failed to make socket closeonexec: %s", strerror (errno)); - return -1; - } - return sock; -} - -zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t *handler, zend_string *address) -{ - struct event *accept_event; - evutil_socket_t sock = s_create_listening_socket (address->val); - - if (sock == -1) { - return 0; - } - - handler->event_base = event_base_new(); - if (!handler->event_base) { - php_error_docref(NULL, E_ERROR, "failed to allocate memory: %s", strerror (errno)); - } - accept_event = event_new (handler->event_base, sock, EV_READ | EV_PERSIST, s_accept_cb, handler); - if (!accept_event) { - php_error_docref(NULL, E_ERROR, "failed to allocate memory: %s", strerror (errno)); - } - event_add (accept_event, NULL); - - switch (event_base_dispatch (handler->event_base)) { - case -1: - php_error_docref(NULL, E_ERROR, "event_base_dispatch() failed: %s", strerror (errno)); - return 0; - break; - - case 1: - php_error_docref(NULL, E_ERROR, "no events registered"); - return 0; - break; - - default: - return 1; - break; - } -} - -void php_memc_proto_handler_destroy (php_memc_proto_handler_t **ptr) -{ - php_memc_proto_handler_t *handler = *ptr; - - if (handler->protocol_handle) - memcached_protocol_destroy_instance (handler->protocol_handle); - - efree (handler); - *ptr = NULL; -} -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim: noet sw=4 ts=4 fdm=marker: - */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_server.h php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_server.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_server.h 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_server.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Mikko Koppanen | - +----------------------------------------------------------------------+ -*/ - -#ifndef _PHP_MEMCACHED_SERVER_H_ -# define _PHP_MEMCACHED_SERVER_H_ - -#ifdef HAVE_MEMCACHED_PROTOCOL - -#include - -/* - Opaque structure -*/ -typedef struct _php_memc_proto_handler_t php_memc_proto_handler_t; - -/* - Functions -*/ -php_memc_proto_handler_t *php_memc_proto_handler_new (); - -void php_memc_proto_handler_destroy (php_memc_proto_handler_t **ptr); - -zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t *h, zend_string *address); - -#endif - -#endif diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_session.c php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_session.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_session.c 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_session.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,554 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009-2010 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#include "php_memcached.h" -#include "php_memcached_private.h" -#include "php_memcached_session.h" - -#include "Zend/zend_smart_str_public.h" - -extern ZEND_DECLARE_MODULE_GLOBALS(php_memcached) - -#define REALTIME_MAXDELTA 60*60*24*30 - -ps_module ps_mod_memcached = { - PS_MOD_UPDATE_TIMESTAMP(memcached) -}; - -typedef struct { - zend_bool is_persistent; - zend_bool has_sasl_data; - zend_bool is_locked; - zend_string *lock_key; -} php_memcached_user_data; - -#ifndef MIN -# define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#ifndef MAX -# define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - -static - int le_memc_sess; - -static -int s_memc_sess_list_entry(void) -{ - return le_memc_sess; -} - -static -void s_destroy_mod_data(memcached_st *memc) -{ - php_memcached_user_data *user_data = memcached_get_user_data(memc); - -#ifdef HAVE_MEMCACHED_SASL - if (user_data->has_sasl_data) { - memcached_destroy_sasl_auth_data(memc); - } -#endif - - memcached_free(memc); - pefree(memc, user_data->is_persistent); - pefree(user_data, user_data->is_persistent); -} - -ZEND_RSRC_DTOR_FUNC(php_memc_sess_dtor) -{ - if (res->ptr) { - s_destroy_mod_data((memcached_st *) res->ptr); - res->ptr = NULL; - } -} - -int php_memc_session_minit(int module_number) -{ - le_memc_sess = - zend_register_list_destructors_ex(NULL, php_memc_sess_dtor, "Memcached Sessions persistent connection", module_number); - - php_session_register_module(ps_memcached_ptr); - return SUCCESS; -} - -static -time_t s_adjust_expiration(zend_long expiration) -{ - if (expiration <= REALTIME_MAXDELTA) { - return expiration; - } else { - return time(NULL) + expiration; - } -} - -static -time_t s_lock_expiration() -{ - if (MEMC_SESS_INI(lock_expiration) > 0) { - return s_adjust_expiration(MEMC_SESS_INI(lock_expiration)); - } - else { - zend_long max_execution_time = zend_ini_long(ZEND_STRL("max_execution_time"), 0); - if (max_execution_time > 0) { - return s_adjust_expiration(max_execution_time); - } - } - return 0; -} - -static -time_t s_session_expiration(zend_long maxlifetime) -{ - if (maxlifetime > 0) { - return s_adjust_expiration(maxlifetime); - } - return 0; -} - -static -zend_bool s_lock_session(memcached_st *memc, zend_string *sid) -{ - memcached_return rc; - char *lock_key; - size_t lock_key_len; - time_t expiration; - zend_long wait_time, retries; - php_memcached_user_data *user_data = memcached_get_user_data(memc); - - lock_key_len = spprintf(&lock_key, 0, "lock.%s", sid->val); - expiration = s_lock_expiration(); - - wait_time = MEMC_SESS_INI(lock_wait_min); - retries = MEMC_SESS_INI(lock_retries); - - do { - rc = memcached_add(memc, lock_key, lock_key_len, "1", sizeof ("1") - 1, expiration, 0); - - switch (rc) { - - case MEMCACHED_SUCCESS: - user_data->lock_key = zend_string_init(lock_key, lock_key_len, user_data->is_persistent); - user_data->is_locked = 1; - break; - - case MEMCACHED_NOTSTORED: - case MEMCACHED_DATA_EXISTS: - if (retries > 0) { - usleep(wait_time * 1000); - wait_time = MIN(MEMC_SESS_INI(lock_wait_max), wait_time * 2); - } - break; - - default: - php_error_docref(NULL, E_WARNING, "Failed to write session lock: %s", memcached_strerror (memc, rc)); - break; - } - } while (!user_data->is_locked && retries-- > 0); - - efree(lock_key); - return user_data->is_locked; -} - -static -void s_unlock_session(memcached_st *memc) -{ - php_memcached_user_data *user_data = memcached_get_user_data(memc); - - if (user_data->is_locked) { - memcached_delete(memc, user_data->lock_key->val, user_data->lock_key->len, 0); - user_data->is_locked = 0; - zend_string_release (user_data->lock_key); - } -} - -static -zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) -{ -#define check_set_behavior(behavior, value) \ - int b = (behavior); \ - uint64_t v = (value); \ - if (v != memcached_behavior_get(memc, b)) { \ - memcached_return rc; \ - if ((rc = memcached_behavior_set(memc, b, v)) != MEMCACHED_SUCCESS) { \ - if (!silent) { \ - php_error_docref(NULL, E_WARNING, "failed to initialise session memcached configuration: %s", memcached_strerror(memc, rc)); \ - } \ - return 0; \ - } \ - } - - if (MEMC_SESS_INI(binary_protocol_enabled)) { - check_set_behavior(MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); - } - - if (MEMC_SESS_INI(consistent_hash_enabled)) { - check_set_behavior(MEMC_SESS_INI(consistent_hash_type), 1); - } - - if (MEMC_SESS_INI(server_failure_limit)) { - check_set_behavior(MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, MEMC_SESS_INI(server_failure_limit)); - } - - if (MEMC_SESS_INI(number_of_replicas)) { - check_set_behavior(MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, MEMC_SESS_INI(number_of_replicas)); - } - - if (MEMC_SESS_INI(randomize_replica_read_enabled)) { - check_set_behavior(MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1); - } - - if (MEMC_SESS_INI(remove_failed_servers_enabled)) { - check_set_behavior(MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1); - } - - if (MEMC_SESS_INI(connect_timeout)) { - check_set_behavior(MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, MEMC_SESS_INI(connect_timeout)); - } - - if (MEMC_SESS_STR_INI(prefix)) { - memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, MEMC_SESS_STR_INI(prefix)); - } - - if (MEMC_SESS_STR_INI(sasl_username) && MEMC_SESS_STR_INI(sasl_password)) { - php_memcached_user_data *user_data; - - if (!php_memc_init_sasl_if_needed()) { - return 0; - } - - check_set_behavior(MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); - - if (memcached_set_sasl_auth_data(memc, MEMC_SESS_STR_INI(sasl_username), MEMC_SESS_STR_INI(sasl_password)) == MEMCACHED_FAILURE) { - php_error_docref(NULL, E_WARNING, "failed to set memcached session sasl credentials"); - return 0; - } - user_data = memcached_get_user_data(memc); - user_data->has_sasl_data = 1; - } - -#undef check_set_behavior - - return 1; -} - -static -void *s_pemalloc_fn(const memcached_st *memc, size_t size, void *context) -{ - zend_bool *is_persistent = memcached_get_user_data(memc); - - return - pemalloc(size, *is_persistent); -} - -static -void s_pefree_fn(const memcached_st *memc, void *mem, void *context) -{ - zend_bool *is_persistent = memcached_get_user_data(memc); - - return - pefree(mem, *is_persistent); -} - -static -void *s_perealloc_fn(const memcached_st *memc, void *mem, const size_t size, void *context) -{ - zend_bool *is_persistent = memcached_get_user_data(memc); - - return - perealloc(mem, size, *is_persistent); -} - -static -void *s_pecalloc_fn(const memcached_st *memc, size_t nelem, const size_t elsize, void *context) -{ - zend_bool *is_persistent = memcached_get_user_data(memc); - - return - pecalloc(nelem, elsize, *is_persistent); -} - - -static -memcached_st *s_init_mod_data (const memcached_server_list_st servers, zend_bool is_persistent) -{ - void *buffer; - php_memcached_user_data *user_data; - memcached_st *memc; - - buffer = pecalloc(1, sizeof(memcached_st), is_persistent); - memc = memcached_create (buffer); - - if (!memc) { - php_error_docref(NULL, E_ERROR, "failed to allocate memcached structure"); - /* not reached */ - } - - memcached_set_memory_allocators(memc, s_pemalloc_fn, s_pefree_fn, s_perealloc_fn, s_pecalloc_fn, NULL); - - user_data = pecalloc(1, sizeof(php_memcached_user_data), is_persistent); - user_data->is_persistent = is_persistent; - user_data->has_sasl_data = 0; - user_data->lock_key = NULL; - user_data->is_locked = 0; - - memcached_set_user_data(memc, user_data); - memcached_server_push (memc, servers); - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1); - return memc; -} - -PS_OPEN_FUNC(memcached) -{ - memcached_st *memc = NULL; - char *plist_key = NULL; - size_t plist_key_len = 0; - - memcached_server_list_st servers; - - // Fail on incompatible PERSISTENT identifier (removed in php-memcached 3.0) - if (strstr(save_path, "PERSISTENT=")) { - php_error_docref(NULL, E_WARNING, "failed to parse session.save_path: PERSISTENT is replaced by memcached.sess_persistent = On"); - PS_SET_MOD_DATA(NULL); - return FAILURE; - } - - // First parse servers - servers = memcached_servers_parse(save_path); - - if (!servers) { - php_error_docref(NULL, E_WARNING, "failed to parse session.save_path"); - PS_SET_MOD_DATA(NULL); - return FAILURE; - } - - if (MEMC_SESS_INI(persistent_enabled)) { - zend_resource *le_p; - - plist_key_len = spprintf(&plist_key, 0, "memc-session:%s", save_path); - - if ((le_p = zend_hash_str_find_ptr(&EG(persistent_list), plist_key, plist_key_len)) != NULL) { - if (le_p->type == s_memc_sess_list_entry()) { - memc = (memcached_st *) le_p->ptr; - - if (!s_configure_from_ini_values(memc, 1)) { - // Remove existing plist entry - zend_hash_str_del(&EG(persistent_list), plist_key, plist_key_len); - memc = NULL; - } - else { - efree(plist_key); - PS_SET_MOD_DATA(memc); - memcached_server_list_free(servers); - return SUCCESS; - } - } - } - } - - memc = s_init_mod_data(servers, MEMC_SESS_INI(persistent_enabled)); - memcached_server_list_free(servers); - - if (!s_configure_from_ini_values(memc, 0)) { - if (plist_key) { - efree(plist_key); - } - s_destroy_mod_data(memc); - PS_SET_MOD_DATA(NULL); - return FAILURE; - } - - if (plist_key) { - zend_resource le; - - le.type = s_memc_sess_list_entry(); - le.ptr = memc; - - GC_SET_REFCOUNT(&le, 1); - - /* plist_key is not a persistent allocated key, thus we use str_update here */ - if (zend_hash_str_update_mem(&EG(persistent_list), plist_key, plist_key_len, &le, sizeof(le)) == NULL) { - php_error_docref(NULL, E_ERROR, "Could not register persistent entry for the memcached session"); - /* not reached */ - } - efree(plist_key); - } - PS_SET_MOD_DATA(memc); - return SUCCESS; -} - -PS_CLOSE_FUNC(memcached) -{ - php_memcached_user_data *user_data; - memcached_st *memc = PS_GET_MOD_DATA(); - - if (!memc) { - php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); - return FAILURE; - } - - user_data = memcached_get_user_data(memc); - - if (user_data->is_locked) { - s_unlock_session(memc); - } - - if (!user_data->is_persistent) { - s_destroy_mod_data(memc); - } - - PS_SET_MOD_DATA(NULL); - return SUCCESS; -} - -PS_READ_FUNC(memcached) -{ - char *payload = NULL; - size_t payload_len = 0; - uint32_t flags = 0; - memcached_return status; - memcached_st *memc = PS_GET_MOD_DATA(); - - if (!memc) { - php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); - return FAILURE; - } - - if (MEMC_SESS_INI(lock_enabled)) { - if (!s_lock_session(memc, key)) { - php_error_docref(NULL, E_WARNING, "Unable to clear session lock record"); - return FAILURE; - } - } - - payload = memcached_get(memc, key->val, key->len, &payload_len, &flags, &status); - - if (status == MEMCACHED_SUCCESS) { - zend_bool *is_persistent = memcached_get_user_data(memc); - *val = zend_string_init(payload, payload_len, 0); - pefree(payload, *is_persistent); - return SUCCESS; - } else if (status == MEMCACHED_NOTFOUND) { - *val = ZSTR_EMPTY_ALLOC(); - return SUCCESS; - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "error getting session from memcached: %s", memcached_last_error_message(memc)); - return FAILURE; - } -} - -PS_WRITE_FUNC(memcached) -{ - zend_long retries = 1; - memcached_st *memc = PS_GET_MOD_DATA(); - time_t expiration = s_session_expiration(maxlifetime); - - if (!memc) { - php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); - return FAILURE; - } - - /* Set the number of write retry attempts to the number of replicas times the number of attempts to remove a server plus the initial write */ - if (MEMC_SESS_INI(remove_failed_servers_enabled)) { - zend_long replicas, failure_limit; - - replicas = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS); - failure_limit = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT); - - retries = 1 + replicas * (failure_limit + 1); - } - - do { - if (memcached_set(memc, key->val, key->len, val->val, val->len, expiration, 0) == MEMCACHED_SUCCESS) { - return SUCCESS; - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "error saving session to memcached: %s", memcached_last_error_message(memc)); - } - } while (--retries > 0); - - return FAILURE; -} - -PS_DESTROY_FUNC(memcached) -{ - php_memcached_user_data *user_data; - memcached_st *memc = PS_GET_MOD_DATA(); - - if (!memc) { - php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); - return FAILURE; - } - - memcached_delete(memc, key->val, key->len, 0); - user_data = memcached_get_user_data(memc); - - if (user_data->is_locked) { - s_unlock_session(memc); - } - return SUCCESS; -} - -PS_GC_FUNC(memcached) -{ - return SUCCESS; -} - -PS_CREATE_SID_FUNC(memcached) -{ - zend_string *sid; - memcached_st *memc = PS_GET_MOD_DATA(); - - if (!memc) { - sid = php_session_create_id(NULL); - } - else { - int retries = 3; - while (retries-- > 0) { - sid = php_session_create_id((void **) &memc); - - if (memcached_add (memc, sid->val, sid->len, NULL, 0, s_lock_expiration(), 0) == MEMCACHED_SUCCESS) { - break; - } - zend_string_release(sid); - sid = NULL; - } - } - return sid; -} - -PS_VALIDATE_SID_FUNC(memcached) -{ - memcached_st *memc = PS_GET_MOD_DATA(); - - if (php_memcached_exist(memc, key) == MEMCACHED_SUCCESS) { - return SUCCESS; - } else { - return FAILURE; - } -} - -PS_UPDATE_TIMESTAMP_FUNC(memcached) -{ - memcached_st *memc = PS_GET_MOD_DATA(); - time_t expiration = s_session_expiration(maxlifetime); - - if (php_memcached_touch(memc, key->val, key->len, expiration) == MEMCACHED_FAILURE) { - return FAILURE; - } - return SUCCESS; -} -/* }}} */ - diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_session.h php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_session.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/php_memcached_session.h 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/php_memcached_session.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009-2010 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#ifndef PHP_MEMCACHED_SESSION_H -#define PHP_MEMCACHED_SESSION_H - -/* session handler struct */ - -#include "ext/session/php_session.h" - -extern ps_module ps_mod_memcached; -#define ps_memcached_ptr &ps_mod_memcached - -PS_FUNCS_UPDATE_TIMESTAMP(memcached); - -PS_OPEN_FUNC(memcached); -PS_CLOSE_FUNC(memcached); -PS_READ_FUNC(memcached); -PS_WRITE_FUNC(memcached); -PS_DESTROY_FUNC(memcached); -PS_GC_FUNC(memcached); -PS_CREATE_SID_FUNC(memcached); -PS_VALIDATE_SID_FUNC(memcached); -PS_UPDATE_TIMESTAMP_FUNC(memcached); - -/* Called from php_memcached.c */ -int php_memc_session_minit(int module_number); - -#endif /* PHP_MEMCACHED_SESSION_H */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/README.markdown php-memcached-3.1.4+2.2.0/memcached-3.1.3/README.markdown --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/README.markdown 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/README.markdown 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -Build Status ------------- -[![Build Status](https://travis-ci.org/php-memcached-dev/php-memcached.png)](https://travis-ci.org/php-memcached-dev/php-memcached) - -Description ------------ -This is the [PECL memcached](https://pecl.php.net/package/memcached) extension, -using the libmemcached library to connect to memcached servers. - -[memcached](https://memcached.org) is a high-performance, distributed memory -object caching system, generic in nature, but intended for use in speeding up -dynamic web applications by alleviating database load. - -Building --------- - - $ phpize - $ ./configure - $ make - $ make test - -Dependencies ------------- - -php-memcached 3.x: -* Supports PHP 7.0 - 7.2. -* Requires libmemcached 1.x or higher. -* Optionally supports igbinary 2.0 or higher. -* Optionally supports msgpack 2.0 or higher. - -php-memcached 2.x: -* Supports PHP 5.2 - 5.6. -* Requires libmemcached 0.44 or higher. -* Optionally supports igbinary 1.0 or higher. -* Optionally supports msgpack 0.5 or higher. - -[libmemcached](http://libmemcached.org/libMemcached.html) version 1.0.18 or -higher is recommended for best performance and compatibility with memcached -servers. - -[igbinary](https://github.com/igbinary/igbinary) is a faster and more compact -binary serializer for PHP data structures. When installing php-memcached from -source code, the igbinary module must be installed first so that php-memcached -can access its C header files. Load both modules in your `php.ini` at runtime -to begin using igbinary. - -[msgpack](https://msgpack.org) is a faster and more compact data structure -representation that is interoperable with msgpack implementations for other -languages. When installing php-memcached from source code, the msgpack module -must be installed first so that php-memcached can access its C header files. -Load both modules in your `php.ini` at runtime to begin using msgpack. diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/001.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/001.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/001.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/001.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ ---TEST-- -Check for memcached presence ---SKIPIF-- - ---FILE-- - ---EXPECT-- -memcached extension is available diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/add.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/add.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/add.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/add.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ ---TEST-- -Memcached::add() ---SKIPIF-- - ---FILE-- -delete('foo'); -var_dump($m->add('foo', 1, 60)); -var_dump($m->get('foo')); -var_dump($m->add('foo', 2, 60)); -var_dump($m->get('foo')); - - ---EXPECT-- -bool(true) -int(1) -bool(false) -int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/append.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/append.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/append.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/append.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ ---TEST-- -Memcached::append() ---SKIPIF-- - ---FILE-- -delete('foo'); -$m->setOption(Memcached::OPT_COMPRESSION, true); -var_dump($m->append('foo', 'a')); -echo error_get_last()["message"], "\n"; - -$m->setOption(Memcached::OPT_COMPRESSION, false); -$m->delete('foo'); -var_dump($m->append('foo', 'a')); -var_dump($m->get('foo')); -$m->set('foo', 'a'); -var_dump($m->append('foo', 'b')); -var_dump($m->get('foo')); - ---EXPECTF-- -NULL -%s: cannot append/prepend with compression turned on -bool(false) -bool(false) -bool(true) -string(2) "ab" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bad_construct.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bad_construct.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bad_construct.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bad_construct.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ ---TEST-- -Memcached construct with bad arguments ---SKIPIF-- - ---FILE-- -setOption (Memcached::OPT_BINARY_PROTOCOL, true)); - -echo "OK" . PHP_EOL; - ---EXPECTF-- -Warning: Memcached::__construct() expects parameter 1 to be string, object given in %s on line 3 -Memcached::__construct() expects parameter 1 to be string, object given -object(Memcached)#1 (0) { -} - -Warning: Memcached::setOption(): Memcached constructor was not called in %s on line 14 -NULL -OK - diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_16084.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_16084.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_16084.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_16084.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ ---TEST-- -Memcached: Bug #16084 (Crash when addServers is called with an associative array) ---SKIPIF-- - ---FILE-- - array ( 'KEYHERE' => 'localhost', 11211, 3 ), ); -$m = new memcached(); -var_dump($m->addServers($servers)); -$list = $m->getServerList(); - -var_dump ($list[0]["host"], $list[0]["port"]); -echo "OK"; - -?> ---EXPECT-- -bool(true) -string(9) "localhost" -int(11211) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_16959.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_16959.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_16959.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_16959.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ ---TEST-- -Memcached: Bug #16959 (getMulti + BINARY_PROTOCOL problem) ---SKIPIF-- - ---FILE-- - true - )); - -$cache->set('key_0', 'value0'); -$cache->set('key_0_additional', 'value0_additional'); - -// -------------- NORMAL -echo "NORMAL\n"; -$keys = array( 'key_0', 'key_0_additional' ); -$values = $cache->getMulti($keys); -echo $cache->getResultMessage(), "\n"; -echo "Values:\n"; -foreach ($values as $k => $v) { - var_dump($k); - var_dump($v); - var_dump($values[$k]); -} -// --------------- REVERSED KEY ORDER -echo "REVERSED KEY ORDER\n"; -$keys = array( 'key_0_additional', 'key_0' ); -$values = $cache->getMulti($keys); -echo $cache->getResultMessage(), "\n"; -echo "Values:\n"; -foreach ($values as $k => $v) { - var_dump($k); - var_dump($v); - var_dump($values[$k]); -} - ---EXPECT-- -NORMAL -SUCCESS -Values: -string(5) "key_0" -string(6) "value0" -string(6) "value0" -string(16) "key_0_additional" -string(17) "value0_additional" -string(17) "value0_additional" -REVERSED KEY ORDER -SUCCESS -Values: -string(16) "key_0_additional" -string(17) "value0_additional" -string(17) "value0_additional" -string(5) "key_0" -string(6) "value0" -string(6) "value0" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_17137.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_17137.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_17137.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_17137.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ ---TEST-- -Change prefix, pecl bug #17137 ---SKIPIF-- - ---FILE-- - true, - Memcached::OPT_PREFIX_KEY => 'prefix1', - )); - -$memcache2 = memc_get_instance (array ( - Memcached::OPT_BINARY_PROTOCOL => true, - Memcached::OPT_PREFIX_KEY => 'prefix2', - )); - -var_dump($memcache->getOption(Memcached::OPT_PREFIX_KEY)); - -var_dump($memcache->set('test', "val_prefix1", 120)); -var_dump($memcache->get('test')); - - -var_dump($memcache2->getOption(Memcached::OPT_PREFIX_KEY)); - -var_dump($memcache2->set('test', "val_prefix2", 120)); -var_dump($memcache2->get('test')); - - -var_dump($memcache->get('test')); ---EXPECT-- -string(7) "prefix1" -bool(true) -string(11) "val_prefix1" -string(7) "prefix2" -bool(true) -string(11) "val_prefix2" -string(11) "val_prefix1" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_18639.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_18639.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/bug_18639.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/bug_18639.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ ---TEST-- -Memcached::getServerByKey(): Bug pecl#18639 (Segfault in getServerByKey) ---SKIPIF-- - ---FILE-- -set('test', 'test1')); -var_dump($m->getServerByKey('1')); - ---EXPECTF-- -bool(true) -array(3) { - ["host"]=> - string(9) "%s" - ["port"]=> - int(%d) - ["weight"]=> - int(%r[01]%r) -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/cachecallback.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/cachecallback.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/cachecallback.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/cachecallback.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ ---TEST-- -Memcached::get() with cache callback ---SKIPIF-- - ---FILE-- -delete($first_key); -$m->delete($second_key); -$m->delete($third_key); - -var_dump ( -$m->get ($first_key, function (Memcached $memc, $key, &$value, &$expiration) { - $value = "hello"; - $expiration = 10; - return true; - }) -); - -var_dump ($m->get ($first_key)); - -var_dump ( -$m->get ($second_key, function (Memcached $memc, $key, &$value, &$expiration) { - $value = "hello"; - $expiration = 10; - return false; - }) -); - -var_dump ($m->get ($second_key)); - -try { - $m->get ($third_key, function (Memcached $memc, $key, &$value, &$expiration) { - $value = "hello"; - $expiration = 10; - throw new Exception ('this is a test'); - return true; - }); -} catch (Exception $e) { - echo 'Got exception' . PHP_EOL; -} - -var_dump ($m->get ($third_key)); - - -echo "OK" . PHP_EOL; - ---EXPECT-- -string(5) "hello" -string(5) "hello" -bool(false) -bool(false) -Got exception -bool(false) -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/callback_exception_2.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/callback_exception_2.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/callback_exception_2.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/callback_exception_2.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ ---TEST-- -Callback initializer throws and dies ---SKIPIF-- - ---FILE-- -isPersistent()); - throw new RuntimeException('Cb exception'); -} - -function init_cb_die($m, $id) { - echo "ran quitting cb\n"; - die("quit in cb"); -} - -error_reporting(0); - -echo "cb with exception\n"; -try { - $m1 = new Memcached(null, 'init_cb'); -} catch (RuntimeException $e) { - echo $e->getMessage(), "\n"; -} - -echo "cb persistent with exception\n"; -try { - $m2 = new Memcached('foo', 'init_cb'); -} catch (RuntimeException $e) { - echo $e->getMessage(), "\n"; -} - -echo "cb persistent dies\n"; -try { - $m3 = new Memcached('bar', 'init_cb_die'); -} catch (RuntimeException $e) { - echo $e->getMessage(), "\n"; -} -echo "not run\n"; - ---EXPECT-- -cb with exception -ran throwing cb -bool(false) -Cb exception -cb persistent with exception -ran throwing cb -bool(true) -Cb exception -cb persistent dies -ran quitting cb -quit in cb diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/callback_exception.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/callback_exception.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/callback_exception.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/callback_exception.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ ---TEST-- -make sure that callback exception behaves correctly ---SKIPIF-- - ---FILE-- - ---EXPECT-- -success -success -empty_cb called -success -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/cas_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/cas_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/cas_multi.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/cas_multi.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ ---TEST-- -Memcached multi fetch cas & set cas ---SKIPIF-- - ---FILE-- - 1, - 'cas_test_2' => 2, -); - -foreach ($data as $key => $v) { - $m->delete($key); -} - -$m->setMulti($data, 10); -$actual = $m->getMulti(array_keys($data), Memcached::GET_EXTENDED); - -foreach ($actual as $key => $v) { - if (is_null($v['cas'])) { - echo "missing cas token(s)\n"; - echo "data: "; - var_dump($data); - echo "actual data: "; - var_dump($actual); - return; - } - - $v = $m->cas($v['cas'], $key, 11); - if (!$v) { - echo "Error setting key: $key value: 11 with CAS: ", $v['cas'], "\n"; - return; - } - $v = $m->get($key); - if ($v !== 11) { - echo "Wanted $key to be 11, value is: "; - var_dump($v); - return; - } -} - -if (array_keys($actual) !== array_keys($data)) { - echo "missing value(s)\n"; - echo "data :"; - var_dump($data); - echo "actual data: "; - var_dump($actual); - return; -} - -echo "OK\n"; - -?> ---EXPECT-- -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/cas.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/cas.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/cas.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/cas.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ ---TEST-- -Memcached fetch cas & set cas ---SKIPIF-- - ---FILE-- -delete('cas_test'); - -$m->set('cas_test', 'hello'); -$cas_token = $m->get('cas_test', null, Memcached::GET_EXTENDED)['cas']; - -$v = $m->cas($cas_token, 'cas_test', 0); -if ($v != true) { - echo "CAS failed"; -} - -echo "OK\n"; -?> ---EXPECT-- -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/check_if_persistent.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/check_if_persistent.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/check_if_persistent.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/check_if_persistent.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ ---TEST-- -Check if persistent object is persistent ---SKIPIF-- - ---FILE-- -setOption(Memcached::OPT_PREFIX_KEY, "foo_"); - -var_dump($m1->isPersistent()); - -$m1 = new Memcached('id1'); -var_dump($m1->isPersistent()); - -$m2 = new Memcached('id1'); -var_dump($m2->isPersistent()); -// this change affects $m1 -$m2->setOption(Memcached::OPT_PREFIX_KEY, "bar_"); - -$m3 = new Memcached('id2'); -var_dump($m3->isPersistent()); - -$m3 = new Memcached(); -var_dump($m3->isPersistent()); - -// objects have the same resource, but they are not the same object. -var_dump($m1 === $m2); -var_dump($m1->getOption(Memcached::OPT_PREFIX_KEY)); ---EXPECT-- -bool(true) -bool(true) -bool(true) -bool(true) -bool(false) -bool(false) -string(4) "bar_" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/check_if_pristine.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/check_if_pristine.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/check_if_pristine.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/check_if_pristine.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ ---TEST-- -Check if persistent object is new or an old persistent one ---SKIPIF-- - ---FILE-- -setOption(Memcached::OPT_PREFIX_KEY, "foo_"); - -var_dump($m1->isPristine()); - -$m1 = new Memcached('id1'); -var_dump($m1->isPristine()); - -$m2 = new Memcached('id1'); -var_dump($m2->isPristine()); -// this change affects $m1 -$m2->setOption(Memcached::OPT_PREFIX_KEY, "bar_"); - -$m3 = new Memcached('id2'); -var_dump($m3->isPristine()); - -$m3 = new Memcached(); -var_dump($m3->isPristine()); ---EXPECT-- -bool(true) -bool(false) -bool(false) -bool(true) -bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/clone.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/clone.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/clone.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/clone.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ ---TEST-- -Test cloning ---SKIPIF-- - ---FILE-- - ---FILE-- -setOption(Memcached::OPT_COMPRESSION, false); - } else { - $m->setOption(Memcached::OPT_COMPRESSION, true); - $m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($set_compression)); - } - - $m->set($key, $value, 1800); - - $value_back = $m->get($key); - var_dump($value === $value_back); -} - -fetch_with_compression($m, 'hello01', $data, 'zlib', 1.3, 4); -fetch_with_compression($m, 'hello02', $data, 'fastlz', 1.3, 4); -fetch_with_compression($m, 'hello03', $data, '', 1.3, 4); -fetch_with_compression($m, 'hello04', $short_data, 'zlib', 1.3, 4); -fetch_with_compression($m, 'hello05', $short_data, 'fastlz', 1.3, 4); -fetch_with_compression($m, 'hello06', $short_data, '', 1.3, 4); -fetch_with_compression($m, 'hello11', $data, 'zlib', 0.3, 4); -fetch_with_compression($m, 'hello12', $data, 'fastlz', 0.3, 4); -fetch_with_compression($m, 'hello13', $data, '', 0.3, 4); -fetch_with_compression($m, 'hello14', $short_data, 'zlib', 0.3, 4); -fetch_with_compression($m, 'hello15', $short_data, 'fastlz', 0.3, 4); -fetch_with_compression($m, 'hello16', $short_data, '', 0.3, 4); -fetch_with_compression($m, 'hello21', $data, 'zlib', 1.3, 2000); -fetch_with_compression($m, 'hello22', $data, 'fastlz', 1.3, 2000); -fetch_with_compression($m, 'hello23', $data, '', 1.3, 2000); -fetch_with_compression($m, 'hello24', $short_data, 'zlib', 1.3, 2000); -fetch_with_compression($m, 'hello25', $short_data, 'fastlz', 1.3, 2000); -fetch_with_compression($m, 'hello26', $short_data, '', 1.3, 2000); -fetch_with_compression($m, 'hello31', $data, 'zlib', 0.3, 2000); -fetch_with_compression($m, 'hello32', $data, 'fastlz', 0.3, 2000); -fetch_with_compression($m, 'hello33', $data, '', 0.3, 2000); -fetch_with_compression($m, 'hello34', $short_data, 'zlib', 0.3, 2000); -fetch_with_compression($m, 'hello35', $short_data, 'fastlz', 0.3, 2000); -fetch_with_compression($m, 'hello36', $short_data, '', 0.3, 2000); -?> ---EXPECT-- -len=[4877] set=[zlib] factor=[1.3] threshold=[4] -bool(true) -len=[4877] set=[fastlz] factor=[1.3] threshold=[4] -bool(true) -len=[4877] set=[] factor=[1.3] threshold=[4] -bool(true) -len=[7] set=[zlib] factor=[1.3] threshold=[4] -bool(true) -len=[7] set=[fastlz] factor=[1.3] threshold=[4] -bool(true) -len=[7] set=[] factor=[1.3] threshold=[4] -bool(true) -len=[4877] set=[zlib] factor=[0.3] threshold=[4] -bool(true) -len=[4877] set=[fastlz] factor=[0.3] threshold=[4] -bool(true) -len=[4877] set=[] factor=[0.3] threshold=[4] -bool(true) -len=[7] set=[zlib] factor=[0.3] threshold=[4] -bool(true) -len=[7] set=[fastlz] factor=[0.3] threshold=[4] -bool(true) -len=[7] set=[] factor=[0.3] threshold=[4] -bool(true) -len=[4877] set=[zlib] factor=[1.3] threshold=[2000] -bool(true) -len=[4877] set=[fastlz] factor=[1.3] threshold=[2000] -bool(true) -len=[4877] set=[] factor=[1.3] threshold=[2000] -bool(true) -len=[7] set=[zlib] factor=[1.3] threshold=[2000] -bool(true) -len=[7] set=[fastlz] factor=[1.3] threshold=[2000] -bool(true) -len=[7] set=[] factor=[1.3] threshold=[2000] -bool(true) -len=[4877] set=[zlib] factor=[0.3] threshold=[2000] -bool(true) -len=[4877] set=[fastlz] factor=[0.3] threshold=[2000] -bool(true) -len=[4877] set=[] factor=[0.3] threshold=[2000] -bool(true) -len=[7] set=[zlib] factor=[0.3] threshold=[2000] -bool(true) -len=[7] set=[fastlz] factor=[0.3] threshold=[2000] -bool(true) -len=[7] set=[] factor=[0.3] threshold=[2000] -bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/compression_types.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/compression_types.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/compression_types.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/compression_types.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ ---TEST-- -Memcached compression test ---SKIPIF-- - ---FILE-- -setOption(Memcached::OPT_COMPRESSION, false); - } else { - $m->setOption(Memcached::OPT_COMPRESSION, true); - $m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($set_compression)); - } - - $m->set($key, $value, 1800); - - if (!$get_compression) { - $m->setOption(Memcached::OPT_COMPRESSION, true); - } else { - $m->setOption(Memcached::OPT_COMPRESSION, true); - $m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($get_compression)); - } - - $value_back = $m->get($key); - var_dump($value === $value_back); -} - -fetch_with_compression($m, 'hello1', $data, 'zlib', 'zlib'); -fetch_with_compression($m, 'hello2', $data, 'zlib', 'fastlz'); -fetch_with_compression($m, 'hello3', $data, 'fastlz', 'fastlz'); -fetch_with_compression($m, 'hello4', $data, 'fastlz', 'zlib'); -fetch_with_compression($m, 'hello5', $data, '', 'zlib'); -fetch_with_compression($m, 'hello6', $data, '', 'fastlz'); -fetch_with_compression($m, 'hello7', $data, 'zlib', ''); -fetch_with_compression($m, 'hello8', $data, 'fastlz', ''); -fetch_with_compression($m, 'hello9', $data, '', ''); -?> ---EXPECT-- -set=[zlib] get=[zlib] -bool(true) -set=[zlib] get=[fastlz] -bool(true) -set=[fastlz] get=[fastlz] -bool(true) -set=[fastlz] get=[zlib] -bool(true) -set=[] get=[zlib] -bool(true) -set=[] get=[fastlz] -bool(true) -set=[zlib] get=[] -bool(true) -set=[fastlz] get=[] -bool(true) -set=[] get=[] -bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/config.inc php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/config.inc --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/config.inc 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/config.inc 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -setOptions ($opts) == false) - echo "Failed to set options" . PHP_EOL; - - $memcached->addServer($host, $port); - if ($memcached->flush() === false) { - return NULL; - } - return $memcached; -} - -function memc_get_instance (array $opts = array (), $persistent_id = null) -{ - return memc_create_instance(MEMC_SERVER_HOST, MEMC_SERVER_PORT, $opts, $persistent_id); -} - -function memc_get_sasl_instance (array $opts = array (), $persistent_id = null) -{ - return memc_create_instance(MEMC_SASL_SERVER_HOST, MEMC_SASL_SERVER_PORT, $opts, $persistent_id); -} - -function memc_run_test ($test_function, $options = array ()) -{ - foreach ($options as $option_set) { - $memc = memc_get_instance ($option_set ['options']); - $test_function ($memc, $option_set); - } - echo "TEST DONE" . PHP_EOL; -} - -function memc_create_combinations ($name, $serializer, $ignore_object_type = false) -{ - return array ( - array ( - 'title' => "$name serializer, ascii protocol", - 'options' => array ( - Memcached::OPT_SERIALIZER => $serializer - ), - 'ignore_object_type' => $ignore_object_type - ), - array ( - 'title' => "$name serializer, binary protocol", - 'options' => array ( - Memcached::OPT_BINARY_PROTOCOL => true, - Memcached::OPT_SERIALIZER => $serializer - ), - 'ignore_object_type' => $ignore_object_type - ), - ); -} - -function memc_get_version($memc) { - $version = $memc->getVersion(); - return array_pop($version); -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/conf_persist.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/conf_persist.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/conf_persist.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/conf_persist.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ ---TEST-- -Conf settings persist. ---SKIPIF-- - ---FILE-- - 'php' -), 'id1'); - -$m1->set('foo', 'bar'); - -for ($i = 1000; $i > 0; $i--) { - $m1 = new Memcached('id1'); - $rv = $m1->get('foo'); - if ($rv !== 'bar') { - echo "Expected bar got:"; - var_dump($rv); - die(); - } - - $prefix = $m1->getOption(Memcached::OPT_PREFIX_KEY); - if ($prefix !== 'php') { - echo "Expected prefix php got:"; - var_dump($prefix); - die(); - } -} - -echo "OK\n"; - -?> ---EXPECT-- -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/construct_persistent.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/construct_persistent.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/construct_persistent.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/construct_persistent.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ ---TEST-- -persistent memcached connection ---SKIPIF-- - ---FILE-- -setOption(Memcached::OPT_PREFIX_KEY, 'php'); -var_dump($m1->getOption(Memcached::OPT_PREFIX_KEY)); - -$m2 = new Memcached('id1'); -var_dump($m1->getOption(Memcached::OPT_PREFIX_KEY)); - -$m3 = new Memcached(); -var_dump($m3->getOption(Memcached::OPT_PREFIX_KEY)); -?> ---EXPECT-- -string(3) "php" -string(3) "php" -string(0) "" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/construct.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/construct.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/construct.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/construct.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---TEST-- -Memcached constructor ---SKIPIF-- - ---FILE-- - ---EXPECT-- -Memcached diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/default_behavior.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/default_behavior.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/default_behavior.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/default_behavior.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ ---TEST-- -Default behaviors ---SKIPIF-- - ---FILE-- -getOption(Memcached::OPT_DISTRIBUTION) == Memcached::DISTRIBUTION_MODULA); -var_dump ($m->getOption(Memcached::OPT_BINARY_PROTOCOL) == false); -var_dump ($m->getOption(Memcached::OPT_CONNECT_TIMEOUT) != 0); - -ini_set('memcached.default_consistent_hash', true); -ini_set('memcached.default_binary_protocol', true); -ini_set('memcached.default_connect_timeout', 1212); - -$m = new Memcached(); -var_dump ($m->getOption(Memcached::OPT_DISTRIBUTION) == Memcached::DISTRIBUTION_CONSISTENT); -var_dump ($m->getOption(Memcached::OPT_BINARY_PROTOCOL) == true); -var_dump ($m->getOption(Memcached::OPT_CONNECT_TIMEOUT) == 1212); - -echo "OK"; - -?> ---EXPECT-- -bool(true) -bool(true) -bool(true) -bool(true) -bool(true) -bool(true) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/deleted.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/deleted.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/deleted.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/deleted.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ ---TEST-- -Memcached store & fetch type correctness ---SKIPIF-- - ---FILE-- -set('eisaleeoo', "foo"); -$m->delete('eisaleeoo'); -$v = $m->get('eisaleeoo'); - -if ($v !== Memcached::GET_ERROR_RETURN_VALUE) { - echo "Wanted: "; - var_dump(Memcached::GET_ERROR_RETURN_VALUE); - echo "Got: "; - var_dump($v); -} - -echo "OK\n"; - -?> ---EXPECT-- -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/deletemulti.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/deletemulti.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/deletemulti.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/deletemulti.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ ---TEST-- -Delete multi ---SKIPIF-- - ---FILE-- - 'foo-data', - 'bar' => 'bar-data', - 'baz' => 'baz-data', - 'lol' => 'lol-data', - 'kek' => 'kek-data', -); - -$keys = array_keys($data); - -$null = null; -$m->setMulti($data, 3600); - -/* Check that all keys were stored */ -var_dump(has_all_keys($keys, $m->getMulti($keys))); - -/* Check that all keys get deleted */ -$deleted = $m->deleteMulti($keys); -var_dump(has_all_keys($keys, $deleted, true)); - -/* Try to get the deleted keys, should give empty array */ -var_dump($m->getMulti($keys)); - -/* ---- same tests for byKey variants ---- */ -$m->setMultiByKey("hi", $data, 3600); - -var_dump(has_all_keys($keys, $m->getMultiByKey('hi', $keys))); - -/* Check that all keys get deleted */ -$deleted = $m->deleteMultiByKey('hi', $keys); -var_dump(has_all_keys($keys, $deleted, true)); - -/* Try to get the deleted keys, should give empty array */ -var_dump($m->getMultiByKey('hi', $keys)); - -/* Test deleting non-existent keys */ -$keys = array(); -$keys[] = "nothere"; -$keys[] = "nothere2"; - -$retval = $m->deleteMulti($keys); - -foreach ($retval as $key => $value) { - if ($value === Memcached::RES_NOTFOUND) { - echo "$key NOT FOUND\n"; - } -} - - -?> ---EXPECT-- -bool(true) -bool(true) -array(0) { -} -bool(true) -bool(true) -array(0) { -} -nothere NOT FOUND -nothere2 NOT FOUND \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/deletemultitypes.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/deletemultitypes.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/deletemultitypes.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/deletemultitypes.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ ---TEST-- -Delete multi key types ---SKIPIF-- - ---FILE-- -deleteMulti($keys); -array_walk($keys, 'dump_types'); - -?> ---EXPECT-- -integer -string -integer -string \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/expire.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/expire.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/expire.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/expire.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ ---TEST-- -Memcached store, fetch & touch expired key ---XFAIL-- -https://code.google.com/p/memcached/issues/detail?id=275 ---SKIPIF-- - ---FILE-- -set($key, "foo", 2); - $v = $m->get($key); - if (!$set || $v != 'foo') { - echo "Error setting key to \"foo\" with 2s expiry.\n"; - return; - } - - sleep(1); - $res = $m->touch($key, 2); - $v = $m->get($key); - - if(!$res || $v != 'foo') { - echo "Error touching key for another 2s expiry.\n"; - var_dump($res); - var_dump($m->getResultMessage()); - var_dump($v); - return; - } - - sleep(3); - $v = $m->get($key); - - if ($v !== Memcached::GET_ERROR_RETURN_VALUE) { - echo "Wanted:\n"; - var_dump(Memcached::GET_ERROR_RETURN_VALUE); - echo "from get of expired value. Got:\n"; - var_dump($v); - return; - } - echo "All OK" . PHP_EOL; -} - -$m = memc_get_instance (array ( - Memcached::OPT_BINARY_PROTOCOL => true - )); - -echo '-- binary protocol' . PHP_EOL; -run_expiry_test ($m); - -$m = memc_get_instance (); - -echo '-- text protocol' . PHP_EOL; -run_expiry_test ($m); - -echo "DONE TEST\n"; -?> ---EXPECT-- --- binary protocol -All OK --- text protocol -All OK -DONE TEST diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/flush_buffers.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/flush_buffers.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/flush_buffers.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/flush_buffers.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ ---TEST-- -Test flushing buffers ---SKIPIF-- - ---FILE-- - 1, - Memcached::OPT_BUFFER_WRITES => 1, - )); - -$key = uniqid ('flush_key_'); - -var_dump ($m->set($key, 'test_val')); - -$m2 = memc_get_instance (); - -var_dump ($m2->get ($key)); -var_dump ($m->flushBuffers ()); -sleep (1); -var_dump ($m2->get ($key)); - -echo "OK" . PHP_EOL; -?> ---EXPECT-- -bool(true) -bool(false) -bool(true) -string(8) "test_val" -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getdelayed.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getdelayed.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getdelayed.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getdelayed.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ ---TEST-- -Memcached getDelayed callback ---SKIPIF-- - ---FILE-- - 'foo-data', - 'bar' => 'bar-data', - 'baz' => 'baz-data', - 'lol' => 'lol-data', - 'kek' => 'kek-data', -); - -foreach ($data as $k => $v) { - $m->set($k, $v, 3600); -} - -function myfunc() { - $datas = func_get_args(); - if (isset($datas[1])) { - var_dump($datas[1]); - } -} - -$m->getDelayed(array_keys($data), true, 'myfunc'); - -?> ---EXPECTF-- -array(4) { - ["key"]=> - string(3) "foo" - ["value"]=> - string(8) "foo-data" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) -} -array(4) { - ["key"]=> - string(3) "bar" - ["value"]=> - string(8) "bar-data" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) -} -array(4) { - ["key"]=> - string(3) "baz" - ["value"]=> - string(8) "baz-data" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) -} -array(4) { - ["key"]=> - string(3) "lol" - ["value"]=> - string(8) "lol-data" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) -} -array(4) { - ["key"]=> - string(3) "kek" - ["value"]=> - string(8) "kek-data" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) -} \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/get_flags.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/get_flags.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/get_flags.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/get_flags.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ ---TEST-- -Memcached::get/getMulti() flags ---SKIPIF-- - ---FILE-- -set ($key1, 'hello1', 20); -$m->set ($key2, 'hello2', 20); - -$value = $m->get($key1); -$extended = $m->get($key1, null, Memcached::GET_EXTENDED); - -var_dump ($value); -var_dump ($extended); - -$values = $m->getMulti(array ($key1, $key2), Memcached::GET_PRESERVE_ORDER); -$extended = $m->getMulti(array ($key1, $key2), Memcached::GET_EXTENDED | Memcached::GET_PRESERVE_ORDER); - -var_dump ($values); -var_dump ($extended); -echo "OK"; - ---EXPECTF-- -string(6) "hello1" -array(3) { - ["value"]=> - string(6) "hello1" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) -} -array(2) { - ["memc.test.%s"]=> - string(6) "hello1" - ["memc.test.%s"]=> - string(6) "hello2" -} -array(2) { - ["memc.test.%s"]=> - array(3) { - ["value"]=> - string(6) "hello1" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) - } - ["memc.test.%s"]=> - array(3) { - ["value"]=> - string(6) "hello2" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) - } -} -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getmulti.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getmulti.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getmulti.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getmulti.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ ---TEST-- -Memcached::getMulti() ---SKIPIF-- - ---FILE-- -setMulti($data)); - -$keys = array_keys($data); -$keys['last'] = new Foo(); - -$v = $m->getMulti($keys); -var_dump(is_array($v)); -var_dump($m->getResultCode() == Memcached::RES_SUCCESS); -if (is_array($v)) { - foreach ($v as $key => $value) { - if (!isset($data[$key]) or $value !== $data[$key]) { - echo "mismatch \$data['$key'] = \n"; - var_dump($data[$key]); - var_dump($value); - } - } -} else { - echo "Result not an array\n"; -} - -var_dump(is_object($keys['last'])); - ---EXPECT-- -bool(true) -bool(true) -bool(true) -bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getserverbykey.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getserverbykey.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getserverbykey.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getserverbykey.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ ---TEST-- -Memcached::getServerByKey() ---SKIPIF-- - ---FILE-- -getServerByKey("a")); - -$m->addServer('localhost', 11211, 1); -$m->addServer('localhost', 11212, 1); -$m->addServer('localhost', 11213, 1); -$m->addServer('localhost', 11214, 1); -$m->addServer('localhost', 11215, 1); - -var_dump($m->getServerByKey("")); -echo $m->getResultMessage(), "\n"; -var_dump($m->getServerByKey("a")); -var_dump($m->getServerByKey("b")); -var_dump($m->getServerByKey("c")); -var_dump($m->getServerByKey("d")); ---EXPECTF-- -bool(false) -bool(false) -A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE -array(%d) { - ["host"]=> - string(%d) "%s" - ["port"]=> - int(%d) - ["weight"]=> - int(0) -} -array(%d) { - ["host"]=> - string(%d) "%s" - ["port"]=> - int(%d) - ["weight"]=> - int(0) -} -array(%d) { - ["host"]=> - string(%d) "%s" - ["port"]=> - int(%d) - ["weight"]=> - int(0) -} -array(%d) { - ["host"]=> - string(%d) "%s" - ["port"]=> - int(%d) - ["weight"]=> - int(0) -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getserverlist.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getserverlist.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/getserverlist.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/getserverlist.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ ---TEST-- -getServerList ---SKIPIF-- - ---FILE-- - array ( 'KEYHERE' => 'localhost', 11211, 3 ), ); -$m = new memcached(); -var_dump($m->getServerList()); -$m->addServers($servers); -var_dump($m->getServerList()); -$m->addServers($servers); -var_dump($m->getServerList()); -$m = new memcached(); -$m->addServer('127.0.0.1', 11211); -var_dump($m->getServerList()); - -echo "OK"; -?> ---EXPECT-- -array(0) { -} -array(1) { - [0]=> - array(3) { - ["host"]=> - string(9) "localhost" - ["port"]=> - int(11211) - ["type"]=> - string(3) "TCP" - } -} -array(2) { - [0]=> - array(3) { - ["host"]=> - string(9) "localhost" - ["port"]=> - int(11211) - ["type"]=> - string(3) "TCP" - } - [1]=> - array(3) { - ["host"]=> - string(9) "localhost" - ["port"]=> - int(11211) - ["type"]=> - string(3) "TCP" - } -} -array(1) { - [0]=> - array(3) { - ["host"]=> - string(9) "127.0.0.1" - ["port"]=> - int(11211) - ["type"]=> - string(3) "TCP" - } -} -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_155.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_155.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_155.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_155.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ ---TEST-- -Test for bug 155 ---SKIPIF-- - ---FILE-- -setOption(Memcached::OPT_BINARY_PROTOCOL, true); -$m->addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); - -$key = 'bug_155_' . uniqid(); - -$m->set ($key, 'test', time() + 86400); - -$m->get ($key); -echo "GET: " . $m->getResultMessage() . PHP_EOL; - -$m->touch ($key, time() + 86400); -echo "TOUCH: " . $m->getResultMessage() . PHP_EOL; - -$m->touch ($key, time() + 86400); -echo "TOUCH: " . $m->getResultMessage() . PHP_EOL; - -$m->get ($key); -echo "GET: " . $m->getResultMessage() . PHP_EOL; - -$m->get ($key); -echo "GET: " . $m->getResultMessage() . PHP_EOL; - -echo "DONE" . PHP_EOL; - ---EXPECT-- -GET: SUCCESS -TOUCH: SUCCESS -TOUCH: SUCCESS -GET: SUCCESS -GET: SUCCESS -DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_21.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_21.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_21.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_21.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ ---TEST-- -Test for Github issue 21 ---SKIPIF-- - ---FILE-- -setOption(Memcached::OPT_BINARY_PROTOCOL, true); - -$m->addServers($newServers); - -$d = $m->get('foo'); - -$m->set('counter', 5); -$n = $m->decrement('counter'); -var_dump($n); - -$n = $m->decrement('counter', 10); -var_dump($n); - -var_dump($m->get('counter')); - -$m->set('counter', 'abc'); -$n = $m->increment('counter'); -var_dump($n); -?> ---EXPECT-- -int(4) -int(0) -int(0) -bool(false) \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_77.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_77.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_77.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_77.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ ---TEST-- -Test for Github issue #77 ---SKIPIF-- - ---FILE-- -touch($key, 5); -var_dump ($mc->getResultCode() == Memcached::RES_NOTFOUND); -$mc->set($key, 1, 5); - -$mc->set($key, 1, 5); -var_dump ($mc->getResultCode() == Memcached::RES_SUCCESS); - -echo "OK\n"; - -?> ---EXPECT-- -bool(true) -bool(true) -OK - diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_90.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_90.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_90.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_90.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ ---TEST-- -Test for GH #90 ---SKIPIF-- - ---FILE-- - true - )); - -// Create a key for use as a lock. If this key already exists, wait till it doesn't exist. -{ - $key = 'LockKey'; - $lockToken = mt_rand(0, mt_getrandmax()); //Random value for ownership verification - - while (true) - { - $casToken = null; - $data = $memcached->get($key, $casToken); - if ($memcached->getResultCode() == Memcached::RES_NOTFOUND) - { - if ($memcached->add($key, $lockToken, 5)) - { - break; - } - } - elseif ($data === false) - { - if ($memcached->cas($casToken, $key, $lockToken, 5)) - { - break; - } - } - - //Sleep 10 milliseconds - usleep(10 * 1000); - } -} - -//Do something here that requires exclusive access to this key - -//Effectively delete our key lock. -{ - $casToken = null; - if ($lockToken == $memcached->get($key, $casToken)) - { - $memcached->cas($casToken, $key, false, 1); - } -} - -//Create 10 keys and then increment them. The first value returned will be wrong. -{ - $keyList = array(); - for ($i = 0; $i < 10; $i++) - { - $keyList[] = $i . '_' . uniqid ('count_value_'); - } - - $valueList = array(); - foreach ($keyList as $key) - { - $valueList[$key] = $memcached->increment($key, 1, 1); - } - - var_dump ($valueList); -} - ---EXPECTF-- -array(10) { - ["0_%s"]=> - int(1) - ["1_%s"]=> - int(1) - ["2_%s"]=> - int(1) - ["3_%s"]=> - int(1) - ["4_%s"]=> - int(1) - ["5_%s"]=> - int(1) - ["6_%s"]=> - int(1) - ["7_%s"]=> - int(1) - ["8_%s"]=> - int(1) - ["9_%s"]=> - int(1) -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_93.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_93.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/gh_93.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/gh_93.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ ---TEST-- -Test for Github issue #93 (double and long overflow) ---SKIPIF-- - ---FILE-- - false - )); - -function testOverflow($m, $value) { - $m->delete('overflow'); - if (true !== $m->set('overflow', $value)) { - echo "Error storing 'overflow' variable\n"; - return false; - } - - if (true !== $m->prepend('overflow', str_repeat('0', 128))) { - echo "Error prepending key\n"; - return false; - } - - $v = @$m->get('overflow'); - if ($v !== $value) { - // At least it doesn't segfault, so we're happy for now - // echo "Error receiving 'overflow' variable\n"; - // return false; - return true; - } - - return true; -} - -if (!testOverflow($m, 10)) { - return; -} - -if (!testOverflow($m, 9.09)) { - return; -} - -echo "OK\n"; -?> ---EXPECT-- -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_64.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_64.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_64.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_64.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ ---TEST-- -64-bit Memcached::increment() decrement() incrementByKey() decrementByKey() ---SKIPIF-- - ---FILE-- -set('foo', 1); -var_dump($m->get('foo')); - -echo "Enormous offset 64-bit\n"; -$m->increment('foo', 0x100000000); -var_dump($m->get('foo')); - -$m->decrement('foo', 0x100000000); -var_dump($m->get('foo')); - -echo "Enormous offset 64-bit by key\n"; -$m->incrementByKey('foo', 'foo', 0x100000000); -var_dump($m->get('foo')); - -$m->decrementByKey('foo', 'foo', 0x100000000); -var_dump($m->get('foo')); - ---EXPECT-- -Normal -int(1) -Enormous offset 64-bit -int(4294967297) -int(1) -Enormous offset 64-bit by key -int(4294967297) -int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_bykey.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_bykey.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_bykey.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_bykey.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ ---TEST-- -Memcached::incrementByKey() Memcached::decrementByKey() ---SKIPIF-- - ---FILE-- -delete('foo'); -var_dump($m->incrementByKey('foo', 'foo', 1)); -var_dump($m->decrementByKey('foo', 'foo', 1)); -var_dump($m->get('foo')); - -echo "Normal\n"; -$m->set('foo', 1); -var_dump($m->get('foo')); -$m->incrementByKey('foo', 'foo'); -var_dump($m->get('foo')); -$m->incrementByKey('foo', 'foo', 2); -var_dump($m->get('foo')); -$m->decrementByKey('foo', 'foo'); -var_dump($m->get('foo')); -$m->decrementByKey('foo', 'foo', 2); -var_dump($m->get('foo')); - -error_reporting(0); - -echo "Negative offset\n"; -error_clear_last(); -$m->incrementByKey('foo', 'foo', -1); -echo error_get_last()["message"], "\n"; -var_dump($m->get('foo')); - -error_clear_last(); -$m->decrementByKey('foo', 'foo', -1); -echo error_get_last()["message"], "\n"; -var_dump($m->get('foo')); - -echo "Enormous offset\n"; -$m->incrementByKey('foo', 'foo', 0x7f000000); -var_dump($m->get('foo')); - -$m->decrementByKey('foo', 'foo', 0x7f000000); -var_dump($m->get('foo')); - ---EXPECT-- -Not there -bool(false) -bool(false) -bool(false) -Normal -int(1) -int(2) -int(4) -int(3) -int(1) -Negative offset -Memcached::incrementByKey(): offset cannot be a negative value -int(1) -Memcached::decrementByKey(): offset cannot be a negative value -int(1) -Enormous offset -int(2130706433) -int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_initial.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_initial.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_initial.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_initial.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ ---TEST-- -Memcached::increment() Memcached::decrement() with initial support ---SKIPIF-- - ---FILE-- - true - )); - -$m->delete('foo'); -var_dump($m->increment('foo', 1, 1)); -var_dump($m->increment('foo', 0)); -$m->delete('foo'); - -var_dump($m->increment('foo', 1, 1)); -var_dump($m->increment('foo', 1, 1)); -var_dump($m->increment('foo', 1, 1)); - -var_dump($m->decrement('foo', 1, 1)); -var_dump($m->decrement('foo', 0)); -$m->delete('foo'); - -$m->deleteByKey('foo', 'foo'); -var_dump($m->incrementByKey('foo', 'foo', 1, 1)); -var_dump($m->incrementByKey('foo', 'foo', 0)); -$m->deleteByKey('foo', 'foo'); - -var_dump($m->incrementByKey('foo', 'foo', 1, 1)); -var_dump($m->incrementByKey('foo', 'foo', 1, 1)); -var_dump($m->incrementByKey('foo', 'foo', 1, 1)); - -var_dump($m->decrementByKey('foo', 'foo', 1, 1)); -var_dump($m->decrementByKey('foo', 'foo', 0)); -$m->deleteByKey('foo', 'foo'); - ---EXPECT-- -int(1) -int(1) -int(1) -int(2) -int(3) -int(2) -int(2) -int(1) -int(1) -int(1) -int(2) -int(3) -int(2) -int(2) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_invalid_key.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_invalid_key.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr_invalid_key.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr_invalid_key.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ ---TEST-- -Memcached::increment() Memcached::decrement() with invalid key ---SKIPIF-- - ---FILE-- -increment('', 1)); -var_dump($m->decrement('', 1)); -?> ---EXPECT-- -bool(false) -bool(false) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/incrdecr.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/incrdecr.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ ---TEST-- -Memcached::increment() Memcached::decrement() ---SKIPIF-- - ---FILE-- -delete('foo'); -var_dump($m->increment('foo', 1)); -var_dump($m->getResultCode()); -var_dump($m->decrement('foo', 1)); -var_dump($m->getResultCode()); -var_dump($m->get('foo')); -var_dump($m->getResultCode()); - -echo "Normal\n"; -$m->set('foo', 1); -var_dump($m->get('foo')); -$m->increment('foo'); -var_dump($m->get('foo')); -$m->increment('foo', 2); -var_dump($m->get('foo')); -$m->decrement('foo'); -var_dump($m->get('foo')); -$m->decrement('foo', 2); -var_dump($m->get('foo')); - -error_reporting(0); - -echo "Negative offset\n"; -error_clear_last(); -$m->increment('foo', -1); -echo error_get_last()["message"], "\n"; -var_dump($m->get('foo')); - -error_clear_last(); -$m->decrement('foo', -1); -echo error_get_last()["message"], "\n"; -var_dump($m->get('foo')); - -echo "Enormous offset\n"; -$m->increment('foo', 0x7f000000); -var_dump($m->get('foo')); - -$m->decrement('foo', 0x7f000000); -var_dump($m->get('foo')); - ---EXPECT-- -Not there -bool(false) -int(16) -bool(false) -int(16) -bool(false) -int(16) -Normal -int(1) -int(2) -int(4) -int(3) -int(1) -Negative offset -Memcached::increment(): offset cannot be a negative value -int(1) -Memcached::decrement(): offset cannot be a negative value -int(1) -Enormous offset -int(2130706433) -int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invalid_options.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invalid_options.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invalid_options.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invalid_options.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ ---TEST-- -Get version ---SKIPIF-- - ---FILE-- -setOption(500, 23423); -var_dump ($m->getResultCode ()); - -echo "OK" . PHP_EOL; -?> ---EXPECTF-- -Warning: Memcached::setOption(): error setting memcached option: INVALID ARGUMENTS in %s on line %d -int(38) -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invoke_callback_2.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invoke_callback_2.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invoke_callback_2.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invoke_callback_2.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ ---TEST-- -Use callback initializer ---SKIPIF-- - ---FILE-- -isPersistent()); - var_dump($id); -} - -function init_cb_fail($m, $id) { - echo "configured, should not be called.\n"; -} - -function init_cb_arg($m, $id) { - var_dump(func_num_args()); - var_dump($id); -} - -function init_nopersist_cb($m, $id) { - var_dump($m->isPersistent()); - var_dump($id); -} - -class Foo extends Memcached { - function __construct($id = null) { - parent::__construct($id, array($this, 'init')); - } - - function init($obj, $id) { - var_dump(func_num_args()); - var_dump($this->isPristine()); - var_dump($this->isPersistent()); - var_dump($id); - } -} - -echo "cb call\n"; -$m1 = new Memcached('foo1', 'init_cb'); - -echo "cb not run\n"; -$m1 = new Memcached('foo1', 'init_cb_fail'); - -echo "cb arg without arg\n"; -$m1 = new Memcached('foo3', 'init_cb_arg'); - -echo "cb arg not persistent\n"; -$m1 = new Memcached(null, 'init_nopersist_cb'); - -echo "cb in object\n"; -$m1 = new Foo(); - -echo "cb persistent in object\n"; -$m1 = new Foo('baz'); - -echo "cb second persistent in object\n"; -$m1 = new Foo('baz'); -?> ---EXPECT-- -cb call -string(9) "Memcached" -bool(true) -string(4) "foo1" -cb not run -cb arg without arg -int(2) -string(4) "foo3" -cb arg not persistent -bool(false) -NULL -cb in object -int(2) -bool(true) -bool(false) -NULL -cb persistent in object -int(2) -bool(true) -bool(true) -string(3) "baz" -cb second persistent in object diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invoke_callback.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invoke_callback.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invoke_callback.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invoke_callback.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ ---TEST-- -Test that callback is invoked on new object ---SKIPIF-- - ---FILE-- -addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); -} - -$m = new Memcached('hi', 'my_func'); -$m = new Memcached('hi', 'my_func'); - -var_dump($m->getServerList()); - -echo "OK\n"; - ---EXPECTF-- -array(1) { - [0]=> - array(3) { - ["host"]=> - string(9) "%s" - ["port"]=> - int(%d) - ["type"]=> - string(3) "TCP" - } -} -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invoke_callback_twice.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invoke_callback_twice.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/invoke_callback_twice.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/invoke_callback_twice.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ ---TEST-- -Test that callback is invoked on new object only once ---SKIPIF-- - ---FILE-- - ---FILE-- - false, - Memcached::OPT_VERIFY_KEY => false - )); -// libmemcached can verify keys, but these are tests are for our own -// function s_memc_valid_key_ascii, so explicitly disable the checks -// that libmemcached can perform. - -echo 'ASCII: SPACES' . PHP_EOL; -var_dump ($ascii->set ('ascii key with spaces', 'this is a test')); -var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo 'ASCII: NEWLINE' . PHP_EOL; -var_dump ($ascii->set ('asciikeywithnewline' . PHP_EOL, 'this is a test')); -var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo 'ASCII: EMPTY' . PHP_EOL; -var_dump ($ascii->set (''/*empty key*/, 'this is a test')); -var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo 'ASCII: TOO LONG' . PHP_EOL; -var_dump ($ascii->set (str_repeat ('1234567890', 512), 'this is a test')); -var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo 'ASCII: GET' . PHP_EOL; -for ($i=0;$i<32;$i++) { - var_dump ($ascii->get ('asciikeywithnonprintablechar-' . chr($i) . '-here')); - var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); -} - -echo 'ASCII: SET' . PHP_EOL; -for ($i=0;$i<32;$i++) { - var_dump ($ascii->set ('asciikeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); - var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); -} - -echo 'OK' . PHP_EOL; - ---EXPECT-- -ASCII: SPACES -bool(false) -bool(true) -ASCII: NEWLINE -bool(false) -bool(true) -ASCII: EMPTY -bool(false) -bool(true) -ASCII: TOO LONG -bool(false) -bool(true) -ASCII: GET -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -ASCII: SET -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/keys_binary.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/keys_binary.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/keys_binary.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/keys_binary.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ ---TEST-- -Test valid and invalid keys - binary ---SKIPIF-- - ---FILE-- - true, - )); - -echo 'BINARY: SPACES' . PHP_EOL; -var_dump ($binary->set ('binary key with spaces', 'this is a test')); -var_dump ($binary->getResultCode () == Memcached::RES_SUCCESS); - -echo 'BINARY: NEWLINE' . PHP_EOL; -var_dump ($binary->set ('binarykeywithnewline' . PHP_EOL, 'this is a test')); -var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo 'BINARY: EMPTY' . PHP_EOL; -var_dump ($binary->set (''/*empty key*/, 'this is a test')); -var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo 'BINARY: TOO LONG' . PHP_EOL; -var_dump ($binary->set (str_repeat ('1234567890', 512), 'this is a test')); -var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo 'BINARY: GET' . PHP_EOL; -// Only newline fails in binary mode (char 10) -for ($i=0;$i<32;$i++) { - $binary->delete ('binarykeywithnonprintablechar-' . chr($i) . '-here'); - var_dump ($binary->get ('binarykeywithnonprintablechar-' . chr($i) . '-here')); - var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); -} - -echo 'BINARY: SET' . PHP_EOL; -// Only newline fails in binary mode (char 10) -for ($i=0;$i<32;$i++) { - var_dump ($binary->set ('binarykeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); - var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - $binary->delete ('binarykeywithnonprintablechar-' . chr($i) . '-here'); -} - -echo 'OK' . PHP_EOL; - ---EXPECT-- -BINARY: SPACES -bool(true) -bool(true) -BINARY: NEWLINE -bool(false) -bool(true) -BINARY: EMPTY -bool(false) -bool(true) -BINARY: TOO LONG -bool(false) -bool(true) -BINARY: GET -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -BINARY: SET -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(false) -bool(true) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/localserver.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/localserver.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/localserver.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/localserver.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ ---TEST-- -Memcached local server test ---SKIPIF-- - ---FILE-- -set($key, array( - 'foo' => 'bar' -), 360); - -var_dump($m->get($key)); -?> ---EXPECT-- -array(1) { - ["foo"]=> - string(3) "bar" -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/multi_order.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/multi_order.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/multi_order.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/multi_order.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ ---TEST-- -Memcached GET_PRESERVE_ORDER flag in getMulti ---SKIPIF-- - ---FILE-- -addServer (MEMC_SERVER_HOST, MEMC_SERVER_PORT); - -$data = array( - 'foo' => 'foo-data', - 'bar' => 'bar-data', - 'baz' => 'baz-data', - 'lol' => 'lol-data', - 'kek' => 'kek-data', -); - -//$m->setMulti($data, 3600); -foreach ($data as $k => $v) { - $m->set($k, $v, 3600); -} - -$keys = array_keys($data); -$keys[] = 'zoo'; -$got = $m->getMulti($keys, Memcached::GET_PRESERVE_ORDER); - -foreach ($got as $k => $v) { - echo "$k $v\n"; -} - -?> ---EXPECT-- -foo foo-data -bar bar-data -baz baz-data -lol lol-data -kek kek-data -zoo diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/no-not-found.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/no-not-found.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/no-not-found.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/no-not-found.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ ---TEST-- -Test that correct return value is returned ---SKIPIF-- - ---FILE-- -addServer('localhost', 5555); // Server should not exist - -$result = $memcached->get('foo_not_exists'); -var_dump ($result === Memcached::GET_ERROR_RETURN_VALUE); - -$result = $memcached->get('foo_not_exists'); -var_dump ($result === Memcached::GET_ERROR_RETURN_VALUE); - -echo "OK\n"; - -?> ---EXPECT-- -bool(true) -bool(true) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/options.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/options.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/options.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/options.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ ---TEST-- -Memcached options ---SKIPIF-- - ---FILE-- -setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_PHP); - -var_dump($m->getOption(Memcached::OPT_COMPRESSION)); -var_dump($m->getOption(Memcached::OPT_SERIALIZER)); -var_dump($m->getOption(Memcached::OPT_SOCKET_SEND_SIZE)); - -$m->setOption(Memcached::OPT_PREFIX_KEY, "\x01"); - -var_dump($m->getOption(Memcached::OPT_HASH) == Memcached::HASH_DEFAULT); -$m->setOption(Memcached::OPT_HASH, Memcached::HASH_MURMUR); -var_dump($m->getOption(Memcached::OPT_HASH) == Memcached::HASH_MURMUR); - - -$m->setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_ZLIB); -var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSION_ZLIB); - -$m->setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_FASTLZ); -var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSION_FASTLZ); - -var_dump($m->setOption(Memcached::OPT_COMPRESSION_TYPE, 0)); -var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSION_FASTLZ); -?> ---EXPECTF-- -bool(true) -int(1) - -Warning: Memcached::getOption(): no servers defined in %s on line %d -NULL - -Warning: Memcached::setOption(): bad key provided in %s on line %d -bool(true) -bool(true) -bool(true) -bool(true) -bool(false) -bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/pr_75.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/pr_75.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/pr_75.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/pr_75.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ ---TEST-- -Wrong return values for binary protocol ---SKIPIF-- - ---FILE-- - true - )); - -$client->set('key1', 'value1'); -echo "set result code: ".$client->getResultCode()."\n"; - -$value = $client->get('key1'); -echo "got $value with result code: ".$client->getResultCode()."\n"; - -var_dump ($client->add('key2', 'value2')); -echo "add result code: ".$client->getResultCode()."\n"; - -echo "OK\n"; - -?> ---EXPECT-- -set result code: 0 -got value1 with result code: 0 -bool(true) -add result code: 0 -OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/prepend.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/prepend.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/prepend.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/prepend.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ ---TEST-- -Memcached::prepend() ---SKIPIF-- - ---FILE-- -delete('foo'); -$m->setOption(Memcached::OPT_COMPRESSION, true); -var_dump($m->prepend('foo', 'a')); - -$m->setOption(Memcached::OPT_COMPRESSION, false); -$m->delete('foo'); -var_dump($m->prepend('foo', 'a')); -var_dump($m->get('foo')); -$m->set('foo', 'a'); -var_dump($m->prepend('foo', 'b')); -var_dump($m->get('foo')); - ---EXPECTF-- -Warning: Memcached::prepend(): cannot append/prepend with compression turned on in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -string(2) "ba" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/replace.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/replace.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/replace.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/replace.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ ---TEST-- -Memcached::replace() ---SKIPIF-- - ---FILE-- -delete('foo'); -var_dump($m->replace('foo', 'bar', 60)); -var_dump($m->get('foo')); - -$m->set('foo', 'kef'); -var_dump($m->replace('foo', 'bar', 60)); -var_dump($m->get('foo')); - ---EXPECT-- -bool(false) -bool(false) -bool(true) -string(3) "bar" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/rescode.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/rescode.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/rescode.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/rescode.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ ---TEST-- -Memcached result codes. ---SKIPIF-- - ---FILE-- -getResultMessage(), "\n"; - -$m->addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT, 1); -echo $m->getResultCode(), "\n"; -echo $m->getResultMessage(), "\n"; - -$m->set('bar_foo', 10); -echo $m->getResultMessage(), "\n"; - -$m->delete('bar_foo'); -echo $m->getResultMessage(), "\n"; - -$m->delete('bar_foo'); -echo $m->getResultCode(), "\n"; -echo $m->getResultMessage(), "\n"; - -$m->set ('asdf_a', 'aa'); -$m->getMulti(array('asdf_a', 'jkhjkhjkb', 'nbahsdgc')); -echo $m->getResultMessage(), "\n"; -$code = $m->getResultCode(); - -$m2 = new Memcached(); -$m2->getMulti(array('asdf_a', 'jkhjkhjkb', 'nbahsdgc')); -echo $m2->getResultCode(), "\n"; -echo $m2->getResultMessage(), "\n"; - -$m2->addServer('127.0.0.1', 7312, 1); -echo $m2->getResultCode(), "\n"; -echo $m2->getResultMessage(), "\n"; - -$m2->delete('bar_foo'); -echo $m2->getResultCode(), "\n"; -echo $m2->getResultMessage(), "\n"; - -var_dump($m->getResultCode() == $code); - -$m = memc_get_instance (array (), 'test1'); -$m2 = new Memcached('test1'); - -$m->delete('moikkamitakuuluu'); -echo $m->getResultMessage(), "\n"; -$m2->set('minapaasetannih', 10, 1); -echo $m->getResultMessage(), "\n"; -echo $m2->getResultMessage(), "\n"; - -$m->delete('bar_foo'); -// clearly "NOT FOUND" -$m->delete('bar_foo'); -$res_m = $m->getResultMessage(); -echo $res_m, "\n"; - -$m2->set('bar_foo', 10); -echo $m->getResultMessage(), "\n"; -echo $m2->getResultMessage(), "\n"; - -$m->delete('bar_foo'); -echo $m->getResultMessage(), "\n"; - -?> ---EXPECTF-- -SUCCESS -%d -SUCCESS -SUCCESS -SUCCESS -%d -NOT FOUND -SUCCESS -%d -NO SERVERS DEFINED -%d -SUCCESS -%d -%rSYSTEM ERROR|WRITE FAILURE|CONNECTION FAILURE%r -bool(true) -NOT FOUND -NOT FOUND -SUCCESS -NOT FOUND -NOT FOUND -SUCCESS -SUCCESS diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/reset_keyprefix.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/reset_keyprefix.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/reset_keyprefix.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/reset_keyprefix.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ ---TEST-- -Cannot reset OPT_PREFIX_KEY #293 ---SKIPIF-- - ---FILE-- -set('key1', 'abc'); -var_dump($m->get('key1')); - -$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); -var_dump($m->get('key1')); - -$m->setOption(Memcached::OPT_PREFIX_KEY, false); -var_dump($m->get('key1')); - -$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); -var_dump($m->get('key1')); - -$m->setOption(Memcached::OPT_PREFIX_KEY, ''); -var_dump($m->get('key1')); - -$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); -var_dump($m->get('key1')); - -$m->setOption(Memcached::OPT_PREFIX_KEY, null); -var_dump($m->get('key1')); ---EXPECTF-- -string(3) "abc" -bool(false) -string(3) "abc" -bool(false) -string(3) "abc" -bool(false) -string(3) "abc" \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/sasl_basic.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/sasl_basic.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/sasl_basic.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/sasl_basic.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ ---TEST-- -Test SASL authentication ---SKIPIF-- - ---INI-- -memcached.use_sasl = on ---FILE-- - true - )); - -var_dump ($m->setSaslAuthData (MEMC_SASL_USER, MEMC_SASL_PASS)); - -$key = uniqid ('sasl_test_'); -var_dump ($m->set ($key, 'set using sasl')); -var_dump ($m->get ($key)); - - -echo "OK" . PHP_EOL; -?> ---EXPECT-- -bool(true) -bool(true) -string(14) "set using sasl" -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_badconf_emptyprefix.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_badconf_emptyprefix.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_badconf_emptyprefix.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_badconf_emptyprefix.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ ---TEST-- -Session bad configurations, prefix ---SKIPIF-- - ---INI-- -memcached.sess_locking = on -memcached.sess_prefix = "memc.sess.key." -session.save_handler = "memcached" - ---FILE-- - ---INI-- -memcached.sess_locking = on -memcached.sess_lock_wait = -1 -memcached.sess_prefix = "memc.sess.key." -session.save_path="127.0.0.1:51312" -session.save_handler = memcached - ---FILE-- - ---INI-- -session.save_handler = "memcached" -session.save_path = "PERSISTENT=1 hello:11211,world:11211" - ---FILE-- - ---INI-- -session.save_handler = memcached ---FILE-- - ---INI-- -session.save_handler = memcached ---FILE-- - 70100) print "skip"; -?> ---INI-- -session.save_handler = memcached ---FILE-- - ---INI-- -session.save_handler = memcached -memcached.sess_binary_protocol = Off ---FILE-- -TRUE]); -$_SESSION['foo'] = 1; -session_write_close(); - -$_SESSION = NULL; - -var_dump($_SESSION); -session_start(); -var_dump($_SESSION); -session_write_close(); - -session_start(); -session_destroy(); - -session_start(); -var_dump($_SESSION); -session_write_close(); - - ---EXPECT-- -NULL -array(1) { - ["foo"]=> - int(1) -} -array(0) { -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_basic3.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_basic3.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_basic3.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_basic3.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ ---TEST-- -Session basic open, write, destroy ---SKIPIF-- - ---INI-- -session.save_handler = memcached -memcached.sess_binary_protocol = Off ---FILE-- - true -]); -var_dump($_SESSION); -session_write_close(); - -session_start(); -session_destroy(); - -session_start(); -var_dump($_SESSION); -session_write_close(); - - ---EXPECT-- -NULL -array(1) { - ["foo"]=> - int(1) -} -array(0) { -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_basic.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_basic.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_basic.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_basic.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ ---TEST-- -Session basic open, write, destroy ---SKIPIF-- - ---INI-- -session.save_handler = memcached -memcached.sess_binary_protocol = Off ---FILE-- - - int(1) -} -array(0) { -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_lazy_warning.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_lazy_warning.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_lazy_warning.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_lazy_warning.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ ---TEST-- -Session lazy binary warning old libmemcached ---SKIPIF-- -= 0x01000018) die ('skip too recent libmemcached'); -?> ---INI-- -session.save_handler = memcached -memcached.sess_binary_protocol = On ---FILE-- -TRUE]); -$_SESSION['foo'] = 1; -session_write_close(); - -$_SESSION = NULL; - -var_dump($_SESSION); -session_start(); -var_dump($_SESSION); -session_write_close(); - -session_start(); -session_destroy(); - -session_start(); -var_dump($_SESSION); -session_write_close(); - - ---EXPECTF-- -NULL -array(1) { - ["foo"]=> - int(1) -} - -Warning: session_write_close(): using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached in %s on line %d -array(0) { -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_lock-php71.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_lock-php71.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_lock-php71.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_lock-php71.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ ---TEST-- -Session lock ---SKIPIF-- - ---INI-- -memcached.sess_locking = true -memcached.sess_lock_wait_min = 500 -memcached.sess_lock_wait_max = 1000 -memcached.sess_lock_retries = 3 -memcached.sess_prefix = "memc.test." - -# Turn off binary protocol while the test matrix has older versions of -# libmemcached for which the extension warns of a broken touch command. -memcached.sess_binary_protocol = Off - -session.save_handler = memcached - ---FILE-- -addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); - -ob_start(); -ini_set ('session.save_path', MEMC_SERVER_HOST . ':' . MEMC_SERVER_PORT); - -session_start(); -$session_id = session_id(); - -$_SESSION["test"] = "hello"; -session_write_close(); - -session_start(); -var_dump ($m->get ('memc.test.' . session_id())); -var_dump ($m->get ('memc.test.lock.' . session_id())); -session_write_close(); -var_dump ($m->get ('memc.test.lock.' . session_id())); - -// Test lock min / max -$m->set ('memc.test.lock.' . $session_id, '1'); - -$time_start = microtime(true); -session_start(); -$time = microtime(true) - $time_start; - -if (round ($time, 1) != 2.5) { - echo "Waited longer than expected: $time" . PHP_EOL; -} -echo "OK"; - ---EXPECTF-- -string(17) "test|s:5:"hello";" -string(1) "1" -bool(false) - -Warning: session_start(): Unable to clear session lock record in %s on line %d - -Warning: session_start(): Failed to read session data: memcached (path: 127.0.0.1:11211) in %s on line %d -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_lock.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_lock.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_lock.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_lock.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ ---TEST-- -Session lock ---SKIPIF-- -= 70100) print "skip"; -?> ---INI-- -memcached.sess_locking = true -memcached.sess_lock_wait_min = 500 -memcached.sess_lock_wait_max = 1000 -memcached.sess_lock_retries = 3 -memcached.sess_prefix = "memc.test." - -# Turn off binary protocol while the test matrix has older versions of -# libmemcached for which the extension warns of a broken touch command. -memcached.sess_binary_protocol = Off - -session.save_handler = memcached - ---FILE-- -addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); - -ob_start(); -ini_set ('session.save_path', MEMC_SERVER_HOST . ':' . MEMC_SERVER_PORT); - -session_start(); -$session_id = session_id(); - -$_SESSION["test"] = "hello"; -session_write_close(); - -session_start(); -var_dump ($m->get ('memc.test.' . session_id())); -var_dump ($m->get ('memc.test.lock.' . session_id())); -session_write_close(); -var_dump ($m->get ('memc.test.lock.' . session_id())); - -// Test lock min / max -$m->set ('memc.test.lock.' . $session_id, '1'); - -$time_start = microtime(true); -session_start(); -$time = microtime(true) - $time_start; - -if (round ($time, 1) != 2.5) { - echo "Waited longer than expected: $time" . PHP_EOL; -} -echo "OK"; - ---EXPECTF-- -string(17) "test|s:5:"hello";" -string(1) "1" -bool(false) - -Warning: session_start(): Unable to clear session lock record in %s on line %d -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_persistent.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_persistent.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_persistent.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_persistent.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ ---TEST-- -Session persistent ---SKIPIF-- - ---INI-- -session.save_handler=memcached -memcached.sess_persistent=1 ---FILE-- - ---EXPECT-- -array(1) { - ["test"]=> - bool(true) -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_regenerate.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_regenerate.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/session_regenerate.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/session_regenerate.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ ---TEST-- -Session regenerate ---SKIPIF-- - ---INI-- -session.save_handler = memcached ---FILE-- -= 0x01000018) die ("skip test for libmemcached lower than 1.0.18"); -?> ---FILE-- -setEncodingKey("Hello")); -var_dump ($m->set ($key, 'set using encoding')); -var_dump ($m->get ($key)); - -echo "OK" . PHP_EOL; - -# libmemcached < 1.0.18 goes into a bad state when the encoding key is changed, -# so php-memcached warns and returns false when trying to change the key. -var_dump ($m->setEncodingKey("World")); - -echo "OK" . PHP_EOL; - -?> ---EXPECTF-- -bool(true) -bool(true) -string(18) "set using encoding" -OK - -Warning: Memcached::setEncodingKey(): libmemcached versions less than 1.0.18 cannot change encoding key in %s on line %d -bool(false) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/set_encoding_key.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/set_encoding_key.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/set_encoding_key.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/set_encoding_key.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ ---TEST-- -Test libmemcached encryption ---SKIPIF-- - ---FILE-- -setEncodingKey("Hello")); -var_dump ($m->set ($key, 'set using encoding')); -var_dump ($m->get ($key)); - -echo "OK" . PHP_EOL; - -# Change the encryption key. The old value will be inaccessible. -var_dump ($m->setEncodingKey("World")); -var_dump ($m->get ($key)); - -echo "OK" . PHP_EOL; - -# Restore the original key to retrieve old values again. -var_dump ($m->setEncodingKey("Hello")); -var_dump ($m->get ($key)); - -echo "OK" . PHP_EOL; - -# With a new encoding key we can still write new values, -# this works as expected with libmemcached 1.0.18 and higher. -var_dump ($m->setEncodingKey("World")); -var_dump ($m->get ($key)); -var_dump ($m->set ($key, 'set using encoding')); -var_dump ($m->get ($key)); - -echo "OK" . PHP_EOL; - -?> ---EXPECT-- -bool(true) -bool(true) -string(18) "set using encoding" -OK -bool(true) -bool(false) -OK -bool(true) -string(18) "set using encoding" -OK -bool(true) -bool(false) -bool(true) -string(18) "set using encoding" -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/set_large.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/set_large.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/set_large.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/set_large.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ ---TEST-- -set large data ---SKIPIF-- - ---FILE-- -set($key, $value, 360)); -var_dump($m->get($key) === $value); -?> ---EXPECT-- -bool(true) -bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/setmulti.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/setmulti.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/setmulti.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/setmulti.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ ---TEST-- -Memcached::setMulti() ---SKIPIF-- - ---FILE-- -deleteMulti($keys); -echo "set keys: "; -var_dump($m->setMulti($data, 10)); - -echo "get: "; -$r = $m->getMulti($keys); -var_dump($r); - -echo "Equal: "; -var_dump($r === $data); - ---EXPECTF-- -Data: array(%d) { - ["foo"]=> - string(3) "bar" - [%i]=> - string(7) "int-max" - [%i]=> - string(7) "int-min" - [%i]=> - string(7) "int-min" - [0]=> - string(4) "zero" - [123]=> - string(11) "onetwothree" - [-123]=> - string(14) "negonetwothree" -} -set keys: bool(true) -get: array(%d) { - ["foo"]=> - string(3) "bar" - [%i]=> - string(7) "int-max" - [%i]=> - string(7) "int-min" - [%i]=> - string(7) "int-min" - [0]=> - string(4) "zero" - [123]=> - string(11) "onetwothree" - [-123]=> - string(14) "negonetwothree" -} -Equal: bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/setoptions.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/setoptions.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/setoptions.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/setoptions.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ ---TEST-- -Set options using setOptions ---SKIPIF-- - ---FILE-- -setOptions(array( - Memcached::OPT_PREFIX_KEY => 'a_prefix', - Memcached::OPT_SERIALIZER => Memcached::SERIALIZER_PHP, - Memcached::OPT_COMPRESSION => 0, - Memcached::OPT_LIBKETAMA_COMPATIBLE => 1, - Memcached::OPT_CONNECT_TIMEOUT => 5000, -))); - -var_dump($m->getOption(Memcached::OPT_PREFIX_KEY) == 'a_prefix'); -var_dump($m->getOption(Memcached::OPT_SERIALIZER) == Memcached::SERIALIZER_PHP); -var_dump($m->getOption(Memcached::OPT_COMPRESSION) == 0); -var_dump($m->getOption(Memcached::OPT_LIBKETAMA_COMPATIBLE) == 1); - -echo "test invalid options\n"; - -var_dump($m->setOptions(array( - "asdf" => 123 -))); - -var_dump($m->setOptions(array( - -1 => 123 -))); - ---EXPECTF-- -bool(true) -bool(true) -bool(true) -bool(true) -bool(true) -test invalid options - -Warning: Memcached::setOptions(): invalid configuration option in %s on line %d -bool(false) - -Warning: Memcached::setOptions(): error setting memcached option: %s in %s on line %d -bool(false) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/skipif.inc php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/skipif.inc --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/skipif.inc 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/skipif.inc 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ - ---FILE-- -setOption(Memcached::OPT_NO_BLOCK, true); -$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); - -$stats = $m->getStats(); -$conns1 = $stats[$key]['total_connections']; - -$stats = $m->getStats(); -$conns2 = $stats[$key]['total_connections']; - -var_dump($conns1 == $conns2); -var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); -var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); -echo "OK" . PHP_EOL; - -// If either or both options are false no need to reconnect -$m->setOption(Memcached::OPT_NO_BLOCK, false); -$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); - -$stats = $m->getStats(); -$conns1 = $stats[$key]['total_connections']; - -$stats = $m->getStats(); -$conns2 = $stats[$key]['total_connections']; - -var_dump($conns1 == $conns2); -var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); -var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); -echo "OK" . PHP_EOL; - -// If either or both options are false no need to reconnect -$m->setOption(Memcached::OPT_NO_BLOCK, true); -$m->setOption(Memcached::OPT_BINARY_PROTOCOL, false); - -$stats = $m->getStats(); -$conns1 = $stats[$key]['total_connections']; - -$stats = $m->getStats(); -$conns2 = $stats[$key]['total_connections']; - -var_dump($conns1 == $conns2); -var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); -var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); -echo "OK" . PHP_EOL; - -// If either or both options are false no need to reconnect -$m->setOption(Memcached::OPT_NO_BLOCK, false); -$m->setOption(Memcached::OPT_BINARY_PROTOCOL, false); - -$stats = $m->getStats(); -$conns1 = $stats[$key]['total_connections']; - -$stats = $m->getStats(); -$conns2 = $stats[$key]['total_connections']; - -var_dump($conns1 == $conns2); -var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); -var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); -echo "OK" . PHP_EOL; - -?> ---EXPECT-- -bool(false) -int(1) -int(1) -OK -bool(true) -int(0) -int(1) -OK -bool(true) -int(1) -int(0) -OK -bool(true) -int(0) -int(0) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/stats.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/stats.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/stats.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/stats.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ ---TEST-- -Check stats ---SKIPIF-- - ---FILE-- -getStats(); -$key = MEMC_SERVER_HOST . ':' . MEMC_SERVER_PORT; - -var_dump (count ($stats) === 1); -var_dump (isset ($stats[$key])); -var_dump (count ($stats[$key]) > 0); -var_dump (is_int ($stats[$key]['cmd_get'])); - -echo "OK"; -?> ---EXPECT-- -bool(true) -bool(true) -bool(true) -bool(true) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/testdata.res php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/testdata.res --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/testdata.res 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/testdata.res 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut malesuada purus vel diam congue condimentum. Vivamus diam erat, commodo eget lacinia venenatis, tempor at nulla. Praesent dapibus aliquam lectus. Aliquam erat volutpat. Praesent congue elementum ipsum, eu bibendum nisi ullamcorper nec. Aenean mattis metus quis libero hendrerit blandit accumsan nisi lacinia. Aenean varius sollicitudin nisl, tempor condimentum turpis congue id. Nunc vulputate purus non nunc dignissim tincidunt. Curabitur adipiscing est in ligula interdum a ultrices nibh ultricies. Aliquam a dapibus lectus. - -Ut eleifend, dui nec aliquam lobortis, quam est luctus lectus, nec hendrerit augue quam ac odio. Nam condimentum, ligula et rhoncus vulputate, lorem urna adipiscing mauris, non mollis velit arcu non urna. Donec sodales ultrices risus, sed hendrerit libero fringilla vitae. Maecenas magna nisl, vehicula scelerisque hendrerit id, fermentum at lorem. Curabitur eu nisl tincidunt arcu venenatis ultricies. Vivamus velit lorem, hendrerit non imperdiet sit amet, eleifend nec mauris. Donec eget condimentum purus. Cras sed lorem sagittis augue faucibus tincidunt. Pellentesque vitae lorem ac orci dignissim tempor. Maecenas diam elit, pulvinar sed gravida rutrum, ultrices vel mauris. In adipiscing placerat eros imperdiet euismod. Nunc quis ante non lectus dictum porta. Nullam orci felis, tristique ut posuere at, tempor sed eros. Pellentesque accumsan posuere magna eu condimentum. Phasellus adipiscing cursus fringilla. Donec diam ipsum, pharetra quis tempus sit amet, mollis in dolor. Pellentesque volutpat vestibulum nulla quis ultricies. Pellentesque scelerisque erat eu nulla ullamcorper tincidunt. - -Nullam commodo lobortis lacus, ac scelerisque diam dignissim eget. Cras eu metus sed tellus accumsan rutrum id ac nunc. Duis rutrum ipsum quis sapien dictum tincidunt. Duis gravida augue et sapien laoreet at pretium eros vulputate. Duis pulvinar lectus quis libero ultricies consequat a id felis. Morbi imperdiet venenatis ipsum eget ultricies. Vivamus fermentum urna sed massa tristique euismod. Pellentesque sed justo ut mi tincidunt luctus semper et elit. In hac habitasse platea dictumst. Praesent suscipit, elit quis fermentum luctus, magna dolor volutpat tellus, nec blandit nulla metus a lacus. Duis gravida, ipsum eu posuere congue, massa augue semper sapien, vel bibendum mi odio nec lectus. Vivamus lacinia urna vitae justo tincidunt dictum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sed libero metus, in imperdiet nibh. - -Integer sapien mauris, pretium sed sodales at, blandit in lacus. Etiam a nisl semper enim pellentesque posuere vitae quis lectus. Etiam ut libero at tortor molestie feugiat non ut ligula. Suspendisse fermentum ipsum vel mauris aliquet convallis. Fusce velit turpis, sollicitudin sit amet luctus id, porta nec ipsum. Fusce consequat, risus vel congue sollicitudin, orci sem auctor nisl, eu consectetur neque tortor id neque. Nunc in odio velit. Duis vitae lacus elit, eu fringilla nulla. Phasellus non mi tellus, volutpat commodo lorem. Pellentesque vel ligula enim. Morbi suscipit, orci sed gravida convallis, nunc leo eleifend lacus, quis elementum dui mi nec risus. Mauris faucibus arcu scelerisque tellus semper dictum. Suspendisse vel posuere turpis. Curabitur ipsum ligula, auctor ut dignissim vel, scelerisque vel mauris. Vivamus est dolor, bibendum ac vestibulum a, congue id felis. Mauris rutrum pharetra tempus. Sed ornare congue purus, id adipiscing mi tincidunt at. Maecenas blandit, lorem in malesuada adipiscing, dolor arcu suscipit magna, ut mollis leo nibh non orci. Sed non massa ipsum, et lobortis tortor. Aliquam et egestas velit. - -Mauris ac sem eget elit imperdiet faucibus at non turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent vel dui vitae enim imperdiet sodales. Maecenas a tristique mauris. Praesent consectetur risus sit amet lacus dictum ut egestas nibh lacinia. Mauris quam augue, fringilla ac pretium a, consectetur sed risus. Sed ullamcorper eleifend dolor, id tempor arcu sodales at. Vestibulum eget sagittis libero. Cras ornare dui ac ante pretium fringilla. Morbi eu tincidunt felis. Vivamus ultrices diam in eros elementum luctus. Aenean eu neque nibh. Mauris neque est, euismod ut rutrum nec, vehicula at magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce sit amet neque ac justo pretium laoreet. Duis non sapien ut eros tristique porttitor vel et lacus. Donec molestie nunc malesuada ante porta ac pretium magna dictum. Nam dolor orci, lacinia egestas ornare eget, viverra et mi. Vivamus convallis lobortis dui, ac sagittis urna mattis sit amet. Duis interdum, est sed dignissim blandit, metus elit scelerisque mauris, sit amet egestas velit arcu quis nunc. diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/touch_binary.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/touch_binary.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/touch_binary.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/touch_binary.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ ---TEST-- -Touch in binary mode ---SKIPIF-- - ---FILE-- -getConstants (); - - foreach ($c as $name => $value) { - if (strpos ($name, 'RES_') === 0 && $value == $code) - return $name; - } -} - -function status_print ($op, $mem, $expected) -{ - $code = $mem->getResultcode(); - - if ($code == $expected) - echo "${op} status code as expected" . PHP_EOL; - else { - $expected = resolve_to_constant ($expected); - $code = resolve_to_constant ($code); - - echo "${op} status code mismatch, expected ${expected} but got ${code}" . PHP_EOL; - } -} - -include dirname (__FILE__) . '/config.inc'; -$mem = memc_get_instance (array (Memcached::OPT_BINARY_PROTOCOL => true)); - -$key = uniqid ('touch_t_'); - -$mem->get($key); -status_print ('get', $mem, Memcached::RES_NOTFOUND); - -$mem->set ($key, 1); -status_print ('set', $mem, Memcached::RES_SUCCESS); - -$mem->get($key); -status_print ('get', $mem, Memcached::RES_SUCCESS); - -$mem->touch ($key, 10); -status_print ('touch', $mem, Memcached::RES_SUCCESS); - -$mem->get($key); -status_print ('get', $mem, Memcached::RES_SUCCESS); - -$mem->get($key); -status_print ('get', $mem, Memcached::RES_SUCCESS); - -echo "OK\n"; - -?> ---EXPECT-- -get status code as expected -set status code as expected -get status code as expected -touch status code as expected -get status code as expected -get status code as expected -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_igbinary_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_igbinary_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_igbinary_multi.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_igbinary_multi.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ ---TEST-- -Memcached multi store & multi fetch type and value correctness using igbinary serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_igbinary.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_igbinary.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_igbinary.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_igbinary.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ ---TEST-- -Memcached store & fetch type and value correctness using igbinary serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types.inc php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types.inc --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types.inc 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types.inc 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ - "1","b" => "2","c" => "3")), - array('object_dummy', new testclass()), - ); - - foreach ($data as $key => $value) { - $m->delete($key); - } - - foreach ($data as $types) { - $key = $types [0]; - $value = $types [1]; - - $m->set($key, $value); - - $actual = $m->get($key); - if ($value !== $actual) { - if (is_object($actual)) { - if ($options['ignore_object_type']) { - $value = (object) (array) $value; - if ($value == $actual) - continue; - } - - if ($value == $actual && get_class($value) == get_class($actual)) - continue; - } - echo "=== {$key} ===\n"; - echo "Expected: "; - var_dump($value); - echo "Actual: "; - var_dump($actual); - - } - } - - $m->flush(); - - if (($actual = $m->get(uniqid ('random_key_'))) !== false) { - echo "Expected: null"; - echo "Actual: " . gettype($actual); - } -} - -function memc_types_test_multi ($m, $options) -{ - $data = array( - 'boolean_true' => true, - 'boolean_false' => false, - - 'string' => "just a string", - 'string_empty' => "", - 'string_large' => str_repeat ('abcdef0123456789', 500), - - 'integer_positive_integer' => 10, - 'integer_negative_integer' => -10, - 'integer_zero_integer' => 0, - - 'float_positive1' => 3.912131, - 'float_positive2' => 1.2131E+52, - 'float_negative' => -42.123312, - 'float_zero' => 0.0, - - 'null' => null, - - 'array_empty' => array(), - 'array' => array(1,2,3,"foo"), - - 'object_array_empty' => (object)array(), - 'object_array' => (object)array('a' => 1, 'b' => 2, 'c' => 3), - 'object_dummy' => new testclass(), - ); - - foreach ($data as $key => $value) { - $m->delete($key); - } - $m->setMulti($data); - $actual = $m->getMulti(array_keys($data)); - - foreach ($data as $key => $value) { - if ($value !== $actual[$key]) { - if (is_object($value)) { - if ($options['ignore_object_type']) { - $value = (object) (array) $value; - if ($value == $actual[$key]) - continue; - } - - if ($value == $actual[$key] && get_class($value) == get_class($actual[$key])) - continue; - } - - echo "=== $key ===\n"; - echo "Expected: "; - var_dump($value); - echo "Actual: "; - var_dump($actual[$key]); - } - } -} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_json_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_json_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_json_multi.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_json_multi.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ ---TEST-- -Memcached multi store & multi fetch type and value correctness using JSON serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_json.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_json.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_json.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_json.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ ---TEST-- -Memcached store & fetch type and value correctness using JSON serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_msgpack_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_msgpack_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_msgpack_multi.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_msgpack_multi.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ ---TEST-- -Memcached multi store & fetch type and value correctness using msgpack serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_msgpack.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_msgpack.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_msgpack.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_msgpack.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ ---TEST-- -Memcached store & fetch type and value correctness using msgpack serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_php_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_php_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_php_multi.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_php_multi.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ ---TEST-- -Memcached multi store & fetch type and value correctness using PHP serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_php.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_php.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/types_php.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/types_php.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ ---TEST-- -Memcached store & fetch type and value correctness using PHP serializer ---SKIPIF-- - ---FILE-- - ---EXPECT-- -TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/undefined_set.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/undefined_set.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/undefined_set.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/undefined_set.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ ---TEST-- -Set with undefined key and value ---SKIPIF-- - ---FILE-- - 'bar'); - -$rv = $m->set($no_key, $value, 360); -var_dump($rv); - - -$rv = $m->set($key, $no_value, 360); -var_dump($rv); - -$rv = $m->set($no_key, $no_value, 360); -var_dump($rv); - -$rv = $m->set($key, $value, $no_time); -var_dump($rv); -?> ---EXPECTF-- -Notice: Undefined variable: no_key in %s -bool(false) - -Notice: Undefined variable: no_value in %s -bool(true) - -Notice: Undefined variable: no_key in %s - -Notice: Undefined variable: no_value in %s -bool(false) - -Notice: Undefined variable: no_time in %s -bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/user-flags.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/user-flags.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/user-flags.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/user-flags.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ ---TEST-- -Memcached user flags ---SKIPIF-- - ---FILE-- -get($key, null, Memcached::GET_EXTENDED)['flags']; -} - -define ('FLAG_1', 1); -define ('FLAG_2', 2); -define ('FLAG_4', 4); -define ('FLAG_32', 32); -define ('FLAG_64', 64); -define ('FLAG_TOO_LARGE', pow(2, 16)); - -include dirname (__FILE__) . '/config.inc'; -$m = memc_get_instance (array (Memcached::OPT_BINARY_PROTOCOL => true)); - -$key = uniqid ('udf_test_'); - -// Set with flags off -$m->set ($key, '1', 10); -$v = $m->get($key, null, Memcached::GET_EXTENDED); -var_dump($v); - -// Set flags on -$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1); -$m->set ($key, '1', 10); -$m->get($key); -check_flags(get_flags($m, $key), array(FLAG_1)); - -// Multiple flags -$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1 | FLAG_2 | FLAG_4); -$m->set ($key, '1', 10); -$m->get($key); -check_flags(get_flags($m, $key), array(FLAG_1, FLAG_2, FLAG_4)); - -// Even more flags -$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1 | FLAG_2 | FLAG_4 | FLAG_32 | FLAG_64); -$m->set ($key, '1', 10); -$m->get($key); -check_flags(get_flags($m, $key), array(FLAG_1, FLAG_2, FLAG_4, FLAG_32, FLAG_64)); - -// User flags with get multi -$values = array( - uniqid ('udf_test_multi_') => "first", - uniqid ('udf_test_multi_') => "second", - uniqid ('udf_test_multi_') => "third", -); - -$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_2 | FLAG_4); -$m->setMulti($values); -$m->getMulti(array_keys($values)); -$flags = $m->getMulti(array_keys($values), Memcached::GET_EXTENDED); - -foreach (array_keys($values) as $key) { - check_flags($flags[$key]['flags'], array(FLAG_2, FLAG_4)); -} - -// User flags with compression on -$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1 | FLAG_2 | FLAG_4); -$m->setOption(Memcached::OPT_COMPRESSION, true); -$m->setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_FASTLZ); - -$m->set ($key, '1', 10); -$m->get($key); -check_flags(get_flags($m, $key), array(FLAG_1, FLAG_2, FLAG_4)); - - -// Too large flags -$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_TOO_LARGE); - -echo "DONE TEST\n"; -?> ---EXPECTF-- -array(3) { - ["value"]=> - string(1) "1" - ["cas"]=> - int(%d) - ["flags"]=> - int(0) -} -Flags OK -Flags OK -Flags OK -Flags OK -Flags OK -Flags OK -Flags OK - -Warning: Memcached::setOption(): MEMC_OPT_USER_FLAGS must be < 65535 in %s on line %d -DONE TEST \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/vbucket.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/vbucket.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/vbucket.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/vbucket.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ ---TEST-- -Memcached virtual buckets ---SKIPIF-- - ---FILE-- - Memcached::DISTRIBUTION_VIRTUAL_BUCKET - )); - -var_dump ($m->setBucket (array (1, 2, 3), null, 2)); - -var_dump ($m->setBucket (array (1,2,2), array (1,2,2), 2)); - -var_dump ($m->setBucket (array ('a', 'b', 'c'), null, 2)); - -var_dump ($m->setBucket (array (), null, 2)); - -var_dump ($m->setBucket (array (), array (), -1)); - -var_dump ($m->setBucket (null, array (), -1)); - -var_dump ($m->setBucket (array (-1), array (-1), 1)); - -echo "OK\n"; - -?> ---EXPECTF-- -bool(true) -bool(true) -bool(true) - -Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d -bool(false) - -Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d -bool(false) - -Warning: Memcached::setBucket() expects parameter 1 to be array, null given in %s on line %d -NULL - -Warning: Memcached::setBucket(): the map must contain positive integers in %s on line %d -bool(false) -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/version.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/version.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.3/tests/version.phpt 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.3/tests/version.phpt 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ ---TEST-- -Get version ---SKIPIF-- - ---FILE-- -getVersion ()); - -echo "OK" . PHP_EOL; -?> ---EXPECTF-- -array(1) { - ["%s:%d"]=> - string(%d) "%d.%d.%d" -} -OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/ChangeLog php-memcached-3.1.4+2.2.0/memcached-3.1.4/ChangeLog --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/ChangeLog 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/ChangeLog 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,289 @@ +memcached extension changelog + +Version 3.1.4 (2019-10-06) +-------------------------- + + * Test on PHP 7.4 as well as 8.0 (#440) + * Fix segfault for unknown memcached flags (#431) + * Update documented defaults for sess_lock_retries( #432) + * Remove stray instances of the TSRMLS_CC macro for PHP 8 compatibility (#444) + +Version 3.1.3 (2018-12-24) +-------------------------- + + * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) + +Version 3.1.2 (2018-12-22) +-------------------------- + + * Fix --enable-memcached-protocol was set to yes by default, reverted to no (#418) + +Version 3.1.1 (2018-12-21) +-------------------------- + + * Fix --disable-memcached-sasl and --disable-memcached-session replaced by --enable variants (#416) + +Version 3.1.0 (2018-12-21) +-------------------------- + + New + * Support for PHP 7.3 (#385, #390) + * Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#344, #392) + * Add support for libmemcached encryption (#345, #381) + * Add error reporting to session code (#165) + * Expose build configuration via PECL (#383) + + Fixes + * Fix hanging getStats() when binary protocol and non-blocking are both enabled (#348) + * Fix session persistence by checking memcached behavior values before setting (#379) + * Fix memcached.sess_persistent not working with memcached.sess_binary_protocol = On (#375) + * Configure warns if libmemcached needs sasl.h (#341, #380) + * Resolve various INI deviations in 3.0.3 (#351) + * Turn off sess_binary_protocol by default with older libmemcached (#330) + + Changes + * Impove Windows builds (#411) + * Support Homebrew ZLIB path (#410) + * Remove forgotten unused comment about -lpthread (#406) + * Git ignore configure.ac (#405) + * Replace obsolete macros AC_TRY_FOO with AC_FOO_IFELSE (#403) + * Remove unused defines (#354) + * Change session_lock and sess_prefix default ini values (#340, #350) + * Use new fast_zpp parameter parsing API (#302, #311) + +Version 3.0.4 (2017-11-20) +-------------------------- + + * Fix corrupted interned strings (#338) + * Fix unit tests for compatibility with PHP 7.2 (#358, #359) + * Fix \x0a in key name locks up connection and triggers a fatal timeout error (#339) + * Fix missing optional parameter getStats($type) (#337) + * Fix typo in skip message (#331) + * Fix build warnings (#329) + * Document GET_EXTENDED flag, add/rename other missing/misnamed constants (#335) + +Version 3.0.3 (2017-02-19) +-------------------------- + + * Fix crash when checking session data with older versions of libmemcached (#328) + * Fix crash due to zend_mm_corrupted when fetching session data (#327) + +Version 3.0.2 (2017-02-12) +-------------------------- + + * Update warning for touch command in binary protocol mode with libmemcached < 1.0.18 (#322) + * Add tests for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) + * Fix tests for 32-bit increment/decrement/incrementByKey/decrementByKey (#319) + +Version 3.0.1 (2017-02-07) +-------------------------- + + * Add API entries for flushBuffers() and getAllKeys() (#316) + * Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) + * Fix compiling with memcached binary protocol enabled (#312) + * Restore php_libmemcached_compat with workaround for missing memcached_exists (#314) + * Travis CI purge old versions of memcached and libmemcached (#309) + +Version 3.0.0 (2017-01-27) +-------------------------- + * Support for PHP 7.0 and PHP 7.1 + * Fix compiling with SASL disabled + * Improved the test suite and Travis CI test runners + * Fix small string compression / decompression + * Fix increment/decrement with adjustments greater than 32-bit integers + * Fix session.gc_maxlifetime to handle both relative and absolute times + * Fix inability to reset OPT_PREFIX_KEY + +Version 3.0.0a1 (2016-02-22) +---------------------------- + Dependencies + * Support for PHP 7.0 + * Requires libmemcached 1.0 or higher + * Optional extension igbinary must 2.0 or higher + * Optional extension msgpack must be 2.0 or higher + + API + * The method signature of get, getByKey, getMulti, and getMultiByKey changed. + * get* and getMulti* commands no longer take cas or user flags parameters. + * get* and getMulti* commands now take the Memcached::GET_EXTENDED flag to retrieve user flags and cas tokens. + * Fixes getStats command to return all stats from all servers + * Fixes allKeys command behaviour + * Fixes error where cache callback for get command was not setting expiration time properly + * Added server type to server list + * Remove use_sasl ini-variable and initialise sasl as needed + * CAS tokens are returned as integers and they overflow to strings as needed + + Session handler + * The session memcached protocol config name was changed, and the default protocol was changed from text to binary protocol. If your memcached setup does not support the binary protocol(e.g. if using twemproxy), then set memcached.sess_binary_protocol = Off. (Previously called memcached.sess_binary) + * Session lock algorithm updated (new ini-values memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries) + * Session extension uses PHP allocators (still some work to do on the rest of the extension) + * Ini-values take effect during session_start or session_regenerate_id + * Fixes crash with session_regenerate_id (work-around for PHP bug) + + Tests + * Fix several problematic tests + +Version 2.2.0 (2014-04-01) +-------------------------- + * Added the OPT_SERVER_TIMEOUT_LIMIT behaviour + +Version 2.2.0RC1 (2014-03-12) +----------------------------- + * Added the OPT_SERVER_TIMEOUT_LIMIT behaviour + * Fixes incorrect size when compressing serialized objects + * Fixes endianess of compressed values + +Version 2.2.0b1 (2013-10-28) +---------------------------- + * Reinstate support for libememcached 0.x series + * Added SASL support to session handler + * Added Memcached::flushBuffers as per GH #78 + * Fixes GH #54: Fixed UDP server adding with newer libmemcached + * Fixed PHP bug #65334: (Segfault if uncompress value failed) + * Fixes GH #14: get with cas token fails to fetch all results + * Fixes GH #68: memcached 2.1.0 requires libmemcached 1.0.10 + * Fixes GH #69: compiling on CentOS 6.4 with libmemcached 1.0.17 + * Merged PR #91: memcached.sess_lock_wait and memcached.sess_lock_max_wait + * Added session handler settings: + - memcached.sess_number_of_replicas + - memcached.sess_randomize_replica_read + - memcached.sess_remove_failed + - memcached.sess_connect_timeout + * Added support for memcached protocol handlers + * Added Memcached::setBucket for virtual bucket support + * Added support for msgpack serialization + * Memcached::setSaslAuthData returns correct status on success + * Added support for user-defined flags in set and get operations + +Version 2.1.0 (2012-08-06) +-------------------------- + * Drop support for libmemcached 0.x series, now 1.0.x is required + * Add support for virtual bucket distribution + * Fix compilation against PHP 5.2 + +Version 2.0.1 (2012-03-03) +-------------------------- + * Fix embedded version number to be not -dev + +Version 2.0.0 (2012-03-02) +-------------------------- + * Add touch() and touchByKey() methods + * Add resetServerList() and quit() methods + * Support binary protocol in sessions + * Make it work with libmemcached up to 1.0.4 + * Test against PHP 5.4.0 + +Version 2.0.0b2 (2011-06-24) +---------------------------- + * Add OPT_REMOVE_FAILED_SERVERS option. + * Make it work with libmemcached up to 0.49. + * Fix a case where invalid session ID could lock the script. + * Improve session support: + - Add support for libmemcached config string + - Add persistence support via PERSISTENT=persistent_id prefix + of the save_path + * Add 3rd parameter to the __construct() that allows specification + of libmemcached configuration string + * Fix a possible crash in __construct() when using persistent + connections + * Add work-around a bug in libmemcached < 0.50 that causes truncation + of last character of server key prefix + * When using multiple servers implement transparent fail-over + * Fix php_memc_cas_impl() implementation when server_key is not being used + * Add support for incrementByKey() and decrementByKey() + * Make increment/decrement initialize value when it is not available (when + using binary protocol) + +Version 2.0.0b1 (2011-03-12) +---------------------------- + * Add fastlz library that provides better/faster payload compression + * Add configure switch to enable/disable JSON serialization support + * Add getAllKeys() method + * Add deleteMulti() and deleteMultiByKey() methods + * Add isPristine() and isPersistent() methods + * Add setOptions() method to set multiple options at once + * Add SERIALIZER_JSON_ARRAY type that decodes JSON payloads as arrays + instead of objects + * Add support for Unix domain socket connections + * Add memcached.compression_threshold INI setting + * Add memcached.compression_factor INI setting + * Add memcached.compression_type INI setting + * Implement a few speed optimizations + * Many bug fixes and memory leaks plugged + * Add several more tests + * Add constants for libmemcached 0.37+: + - Memcached::OPT_NUMBER_OF_REPLICAS + - Memcached::OPT_RANDOMIZE_REPLICA_READ + * Add 'on_new' callback to constructor + * Add SASL support + +Version 1.0.2 (2010-05-03) +-------------------------- + * Fix build for libmemcached-0.39 (memcached_server_list() issue) + +Version 1.0.1 (2010-03-11) +-------------------------- + * Fix JSON API handling to account for PHP 5.2/5.3 version differences. + * Add memcached.sess_locking, memcached.sess_lock_wait, and + memcached.sess_prefix INI entries. + * Add OPT_AUTO_EJECT_HOSTS option. + +Version 1.0.0 (2009-07-04) +-------------------------- + * First stable release. + * Add getResultMessage() method. + * Fix OPT_RECV_TIMEOUT definition. + * Initialize Session lock wait to max execution time (if max execution + time is unlimited, default to 30 seconds). + +Version 0.2.0 (2009-06-04) +-------------------------- + * Add JSON serializer support, requires PHP 5.2.10+. + * Add HAVE_JSON and HAVE_IGBINARY class constants that indicate + whether the respective serializers are available. + * Add 'flags' parameter to getMulti() and getMultiByKey(). + * Add GET_PRESERVE_ORDER class constant that can be used with + abovementioned flags parameter to make the order of the keys in the + response match the request. + * Fix an issue with retrieving 0-length payloads (FALSE boolean value). + * Refactor the way payload types are stored in memcached flags to optimize + the structure and allow for future expansion. WARNING! You have to flush + the cache when upgrading to this version. + * Add several tests. + +Version 0.1.5 (2009-03-31) +-------------------------- + * Implement getVersion(). + * Add support for preserving boolean value types. + * Fix crash when child class does not call constructor. + * Fix bug #16084 (Crash when addServers is called with an associative array). + * ZTS compilation fixes. + +Version 0.1.4 (2009-02-13) +-------------------------- + * Fix compilation against PHP 5.3. + * Add support for 'igbinary' serializer (Oleg Grenrus) + +Version 0.1.3 (2009-02-06) +-------------------------- + * Bludgeon bug #15896 (Memcached setMulti error) into submission. + +Version 0.1.2 (2009-02-06) +-------------------------- + * Fix bug #15896 (Memcached setMulti error). + * Check for empty key in getServerByKey(). + * Allow passing 'null' for callbacks. + * get() with cas token fetching wasn't erroring out properly. + * Rename certain parameters in the API to be more clear. + * Allow only strings as the append/prepend value. + * Remove expiration parameter from append/prepend. + +Version 0.1.1 (2009-02-02) +-------------------------- + * Add OPT_LIBKETAMA_COMPATIBLE option. + * Implement addServers() method. + * Swap internal compressed and serialized flags to be compatible with other clients. + +Version 0.1.0 (2009-01-29) +-------------------------- + * Initial release diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/config.m4 php-memcached-3.1.4+2.2.0/memcached-3.1.4/config.m4 --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/config.m4 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/config.m4 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,409 @@ +dnl vim:se ts=2 sw=2 et: + +PHP_ARG_ENABLE(memcached, whether to enable memcached support, +[ --enable-memcached Enable memcached support]) + +PHP_ARG_WITH(libmemcached-dir, for libmemcached, +[ --with-libmemcached-dir=DIR Set the path to libmemcached install prefix.], yes) + +PHP_ARG_ENABLE(memcached-session, whether to enable memcached session handler support, +[ --enable-memcached-session Enable memcached session handler support], yes, no) + +PHP_ARG_ENABLE(memcached-igbinary, whether to enable memcached igbinary serializer support, +[ --enable-memcached-igbinary Enable memcached igbinary serializer support], no, no) + +PHP_ARG_ENABLE(memcached-json, whether to enable memcached json serializer support, +[ --enable-memcached-json Enable memcached json serializer support], no, no) + +PHP_ARG_ENABLE(memcached-msgpack, whether to enable memcached msgpack serializer support, +[ --enable-memcached-msgpack Enable memcached msgpack serializer support], no, no) + +PHP_ARG_ENABLE(memcached-sasl, whether to enable memcached sasl support, +[ --enable-memcached-sasl Enable memcached sasl support], yes, no) + +PHP_ARG_ENABLE(memcached-protocol, whether to enable memcached protocol support, +[ --enable-memcached-protocol Enable memcached protocol support], no, no) + +PHP_ARG_WITH(system-fastlz, whether to use system FastLZ library, +[ --with-system-fastlz Use system FastLZ library], no, no) + +if test -z "$PHP_ZLIB_DIR"; then +PHP_ARG_WITH(zlib-dir, for ZLIB, +[ --with-zlib-dir=DIR Set the path to ZLIB install prefix.], no) +fi + +if test -z "$PHP_DEBUG"; then + AC_ARG_ENABLE(debug, + [ --enable-debug Compile with debugging symbols],[ + PHP_DEBUG=$enableval + ],[ PHP_DEBUG=no + ]) +fi + +if test "$PHP_MEMCACHED" != "no"; then + + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + if test "x$PKG_CONFIG" = "xno"; then + AC_MSG_RESULT([pkg-config not found]) + AC_MSG_ERROR([Please reinstall the pkg-config distribution]) + fi + + dnl # zlib + if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then + if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then + PHP_ZLIB_DIR="$PHP_ZLIB_DIR" + PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include/zlib" + elif test -f "$PHP_ZLIB_DIR/include/zlib.h"; then + PHP_ZLIB_DIR="$PHP_ZLIB_DIR" + PHP_ZLIB_INCDIR="$PHP_ZLIB_DIR/include" + else + AC_MSG_ERROR([Can't find ZLIB headers under "$PHP_ZLIB_DIR"]) + fi + else + for i in /usr/local /usr/local/opt/zlib /usr; do + if test -f "$i/include/zlib/zlib.h"; then + PHP_ZLIB_DIR="$i" + PHP_ZLIB_INCDIR="$i/include/zlib" + elif test -f "$i/include/zlib.h"; then + PHP_ZLIB_DIR="$i" + PHP_ZLIB_INCDIR="$i/include" + fi + done + fi + + AC_MSG_CHECKING([for zlib location]) + if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then + AC_MSG_RESULT([$PHP_ZLIB_DIR]) + PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR/$PHP_LIBDIR, MEMCACHED_SHARED_LIBADD) + PHP_ADD_INCLUDE($PHP_ZLIB_INCDIR) + else + AC_MSG_ERROR([memcached support requires ZLIB. Use --with-zlib-dir= to specify the prefix where ZLIB headers and library are located]) + fi + + if test "$PHP_MEMCACHED_SESSION" != "no"; then + AC_MSG_CHECKING([for session includes]) + session_inc_path="" + + if test -f "$abs_srcdir/include/php/ext/session/php_session.h"; then + session_inc_path="$abs_srcdir/include/php" + elif test -f "$abs_srcdir/ext/session/php_session.h"; then + session_inc_path="$abs_srcdir" + elif test -f "$phpincludedir/ext/session/php_session.h"; then + session_inc_path="$phpincludedir" + else + for i in php php4 php5 php6; do + if test -f "$prefix/include/$i/ext/session/php_session.h"; then + session_inc_path="$prefix/include/$i" + fi + done + fi + + if test "$session_inc_path" = ""; then + AC_MSG_ERROR([Cannot find php_session.h]) + else + AC_MSG_RESULT([$session_inc_path]) + fi + fi + + if test "$PHP_MEMCACHED_JSON" != "no"; then + AC_MSG_CHECKING([for json includes]) + json_inc_path="" + + if test -f "$abs_srcdir/include/php/ext/json/php_json.h"; then + json_inc_path="$abs_srcdir/include/php" + elif test -f "$abs_srcdir/ext/json/php_json.h"; then + json_inc_path="$abs_srcdir" + elif test -f "$phpincludedir/ext/json/php_json.h"; then + json_inc_path="$phpincludedir" + else + for i in php php4 php5 php6; do + if test -f "$prefix/include/$i/ext/json/php_json.h"; then + json_inc_path="$prefix/include/$i" + fi + done + fi + if test "$json_inc_path" = ""; then + AC_MSG_ERROR([Cannot find php_json.h]) + else + AC_DEFINE(HAVE_JSON_API,1,[Whether JSON API is available]) + AC_MSG_RESULT([$json_inc_path]) + fi + fi + + if test "$PHP_MEMCACHED_IGBINARY" != "no"; then + AC_MSG_CHECKING([for igbinary includes]) + igbinary_inc_path="" + + if test -f "$abs_srcdir/include/php/ext/igbinary/igbinary.h"; then + igbinary_inc_path="$abs_srcdir/include/php" + elif test -f "$abs_srcdir/ext/igbinary/igbinary.h"; then + igbinary_inc_path="$abs_srcdir" + elif test -f "$phpincludedir/ext/session/igbinary.h"; then + igbinary_inc_path="$phpincludedir" + elif test -f "$phpincludedir/ext/igbinary/igbinary.h"; then + igbinary_inc_path="$phpincludedir" + else + for i in php php4 php5 php6; do + if test -f "$prefix/include/$i/ext/igbinary/igbinary.h"; then + igbinary_inc_path="$prefix/include/$i" + fi + done + fi + + if test "$igbinary_inc_path" = ""; then + AC_MSG_ERROR([Cannot find igbinary.h]) + else + AC_MSG_RESULT([$igbinary_inc_path]) + fi + fi + + if test "$PHP_MEMCACHED_MSGPACK" != "no"; then + AC_MSG_CHECKING([for msgpack includes]) + msgpack_inc_path="" + + if test -f "$abs_srcdir/include/php/ext/msgpack/php_msgpack.h"; then + msgpack_inc_path="$abs_srcdir/include/php" + elif test -f "$abs_srcdir/ext/msgpack/php_msgpack.h"; then + msgpack_inc_path="$abs_srcdir" + elif test -f "$phpincludedir/ext/session/php_msgpack.h"; then + msgpack_inc_path="$phpincludedir" + elif test -f "$phpincludedir/ext/msgpack/php_msgpack.h"; then + msgpack_inc_path="$phpincludedir" + else + for i in php php4 php5 php6; do + if test -f "$prefix/include/$i/ext/msgpack/php_msgpack.h"; then + msgpack_inc_path="$prefix/include/$i" + fi + done + fi + + if test "$msgpack_inc_path" = ""; then + AC_MSG_ERROR([Cannot find php_msgpack.h]) + else + AC_MSG_RESULT([$msgpack_inc_path]) + fi + fi + + AC_MSG_CHECKING([for memcached session support]) + if test "$PHP_MEMCACHED_SESSION" != "no"; then + AC_MSG_RESULT([enabled]) + AC_DEFINE(HAVE_MEMCACHED_SESSION,1,[Whether memcache session handler is enabled]) + SESSION_INCLUDES="-I$session_inc_path" + ifdef([PHP_ADD_EXTENSION_DEP], + [ + PHP_ADD_EXTENSION_DEP(memcached, session) + ]) + else + SESSION_INCLUDES="" + AC_MSG_RESULT([disabled]) + fi + + AC_MSG_CHECKING([for memcached igbinary support]) + if test "$PHP_MEMCACHED_IGBINARY" != "no"; then + AC_MSG_RESULT([enabled]) + AC_DEFINE(HAVE_MEMCACHED_IGBINARY,1,[Whether memcache igbinary serializer is enabled]) + IGBINARY_INCLUDES="-I$igbinary_inc_path" + ifdef([PHP_ADD_EXTENSION_DEP], + [ + PHP_ADD_EXTENSION_DEP(memcached, igbinary) + ]) + else + IGBINARY_INCLUDES="" + AC_MSG_RESULT([disabled]) + fi + + AC_MSG_CHECKING([for memcached msgpack support]) + if test "$PHP_MEMCACHED_MSGPACK" != "no"; then + AC_MSG_RESULT([enabled]) + AC_DEFINE(HAVE_MEMCACHED_MSGPACK,1,[Whether memcache msgpack serializer is enabled]) + MSGPACK_INCLUDES="-I$msgpack_inc_path" + ifdef([PHP_ADD_EXTENSION_DEP], + [ + PHP_ADD_EXTENSION_DEP(memcached, msgpack) + ]) + else + MSGPACK_INCLUDES="" + AC_MSG_RESULT([disabled]) + fi + + AC_MSG_CHECKING([for libmemcached location]) + export ORIG_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" + + if test "$PHP_LIBMEMCACHED_DIR" != "no" && test "$PHP_LIBMEMCACHED_DIR" != "yes"; then + export PKG_CONFIG_PATH="$PHP_LIBMEMCACHED_DIR/$PHP_LIBDIR/pkgconfig" + + if test ! -f "$PHP_LIBMEMCACHED_DIR/include/libmemcached/memcached.h"; then + AC_MSG_ERROR(Unable to find memcached.h under $PHP_LIBMEMCACHED_DIR) + fi + else + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/$PHP_LIBDIR/pkgconfig:/usr/$PHP_LIBDIR/pkgconfig:/opt/$PHP_LIBDIR/pkgconfig" + fi + + if ! $PKG_CONFIG --exists libmemcached; then + AC_MSG_ERROR([memcached support requires libmemcached. Use --with-libmemcached-dir= to specify the prefix where libmemcached headers and library are located]) + else + PHP_LIBMEMCACHED_VERSION=`$PKG_CONFIG libmemcached --modversion` + PHP_LIBMEMCACHED_DIR=`$PKG_CONFIG libmemcached --variable=prefix` + + AC_MSG_RESULT([found version $PHP_LIBMEMCACHED_VERSION, under $PHP_LIBMEMCACHED_DIR]) + + PHP_LIBMEMCACHED_LIBS=`$PKG_CONFIG libmemcached --libs` + PHP_LIBMEMCACHED_INCLUDES=`$PKG_CONFIG libmemcached --cflags` + + PHP_EVAL_LIBLINE($PHP_LIBMEMCACHED_LIBS, MEMCACHED_SHARED_LIBADD) + PHP_EVAL_INCLINE($PHP_LIBMEMCACHED_INCLUDES) + + ORIG_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $INCLUDES" + + dnl # Always check if libmemcached was built with SASL support, + dnl # because it will require sasl.h even if not used here. + AC_CACHE_CHECK([for libmemcached sasl.h requirement], ac_cv_memc_sasl_support, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + #if LIBMEMCACHED_WITH_SASL_SUPPORT + /* yes */ + #else + # error "no sasl support" + #endif + ]])], + [ac_cv_memc_sasl_support="yes"], + [ac_cv_memc_sasl_support="no"] + ) + ]) + + if test "$ac_cv_memc_sasl_support" = "yes"; then + AC_CHECK_HEADERS([sasl/sasl.h], [ac_cv_have_memc_sasl_h="yes"], [ac_cv_have_memc_sasl_h="no"]) + fi + + dnl # If libmemcached requires sasl.h but we can't find sasl.h, that's a hard error + dnl # regardless of the option --enable-memcached-sasl or --disable-memcached-sasl + AC_MSG_CHECKING([whether to enable sasl support]) + if test "$ac_cv_memc_sasl_support" = "yes" && test "$ac_cv_have_memc_sasl_h" = "no"; then + AC_MSG_ERROR([no, libmemcached built with sasl required, but sasl.h not found.]) + fi + + if test "$PHP_MEMCACHED_SASL" != "no"; then + AC_MSG_RESULT(yes) + if test "$ac_cv_memc_sasl_support" = "yes" && test "$ac_cv_have_memc_sasl_h" = "yes"; then + PHP_CHECK_LIBRARY(sasl2, sasl_client_init, [PHP_ADD_LIBRARY(sasl2, 1, MEMCACHED_SHARED_LIBADD)]) + AC_DEFINE(HAVE_MEMCACHED_SASL, 1, [Have SASL support]) + else + AC_MSG_ERROR([no, libmemcached built with sasl disabled. Run configure with --disable-memcached-sasl or update libmemcached with sasl support]) + fi + else + AC_MSG_RESULT([no]) + fi + + ORIG_CFLAGS="$CFLAGS" + ORIG_LIBS="$LIBS" + + CFLAGS="$CFLAGS $PHP_LIBMEMCACHED_INCLUDES" + LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" + + AC_CACHE_CHECK([whether memcached_exist is defined], ac_cv_have_memcached_exist, [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[memcached_exist (NULL, NULL, 0);]])], + [ac_cv_have_memcached_exist="yes"], + [ac_cv_have_memcached_exist="no"]) + ]) + + CFLAGS="$ORIG_CFLAGS" + LIBS="$ORIG_LIBS" + + CFLAGS="$CFLAGS $PHP_LIBMEMCACHED_INCLUDES" + LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" + + if test "$ac_cv_have_memcached_exist" = "yes"; then + AC_DEFINE(HAVE_MEMCACHED_EXIST, [1], [Whether memcached_exist is defined]) + fi + + AC_CACHE_CHECK([whether memcached_set_encoding_key is defined], ac_cv_have_memcached_set_encoding_key, [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[memcached_set_encoding_key (NULL, NULL, 0);]])], + [ac_cv_have_memcached_set_encoding_key="yes"], + [ac_cv_have_memcached_set_encoding_key="no"]) + ]) + + CFLAGS="$ORIG_CFLAGS" + LIBS="$ORIG_LIBS" + + if test "$ac_cv_have_memcached_set_encoding_key" = "yes"; then + AC_DEFINE(HAVE_MEMCACHED_SET_ENCODING_KEY, [1], [Whether memcached_set_encoding_key is defined]) + fi + + PHP_MEMCACHED_FILES="php_memcached.c php_libmemcached_compat.c g_fmt.c" + + if test "$PHP_SYSTEM_FASTLZ" != "no"; then + AC_CHECK_HEADERS([fastlz.h], [ac_cv_have_fastlz="yes"], [ac_cv_have_fastlz="no"]) + PHP_CHECK_LIBRARY(fastlz, fastlz_compress, + [PHP_ADD_LIBRARY(fastlz, 1, MEMCACHED_SHARED_LIBADD)], + [AC_MSG_ERROR(FastLZ library not found)]) + else + ac_cv_have_fastlz="no" + PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} fastlz/fastlz.c" + fi + + if test "$PHP_MEMCACHED_SESSION" != "no"; then + PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_session.c" + fi + + LIBEVENT_INCLUDES="" + AC_MSG_CHECKING([for memcached protocol support]) + if test "$PHP_MEMCACHED_PROTOCOL" != "no"; then + AC_MSG_RESULT([enabled]) + + AC_CACHE_CHECK([whether libmemcachedprotocol is usable], ac_cv_have_libmemcachedprotocol, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[memcached_binary_protocol_callback_st s_test_impl; + s_test_impl.interface.v1.delete_object = 0; + ]])], + [ac_cv_have_libmemcachedprotocol="yes"], + [ac_cv_have_libmemcachedprotocol="no"] + ) + ]) + + if test "$ac_cv_have_libmemcachedprotocol" != "yes"; then + AC_MSG_ERROR([Cannot enable libmemcached protocol]) + fi + + PHP_ADD_LIBRARY_WITH_PATH(memcachedprotocol, $PHP_LIBMEMCACHED_DIR/$PHP_LIBDIR, MEMCACHED_SHARED_LIBADD) + + AC_MSG_CHECKING([for libevent]) + if $PKG_CONFIG --exists libevent; then + PHP_MEMCACHED_LIBEVENT_VERSION=`$PKG_CONFIG libevent --modversion` + PHP_MEMCACHED_LIBEVENT_PREFIX=`$PKG_CONFIG libevent --variable=prefix` + + AC_MSG_RESULT([found version $PHP_MEMCACHED_LIBEVENT_VERSION, under $PHP_MEMCACHED_LIBEVENT_PREFIX]) + LIBEVENT_LIBS=`$PKG_CONFIG libevent --libs` + LIBEVENT_INCLUDES=`$PKG_CONFIG libevent --cflags` + + PHP_EVAL_LIBLINE($LIBEVENT_LIBS, MEMCACHED_SHARED_LIBADD) + PHP_EVAL_INCLINE($LIBEVENT_INCLUDES) + else + AC_MSG_ERROR(Unable to find libevent installation) + fi + PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_server.c" + AC_DEFINE(HAVE_MEMCACHED_PROTOCOL,1,[Whether memcached protocol is enabled]) + else + AC_MSG_RESULT([disabled]) + fi + + CFLAGS="$ORIG_CFLAGS" + + export PKG_CONFIG_PATH="$ORIG_PKG_CONFIG_PATH" + PHP_SUBST(MEMCACHED_SHARED_LIBADD) + + PHP_NEW_EXTENSION(memcached, $PHP_MEMCACHED_FILES, $ext_shared,,$SESSION_INCLUDES $IGBINARY_INCLUDES $LIBEVENT_INCLUDES $MSGPACK_INCLUDES) + if test "ac_cv_have_fastlz" != "yes"; then + PHP_ADD_BUILD_DIR($ext_builddir/fastlz, 1) + fi + + ifdef([PHP_ADD_EXTENSION_DEP], + [ + PHP_ADD_EXTENSION_DEP(memcached, spl, true) + ]) + fi +fi + diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/config.w32 php-memcached-3.1.4+2.2.0/memcached-3.1.4/config.w32 --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/config.w32 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/config.w32 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,43 @@ +// vim:ft=javascript + +ARG_ENABLE('memcached', 'libmemcached extension', 'no'); + +ARG_ENABLE('memcached-session', 'whether to enable memcached session handler support', 'no'); +ARG_ENABLE('memcached-igbinary', 'whether to enable memcached igbinary serializer support', 'no'); +ARG_ENABLE('memcached-json', 'whether to enable memcached json serializer support', 'no'); + +if (PHP_MEMCACHED == "yes") { + + if (!CHECK_LIB("memcached.lib", "memcached", PHP_MEMCACHED)) { + ERROR("memcached: library 'memcached' not found"); + } + + if (!CHECK_HEADER_ADD_INCLUDE("libmemcached/memcached.h", "CFLAGS_MEMCACHED")) { + ERROR("memcached: header 'libmemcached/memcached.h' not found"); + } + + if (PHP_MEMCACHED_JSON != "no"){ + AC_DEFINE("HAVE_JSON_API",1); + } + + var memcached_extra_src = ""; + + if (PHP_MEMCACHED_SESSION != "no"){ + AC_DEFINE("HAVE_MEMCACHED_SESSION",1); + ADD_EXTENSION_DEP("memcached", "session", true) + memcached_extra_src += " php_memcached_session.c"; + } + + if (PHP_MEMCACHED_IGBINARY != "no"){ + AC_DEFINE("HAVE_MEMCACHED_IGBINARY",1); + ADD_EXTENSION_DEP("memcached", "igbinary", true); + if (!CHECK_HEADER_ADD_INCLUDE("igbinary.h", "CFLAGS_MEMCACHED")) { + ERROR("memcached: header 'igbinary.h' not found"); + } + } + + EXTENSION("memcached", "php_memcached.c php_libmemcached_compat.c g_fmt.c"+memcached_extra_src); + ADD_SOURCES(configure_module_dirname+"\\fastlz", "fastlz.c", "memcached"); + AC_DEFINE("HAVE_MEMCACHED", 1, "memcached support"); + AC_DEFINE("MEMCACHED_EXPORTS", 1) +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/CREDITS php-memcached-3.1.4+2.2.0/memcached-3.1.4/CREDITS --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/CREDITS 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/CREDITS 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,2 @@ +memcached +Andrei Zmievski, Oleg Grenrus (igbinary support) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/fastlz/fastlz.c php-memcached-3.1.4+2.2.0/memcached-3.1.4/fastlz/fastlz.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/fastlz/fastlz.c 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/fastlz/fastlz.c 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,551 @@ +/* + FastLZ - lightning-fast lossless compression library + + Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) + Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) + +/* + * Always check for bound when decompressing. + * Generally it is best to leave it defined. + */ +#define FASTLZ_SAFE + +/* + * Give hints to the compiler for branch prediction optimization. + */ +#if defined(__GNUC__) && (__GNUC__ > 2) +#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1)) +#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0)) +#else +#define FASTLZ_EXPECT_CONDITIONAL(c) (c) +#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c) +#endif + +/* + * Use inlined functions for supported systems. + */ +#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C) +#define FASTLZ_INLINE inline +#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__) +#define FASTLZ_INLINE __inline +#else +#define FASTLZ_INLINE +#endif + +/* + * Prevent accessing more than 8-bit at once, except on x86 architectures. + */ +#if !defined(FASTLZ_STRICT_ALIGN) +#define FASTLZ_STRICT_ALIGN +#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ +#undef FASTLZ_STRICT_ALIGN +#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */ +#undef FASTLZ_STRICT_ALIGN +#elif defined(_M_IX86) /* Intel, MSVC */ +#undef FASTLZ_STRICT_ALIGN +#elif defined(__386) +#undef FASTLZ_STRICT_ALIGN +#elif defined(_X86_) /* MinGW */ +#undef FASTLZ_STRICT_ALIGN +#elif defined(__I86__) /* Digital Mars */ +#undef FASTLZ_STRICT_ALIGN +#endif +#endif + +/* + * FIXME: use preprocessor magic to set this on different platforms! + */ +typedef unsigned char flzuint8; +typedef unsigned short flzuint16; +typedef unsigned int flzuint32; + +/* prototypes */ +int fastlz_compress(const void* input, int length, void* output); +int fastlz_compress_level(int level, const void* input, int length, void* output); +int fastlz_decompress(const void* input, int length, void* output, int maxout); + +#define MAX_COPY 32 +#define MAX_LEN 264 /* 256 + 8 */ +#define MAX_DISTANCE 8192 + +#if !defined(FASTLZ_STRICT_ALIGN) +#define FASTLZ_READU16(p) *((const flzuint16*)(p)) +#else +#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) +#endif + +#define HASH_LOG 13 +#define HASH_SIZE (1<< HASH_LOG) +#define HASH_MASK (HASH_SIZE-1) +#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; } + +#undef FASTLZ_LEVEL +#define FASTLZ_LEVEL 1 + +#undef FASTLZ_COMPRESSOR +#undef FASTLZ_DECOMPRESSOR +#define FASTLZ_COMPRESSOR fastlz1_compress +#define FASTLZ_DECOMPRESSOR fastlz1_decompress +static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); +static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); +#include "fastlz.c" + +#undef FASTLZ_LEVEL +#define FASTLZ_LEVEL 2 + +#undef MAX_DISTANCE +#define MAX_DISTANCE 8191 +#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1) + +#undef FASTLZ_COMPRESSOR +#undef FASTLZ_DECOMPRESSOR +#define FASTLZ_COMPRESSOR fastlz2_compress +#define FASTLZ_DECOMPRESSOR fastlz2_decompress +static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); +static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); +#include "fastlz.c" + +int fastlz_compress(const void* input, int length, void* output) +{ + /* for short block, choose fastlz1 */ + if(length < 65536) + return fastlz1_compress(input, length, output); + + /* else... */ + return fastlz2_compress(input, length, output); +} + +int fastlz_decompress(const void* input, int length, void* output, int maxout) +{ + /* magic identifier for compression level */ + int level = ((*(const flzuint8*)input) >> 5) + 1; + + if(level == 1) + return fastlz1_decompress(input, length, output, maxout); + if(level == 2) + return fastlz2_decompress(input, length, output, maxout); + + /* unknown level, trigger error */ + return 0; +} + +int fastlz_compress_level(int level, const void* input, int length, void* output) +{ + if(level == 1) + return fastlz1_compress(input, length, output); + if(level == 2) + return fastlz2_compress(input, length, output); + + return 0; +} + +#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ + +static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output) +{ + const flzuint8* ip = (const flzuint8*) input; + const flzuint8* ip_bound = ip + length - 2; + const flzuint8* ip_limit = ip + length - 12; + flzuint8* op = (flzuint8*) output; + + const flzuint8* htab[HASH_SIZE]; + const flzuint8** hslot; + flzuint32 hval; + + flzuint32 copy; + + /* sanity check */ + if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4)) + { + if(length) + { + /* create literal copy only */ + *op++ = length-1; + ip_bound++; + while(ip <= ip_bound) + *op++ = *ip++; + return length+1; + } + else + return 0; + } + + /* initializes hash table */ + for (hslot = htab; hslot < htab + HASH_SIZE; hslot++) + *hslot = ip; + + /* we start with literal copy */ + copy = 2; + *op++ = MAX_COPY-1; + *op++ = *ip++; + *op++ = *ip++; + + /* main loop */ + while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) + { + const flzuint8* ref; + flzuint32 distance; + + /* minimum match length */ + flzuint32 len = 3; + + /* comparison starting-point */ + const flzuint8* anchor = ip; + + /* check for a run */ +#if FASTLZ_LEVEL==2 + if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1)) + { + distance = 1; + ip += 3; + ref = anchor - 1 + 3; + goto match; + } +#endif + + /* find potential match */ + HASH_FUNCTION(hval,ip); + hslot = htab + hval; + ref = htab[hval]; + + /* calculate distance to the match */ + distance = anchor - ref; + + /* update hash table */ + *hslot = anchor; + + /* is this a match? check the first 3 bytes */ + if(distance==0 || +#if FASTLZ_LEVEL==1 + (distance >= MAX_DISTANCE) || +#else + (distance >= MAX_FARDISTANCE) || +#endif + *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++) + goto literal; + +#if FASTLZ_LEVEL==2 + /* far, needs at least 5-byte match */ + if(distance >= MAX_DISTANCE) + { + if(*ip++ != *ref++ || *ip++!= *ref++) + goto literal; + len += 2; + } + + match: +#endif + + /* last matched byte */ + ip = anchor + len; + + /* distance is biased */ + distance--; + + if(!distance) + { + /* zero distance means a run */ + flzuint8 x = ip[-1]; + while(ip < ip_bound) + if(*ref++ != x) break; else ip++; + } + else + for(;;) + { + /* safe because the outer check against ip limit */ + if(*ref++ != *ip++) break; + if(*ref++ != *ip++) break; + if(*ref++ != *ip++) break; + if(*ref++ != *ip++) break; + if(*ref++ != *ip++) break; + if(*ref++ != *ip++) break; + if(*ref++ != *ip++) break; + if(*ref++ != *ip++) break; + while(ip < ip_bound) + if(*ref++ != *ip++) break; + break; + } + + /* if we have copied something, adjust the copy count */ + if(copy) + /* copy is biased, '0' means 1 byte copy */ + *(op-copy-1) = copy-1; + else + /* back, to overwrite the copy count */ + op--; + + /* reset literal counter */ + copy = 0; + + /* length is biased, '1' means a match of 3 bytes */ + ip -= 3; + len = ip - anchor; + + /* encode the match */ +#if FASTLZ_LEVEL==2 + if(distance < MAX_DISTANCE) + { + if(len < 7) + { + *op++ = (len << 5) + (distance >> 8); + *op++ = (distance & 255); + } + else + { + *op++ = (7 << 5) + (distance >> 8); + for(len-=7; len >= 255; len-= 255) + *op++ = 255; + *op++ = len; + *op++ = (distance & 255); + } + } + else + { + /* far away, but not yet in the another galaxy... */ + if(len < 7) + { + distance -= MAX_DISTANCE; + *op++ = (len << 5) + 31; + *op++ = 255; + *op++ = distance >> 8; + *op++ = distance & 255; + } + else + { + distance -= MAX_DISTANCE; + *op++ = (7 << 5) + 31; + for(len-=7; len >= 255; len-= 255) + *op++ = 255; + *op++ = len; + *op++ = 255; + *op++ = distance >> 8; + *op++ = distance & 255; + } + } +#else + + if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2)) + while(len > MAX_LEN-2) + { + *op++ = (7 << 5) + (distance >> 8); + *op++ = MAX_LEN - 2 - 7 -2; + *op++ = (distance & 255); + len -= MAX_LEN-2; + } + + if(len < 7) + { + *op++ = (len << 5) + (distance >> 8); + *op++ = (distance & 255); + } + else + { + *op++ = (7 << 5) + (distance >> 8); + *op++ = len - 7; + *op++ = (distance & 255); + } +#endif + + /* update the hash at match boundary */ + HASH_FUNCTION(hval,ip); + htab[hval] = ip++; + HASH_FUNCTION(hval,ip); + htab[hval] = ip++; + + /* assuming literal copy */ + *op++ = MAX_COPY-1; + + continue; + + literal: + *op++ = *anchor++; + ip = anchor; + copy++; + if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) + { + copy = 0; + *op++ = MAX_COPY-1; + } + } + + /* left-over as literal copy */ + ip_bound++; + while(ip <= ip_bound) + { + *op++ = *ip++; + copy++; + if(copy == MAX_COPY) + { + copy = 0; + *op++ = MAX_COPY-1; + } + } + + /* if we have copied something, adjust the copy length */ + if(copy) + *(op-copy-1) = copy-1; + else + op--; + +#if FASTLZ_LEVEL==2 + /* marker for fastlz2 */ + *(flzuint8*)output |= (1 << 5); +#endif + + return op - (flzuint8*)output; +} + +static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout) +{ + const flzuint8* ip = (const flzuint8*) input; + const flzuint8* ip_limit = ip + length; + flzuint8* op = (flzuint8*) output; + flzuint8* op_limit = op + maxout; + flzuint32 ctrl = (*ip++) & 31; + int loop = 1; + + do + { + const flzuint8* ref = op; + flzuint32 len = ctrl >> 5; + flzuint32 ofs = (ctrl & 31) << 8; + + if(ctrl >= 32) + { +#if FASTLZ_LEVEL==2 + flzuint8 code; +#endif + len--; + ref -= ofs; + if (len == 7-1) +#if FASTLZ_LEVEL==1 + len += *ip++; + ref -= *ip++; +#else + do + { + code = *ip++; + len += code; + } while (code==255); + code = *ip++; + ref -= code; + + /* match from 16-bit distance */ + if(FASTLZ_UNEXPECT_CONDITIONAL(code==255)) + if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8))) + { + ofs = (*ip++) << 8; + ofs += *ip++; + ref = op - ofs - MAX_DISTANCE; + } +#endif + +#ifdef FASTLZ_SAFE + if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit)) + return 0; + + if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output)) + return 0; +#endif + + if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) + ctrl = *ip++; + else + loop = 0; + + if(ref == op) + { + /* optimize copy for a run */ + flzuint8 b = ref[-1]; + *op++ = b; + *op++ = b; + *op++ = b; + for(; len; --len) + *op++ = b; + } + else + { +#if !defined(FASTLZ_STRICT_ALIGN) + const flzuint16* p; + flzuint16* q; +#endif + /* copy from reference */ + ref--; + *op++ = *ref++; + *op++ = *ref++; + *op++ = *ref++; + +#if !defined(FASTLZ_STRICT_ALIGN) + /* copy a byte, so that now it's word aligned */ + if(len & 1) + { + *op++ = *ref++; + len--; + } + + /* copy 16-bit at once */ + q = (flzuint16*) op; + op += len; + p = (const flzuint16*) ref; + for(len>>=1; len > 4; len-=4) + { + *q++ = *p++; + *q++ = *p++; + *q++ = *p++; + *q++ = *p++; + } + for(; len; --len) + *q++ = *p++; +#else + for(; len; --len) + *op++ = *ref++; +#endif + } + } + else + { + ctrl++; +#ifdef FASTLZ_SAFE + if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit)) + return 0; + if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit)) + return 0; +#endif + + *op++ = *ip++; + for(--ctrl; ctrl; ctrl--) + *op++ = *ip++; + + loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit); + if(loop) + ctrl = *ip++; + } + } + while(FASTLZ_EXPECT_CONDITIONAL(loop)); + + return op - (flzuint8*)output; +} + +#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/fastlz/fastlz.h php-memcached-3.1.4+2.2.0/memcached-3.1.4/fastlz/fastlz.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/fastlz/fastlz.h 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/fastlz/fastlz.h 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,100 @@ +/* + FastLZ - lightning-fast lossless compression library + + Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) + Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef FASTLZ_H +#define FASTLZ_H + +#define FASTLZ_VERSION 0x000100 + +#define FASTLZ_VERSION_MAJOR 0 +#define FASTLZ_VERSION_MINOR 0 +#define FASTLZ_VERSION_REVISION 0 + +#define FASTLZ_VERSION_STRING "0.1.0" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + Compress a block of data in the input buffer and returns the size of + compressed block. The size of input buffer is specified by length. The + minimum input buffer size is 16. + + The output buffer must be at least 5% larger than the input buffer + and can not be smaller than 66 bytes. + + If the input is not compressible, the return value might be larger than + length (input buffer size). + + The input buffer and the output buffer can not overlap. +*/ + +int fastlz_compress(const void* input, int length, void* output); + +/** + Decompress a block of compressed data and returns the size of the + decompressed block. If error occurs, e.g. the compressed data is + corrupted or the output buffer is not large enough, then 0 (zero) + will be returned instead. + + The input buffer and the output buffer can not overlap. + + Decompression is memory safe and guaranteed not to write the output buffer + more than what is specified in maxout. + */ + +int fastlz_decompress(const void* input, int length, void* output, int maxout); + +/** + Compress a block of data in the input buffer and returns the size of + compressed block. The size of input buffer is specified by length. The + minimum input buffer size is 16. + + The output buffer must be at least 5% larger than the input buffer + and can not be smaller than 66 bytes. + + If the input is not compressible, the return value might be larger than + length (input buffer size). + + The input buffer and the output buffer can not overlap. + + Compression level can be specified in parameter level. At the moment, + only level 1 and level 2 are supported. + Level 1 is the fastest compression and generally useful for short data. + Level 2 is slightly slower but it gives better compression ratio. + + Note that the compressed data, regardless of the level, can always be + decompressed using the function fastlz_decompress above. +*/ + +int fastlz_compress_level(int level, const void* input, int length, void* output); + +#if defined (__cplusplus) +} +#endif + +#endif /* FASTLZ_H */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/fastlz/LICENSE php-memcached-3.1.4+2.2.0/memcached-3.1.4/fastlz/LICENSE --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/fastlz/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/fastlz/LICENSE 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,24 @@ +FastLZ - lightning-fast lossless compression library + +Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) +Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) +Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/g_fmt.c php-memcached-3.1.4+2.2.0/memcached-3.1.4/g_fmt.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/g_fmt.c 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/g_fmt.c 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,101 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 1996 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* g_fmt(buf,x) stores the closest decimal approximation to x in buf; + * it suffices to declare buf + * char buf[32]; + */ + +/* Modified for use with php in the memcached client extension. + * + * // Teddy Grenman , 2010-05-18. + */ + +#include + +char *php_memcached_g_fmt(register char *b, double x) { + register int i, k; + register char *s; + int decpt, j, sign; + char *b0, *s0, *se; + + b0 = b; +#ifdef IGNORE_ZERO_SIGN + if (!x) { + *b++ = '0'; + *b = 0; + goto done; + } +#endif + + s = s0 = zend_dtoa(x, 0, 0, &decpt, &sign, &se); + if (sign) + *b++ = '-'; + if (decpt == 9999) /* Infinity or Nan */ { + while((*b++ = *s++)); + goto done0; + } + if (decpt <= -4 || decpt > se - s + 5) { + *b++ = *s++; + if (*s) { + *b++ = '.'; + while((*b = *s++)) + b++; + } + *b++ = 'e'; + /* sprintf(b, "%+.2d", decpt - 1); */ + if (--decpt < 0) { + *b++ = '-'; + decpt = -decpt; + } + else + *b++ = '+'; + for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10); + for(;;) { + i = decpt / k; + *b++ = i + '0'; + if (--j <= 0) + break; + decpt -= i*k; + decpt *= 10; + } + *b = 0; + } else if (decpt <= 0) { + *b++ = '.'; + for(; decpt < 0; decpt++) + *b++ = '0'; + while((*b++ = *s++)); + } else { + while((*b = *s++)) { + b++; + if (--decpt == 0 && *s) + *b++ = '.'; + } + for(; decpt > 0; decpt--) + *b++ = '0'; + *b = 0; + } + + done0: + zend_freedtoa(s0); +#ifdef IGNORE_ZERO_SIGN + done: +#endif + return b0; +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/g_fmt.h php-memcached-3.1.4+2.2.0/memcached-3.1.4/g_fmt.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/g_fmt.h 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/g_fmt.h 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,34 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 1996 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* g_fmt(buf,x) stores the closest decimal approximation to x in buf; + * it suffices to declare buf + * char buf[32]; + */ + +/* Modified for use with php in the memcached client + * extension by Teddy Grenman, 2010. + */ + +#ifndef MEMC_G_FMT_H +#define MEMC_G_FMT_H + +char *php_memcached_g_fmt(register char *b, double x); + +#endif diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/LICENSE php-memcached-3.1.4+2.2.0/memcached-3.1.4/LICENSE --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/LICENSE 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,68 @@ +-------------------------------------------------------------------- + The PHP License, version 3.01 +Copyright (c) 1999 - 2010 The PHP Group. All rights reserved. +-------------------------------------------------------------------- + +Redistribution and use in source and binary forms, with or without +modification, is permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + 3. The name "PHP" must not be used to endorse or promote products + derived from this software without prior written permission. For + written permission, please contact group@php.net. + + 4. Products derived from this software may not be called "PHP", nor + may "PHP" appear in their name, without prior written permission + from group@php.net. You may indicate that your software works in + conjunction with PHP by saying "Foo for PHP" instead of calling + it "PHP Foo" or "phpfoo" + + 5. The PHP Group may publish revised and/or new versions of the + license from time to time. Each version will be given a + distinguishing version number. + Once covered code has been published under a particular version + of the license, you may always continue to use it under the terms + of that version. You may also choose to use such covered code + under the terms of any subsequent version of the license + published by the PHP Group. No one other than the PHP Group has + the right to modify the terms applicable to covered code created + under this License. + + 6. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes PHP software, freely available from + ". + +THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND +ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP +DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------- + +This software consists of voluntary contributions made by many +individuals on behalf of the PHP Group. + +The PHP Group can be contacted via Email at group@php.net. + +For more information on the PHP Group and the PHP project, +please see . + +PHP includes the Zend Engine, freely available at +. diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/memcached-api.php php-memcached-3.1.4+2.2.0/memcached-3.1.4/memcached-api.php --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/memcached-api.php 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/memcached-api.php 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,376 @@ + comp_len * factor +; +; the default value is 1.3 (23% space saving) +;memcached.compression_factor = "1.3" + +; The compression threshold +; +; Do not compress serialized values below this threshold. +; the default is 2000 bytes +;memcached.compression_threshold = 2000 + +; Set the default serializer for new memcached objects. +; valid values are: php, igbinary, json, json_array, msgpack +; +; json - standard php JSON encoding. This serializer +; is fast and compact but only works on UTF-8 +; encoded data and does not fully implement +; serializing. See the JSON extension. +; json_array - as json, but decodes into arrays +; php - the standard php serializer +; igbinary - a binary serializer +; msgpack - a cross-language binary serializer +; +; The default is igbinary if available, then msgpack if available, then php otherwise. +;memcached.serializer = "igbinary" + +; The amount of retries for failed store commands. +; This mechanism allows transparent fail-over to secondary servers when +; set/increment/decrement/setMulti operations fail on the desired server in a multi-server +; environment. +; the default is 2 +;memcached.store_retry_count = 2 + +; Sets the default for consistent hashing for new connections. +; (To configure consistent hashing for session connections, +; use memcached.sess_consistent_hash instead) +; +; If set to On, consistent hashing (libketama) is used +; for session handling. +; When consistent hashing is used, one can add or remove cache +; node(s) without messing up too much with existing keys +; default is Off +;memcached.default_consistent_hash = Off + +; Sets the default memcached protocol for new connections. +; (To configure the memcached protocol for connections used by sessions, +; use memcached.sess_binary_protocol instead) +; +; If set to On, the memcached binary protocol is used by default. +; If set to Off, the memcached text protocol is used. +; Default is Off +;memcached.default_binary_protocol = Off + +; Sets the default memcached connection timeout for new connections. +; (To configure the memcached connection timeout for sessions, +; use memcached.sess_connect_timeout instead) +; In non-blocking mode this changes the value of the timeout. +; during socket connection in milliseconds. Specifying -1 means an infinite timeout. +; Specifying 0 means using the memcached library's default connection timeout. +; Default is 0. +;memcached.default_connect_timeout = 0 diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_libmemcached_compat.c php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_libmemcached_compat.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_libmemcached_compat.c 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_libmemcached_compat.c 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,59 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#include "php_memcached.h" +#include "php_memcached_private.h" +#include "php_libmemcached_compat.h" + +memcached_return php_memcached_exist(memcached_st *memc, zend_string *key) +{ +#ifdef HAVE_MEMCACHED_EXIST + return memcached_exist(memc, key->val, key->len); +#else + memcached_return rc = MEMCACHED_SUCCESS; + uint32_t flags = 0; + size_t value_length = 0; + char *value = NULL; + + value = memcached_get(memc, key->val, key->len, &value_length, &flags, &rc); + if (value) { + zend_bool *is_persistent = memcached_get_user_data(memc); + pefree(value, *is_persistent); + } + return rc; +#endif +} + +memcached_return php_memcached_touch(memcached_st *memc, const char *key, size_t key_len, time_t expiration) +{ +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { + php_error_docref(NULL, E_WARNING, "using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached"); + } +#endif + return memcached_touch(memc, key, key_len, expiration); +} + +memcached_return php_memcached_touch_by_key(memcached_st *memc, const char *server_key, size_t server_key_len, const char *key, size_t key_len, time_t expiration) +{ +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { + php_error_docref(NULL, E_WARNING, "using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached"); + } +#endif + return memcached_touch_by_key(memc, server_key, server_key_len, key, key_len, expiration); +} + diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_libmemcached_compat.h php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_libmemcached_compat.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_libmemcached_compat.h 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_libmemcached_compat.h 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_LIBMEMCACHED_COMPAT +#define PHP_LIBMEMCACHED_COMPAT + +/* this is the version(s) we support */ +#include + +memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); + +memcached_return php_memcached_touch(memcached_st *memc, const char *key, size_t key_len, time_t expiration); +memcached_return php_memcached_touch_by_key(memcached_st *memc, const char *server_key, size_t server_key_len, const char *key, size_t key_len, time_t expiration); + +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000017 +typedef const memcached_instance_st * php_memcached_instance_st; +#else +typedef memcached_server_instance_st php_memcached_instance_st; +#endif + +#endif diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached.c php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached.c 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached.c 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,4691 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009-2010 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +/* TODO + * - set LIBKETAMA_COMPATIBLE as the default? + * - fix unserialize(serialize($memc)) + */ + +#include "php_memcached.h" +#include "php_memcached_private.h" +#include "php_memcached_server.h" +#include "g_fmt.h" + +#include +#include + +#ifdef HAVE_MEMCACHED_SESSION +# include "php_memcached_session.h" +#endif +#ifdef HAVE_FASTLZ_H +#include +#else +#include "fastlz/fastlz.h" +#endif +#include + +#ifdef HAVE_JSON_API +# include "ext/json/php_json.h" +#endif + +#ifdef HAVE_MEMCACHED_IGBINARY +#ifdef PHP_WIN32 +//Windows extensions are generally built together, +//so it wont be in the installed location +#include "igbinary.h" +#else +# include "ext/igbinary/igbinary.h" +#endif +#endif + +#ifdef HAVE_MEMCACHED_MSGPACK +# include "ext/msgpack/php_msgpack.h" +#endif + +static int le_memc; + +static int php_memc_list_entry(void) { + return le_memc; +} + +/**************************************** + Protocol parameters +****************************************/ +#define MEMC_OBJECT_KEY_MAX_LENGTH 250 + +/**************************************** + Custom options +****************************************/ +#define MEMC_OPT_COMPRESSION -1001 +#define MEMC_OPT_PREFIX_KEY -1002 +#define MEMC_OPT_SERIALIZER -1003 +#define MEMC_OPT_COMPRESSION_TYPE -1004 +#define MEMC_OPT_STORE_RETRY_COUNT -1005 +#define MEMC_OPT_USER_FLAGS -1006 + +/**************************************** + Custom result codes +****************************************/ +#define MEMC_RES_PAYLOAD_FAILURE -1001 + +/**************************************** + Payload value flags +****************************************/ +#define MEMC_CREATE_MASK(start, n_bits) (((1 << n_bits) - 1) << start) + +#define MEMC_MASK_TYPE MEMC_CREATE_MASK(0, 4) +#define MEMC_MASK_INTERNAL MEMC_CREATE_MASK(4, 12) +#define MEMC_MASK_USER MEMC_CREATE_MASK(16, 16) + +#define MEMC_VAL_GET_TYPE(flags) ((flags) & MEMC_MASK_TYPE) +#define MEMC_VAL_SET_TYPE(flags, type) ((flags) |= ((type) & MEMC_MASK_TYPE)) + +#define MEMC_VAL_IS_STRING 0 +#define MEMC_VAL_IS_LONG 1 +#define MEMC_VAL_IS_DOUBLE 2 +#define MEMC_VAL_IS_BOOL 3 +#define MEMC_VAL_IS_SERIALIZED 4 +#define MEMC_VAL_IS_IGBINARY 5 +#define MEMC_VAL_IS_JSON 6 +#define MEMC_VAL_IS_MSGPACK 7 + +#define MEMC_VAL_COMPRESSED (1<<0) +#define MEMC_VAL_COMPRESSION_ZLIB (1<<1) +#define MEMC_VAL_COMPRESSION_FASTLZ (1<<2) + +#define MEMC_VAL_GET_FLAGS(internal_flags) (((internal_flags) & MEMC_MASK_INTERNAL) >> 4) +#define MEMC_VAL_SET_FLAG(internal_flags, internal_flag) ((internal_flags) |= (((internal_flag) << 4) & MEMC_MASK_INTERNAL)) +#define MEMC_VAL_HAS_FLAG(internal_flags, internal_flag) ((MEMC_VAL_GET_FLAGS(internal_flags) & (internal_flag)) == (internal_flag)) +#define MEMC_VAL_DEL_FLAG(internal_flags, internal_flag) (internal_flags &= (~(((internal_flag) << 4) & MEMC_MASK_INTERNAL))) + +/**************************************** + User-defined flags +****************************************/ +#define MEMC_VAL_GET_USER_FLAGS(flags) ((flags & MEMC_MASK_USER) >> 16) +#define MEMC_VAL_SET_USER_FLAGS(flags, udf_flags) ((flags) |= ((udf_flags << 16) & MEMC_MASK_USER)) +#define MEMC_VAL_USER_FLAGS_MAX ((1 << 16) - 1) + +/**************************************** + "get" operation flags +****************************************/ +#define MEMC_GET_PRESERVE_ORDER 1 +#define MEMC_GET_EXTENDED 2 + +/**************************************** + Helper macros +****************************************/ +#define RETURN_FROM_GET RETURN_FALSE + +/**************************************** + Structures and definitions +****************************************/ + +typedef enum { + MEMC_OP_SET, + MEMC_OP_TOUCH, + MEMC_OP_ADD, + MEMC_OP_REPLACE, + MEMC_OP_APPEND, + MEMC_OP_PREPEND +} php_memc_write_op; + +typedef struct { + + zend_bool is_persistent; + zend_bool compression_enabled; + zend_bool encoding_enabled; + + zend_long serializer; + zend_long compression_type; + + zend_long store_retry_count; + zend_long set_udf_flags; + +#ifdef HAVE_MEMCACHED_SASL + zend_bool has_sasl_data; +#endif +} php_memc_user_data_t; + +typedef struct { + memcached_st *memc; + zend_bool is_pristine; + int rescode; + int memc_errno; + zend_object zo; +} php_memc_object_t; + +typedef struct { + size_t num_valid_keys; + + const char **mkeys; + size_t *mkeys_len; + + zend_string **strings; + +} php_memc_keys_t; + +typedef struct { + zval *object; + zend_fcall_info fci; + zend_fcall_info_cache fcc; +} php_memc_result_callback_ctx_t; + +static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) { + return (php_memc_object_t *)((char *)obj - XtOffsetOf(php_memc_object_t, zo)); +} +#define Z_MEMC_OBJ_P(zv) php_memc_fetch_object(Z_OBJ_P(zv)); + +#define MEMC_METHOD_INIT_VARS \ + zval* object = getThis(); \ + php_memc_object_t* intern = NULL; \ + php_memc_user_data_t* memc_user_data = NULL; + +#define MEMC_METHOD_FETCH_OBJECT \ + intern = Z_MEMC_OBJ_P(object); \ + if (!intern->memc) { \ + php_error_docref(NULL, E_WARNING, "Memcached constructor was not called"); \ + return; \ + } \ + memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc); \ + (void)memc_user_data; /* avoid unused variable warning */ + +static +zend_bool s_memc_valid_key_binary(zend_string *key) +{ + return memchr(ZSTR_VAL(key), '\n', ZSTR_LEN(key)) == NULL; +} + +static +zend_bool s_memc_valid_key_ascii(zend_string *key) +{ + const char *str = ZSTR_VAL(key); + size_t i, len = ZSTR_LEN(key); + + for (i = 0; i < len; i++) { + if (iscntrl(str[i]) || isspace(str[i])) + return 0; + } + return 1; +} + +#define MEMC_CHECK_KEY(intern, key) \ + if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ + ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ + (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ + ? !s_memc_valid_key_binary(key) \ + : !s_memc_valid_key_ascii(key) \ + ))) { \ + intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \ + RETURN_FALSE; \ + } + +#ifdef HAVE_MEMCACHED_PROTOCOL +typedef struct { + php_memc_proto_handler_t *handler; + zend_object zo; +} php_memc_server_t; + +static inline php_memc_server_t *php_memc_server_fetch_object(zend_object *obj) { + return (php_memc_server_t *)((char *)obj - XtOffsetOf(php_memc_server_t, zo)); +} +#define Z_MEMC_SERVER_P(zv) php_memc_server_fetch_object(Z_OBJ_P(zv)) + +static zend_object_handlers memcached_server_object_handlers; +static zend_class_entry *memcached_server_ce = NULL; +#endif + +static zend_class_entry *memcached_ce = NULL; +static zend_class_entry *memcached_exception_ce = NULL; +static zend_object_handlers memcached_object_handlers; + +#ifdef HAVE_SPL +static zend_class_entry *spl_ce_RuntimeException = NULL; +#endif + +ZEND_DECLARE_MODULE_GLOBALS(php_memcached) + +#ifdef COMPILE_DL_MEMCACHED +ZEND_GET_MODULE(memcached) +#endif + +static PHP_INI_MH(OnUpdateCompressionType) +{ + if (!new_value) { + MEMC_G(compression_type) = COMPRESSION_TYPE_FASTLZ; + } else if (!strcmp(ZSTR_VAL(new_value), "fastlz")) { + MEMC_G(compression_type) = COMPRESSION_TYPE_FASTLZ; + } else if (!strcmp(ZSTR_VAL(new_value), "zlib")) { + MEMC_G(compression_type) = COMPRESSION_TYPE_ZLIB; + } else { + return FAILURE; + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} + +static PHP_INI_MH(OnUpdateSerializer) +{ + if (!new_value) { + MEMC_G(serializer_type) = SERIALIZER_DEFAULT; + } else if (!strcmp(ZSTR_VAL(new_value), "php")) { + MEMC_G(serializer_type) = SERIALIZER_PHP; +#ifdef HAVE_MEMCACHED_IGBINARY + } else if (!strcmp(ZSTR_VAL(new_value), "igbinary")) { + MEMC_G(serializer_type) = SERIALIZER_IGBINARY; +#endif // IGBINARY +#ifdef HAVE_JSON_API + } else if (!strcmp(ZSTR_VAL(new_value), "json")) { + MEMC_G(serializer_type) = SERIALIZER_JSON; + } else if (!strcmp(ZSTR_VAL(new_value), "json_array")) { + MEMC_G(serializer_type) = SERIALIZER_JSON_ARRAY; +#endif // JSON +#ifdef HAVE_MEMCACHED_MSGPACK + } else if (!strcmp(ZSTR_VAL(new_value), "msgpack")) { + MEMC_G(serializer_type) = SERIALIZER_MSGPACK; +#endif // msgpack + } else { + return FAILURE; + } + + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} + +#ifdef HAVE_MEMCACHED_SESSION +static +PHP_INI_MH(OnUpdateDeprecatedLockValue) +{ + if (ZSTR_LEN(new_value) > 0 && strcmp(ZSTR_VAL(new_value), "not set")) { + php_error_docref(NULL, E_DEPRECATED, "memcached.sess_lock_wait and memcached.sess_lock_max_wait are deprecated. Please update your configuration to use memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries"); + } + return FAILURE; +} + +static +PHP_INI_MH(OnUpdateSessionPrefixString) +{ + if (new_value && ZSTR_LEN(new_value) > 0) { + if (ZSTR_LEN(new_value) > MEMCACHED_MAX_KEY) { + php_error_docref(NULL, E_WARNING, "memcached.sess_prefix too long (max: %d)", MEMCACHED_MAX_KEY - 1); + return FAILURE; + } + if (!s_memc_valid_key_ascii(new_value)) { + php_error_docref(NULL, E_WARNING, "memcached.sess_prefix cannot contain whitespace or control characters"); + return FAILURE; + } + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} + +static +PHP_INI_MH(OnUpdateConsistentHash) +{ + if (!new_value) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; + } else if (!strcmp(ZSTR_VAL(new_value), "ketama")) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; + } else if (!strcmp(ZSTR_VAL(new_value), "ketama_weighted")) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED; + } else { + php_error_docref(NULL, E_WARNING, "memcached.sess_consistent_hash_type must be ketama or ketama_weighted"); + return FAILURE; + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} +#endif // HAVE_MEMCACHED_SESSION + +#define MEMC_INI_ENTRY(key, default_value, update_fn, gkey) \ + STD_PHP_INI_ENTRY("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) + +#define MEMC_INI_BOOL(key, default_value, update_fn, gkey) \ + STD_PHP_INI_BOOLEAN("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) + +#define MEMC_INI_LINK(key, default_value, update_fn, gkey) \ + STD_PHP_INI_ENTRY_EX("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals, display_link_numbers) + +#define MEMC_SESSION_INI_ENTRY(key, default_value, update_fn, gkey) \ + STD_PHP_INI_ENTRY("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) + +#define MEMC_SESSION_INI_BOOL(key, default_value, update_fn, gkey) \ + STD_PHP_INI_BOOLEAN("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) + +#define MEMC_SESSION_INI_LINK(key, default_value, update_fn, gkey) \ + STD_PHP_INI_ENTRY_EX("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals, display_link_numbers) + + +/* {{{ INI entries */ +PHP_INI_BEGIN() + +#ifdef HAVE_MEMCACHED_SESSION + MEMC_SESSION_INI_BOOL ("locking", "1", OnUpdateBool, lock_enabled) + MEMC_SESSION_INI_ENTRY("lock_wait_min", "150", OnUpdateLongGEZero, lock_wait_min) + MEMC_SESSION_INI_ENTRY("lock_wait_max", "150", OnUpdateLongGEZero, lock_wait_max) + MEMC_SESSION_INI_ENTRY("lock_retries", "5", OnUpdateLong, lock_retries) + MEMC_SESSION_INI_ENTRY("lock_expire", "0", OnUpdateLongGEZero, lock_expiration) +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + MEMC_SESSION_INI_BOOL ("binary_protocol", "0", OnUpdateBool, binary_protocol_enabled) +#else + MEMC_SESSION_INI_BOOL ("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled) +#endif + MEMC_SESSION_INI_BOOL ("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) + MEMC_SESSION_INI_ENTRY("consistent_hash_type", "ketama", OnUpdateConsistentHash, consistent_hash_name) + MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas) + MEMC_SESSION_INI_BOOL ("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) + MEMC_SESSION_INI_BOOL ("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) + MEMC_SESSION_INI_ENTRY("server_failure_limit", "0", OnUpdateLongGEZero, server_failure_limit) + MEMC_SESSION_INI_LINK ("connect_timeout", "0", OnUpdateLong, connect_timeout) + + MEMC_SESSION_INI_ENTRY("sasl_username", "", OnUpdateString, sasl_username) + MEMC_SESSION_INI_ENTRY("sasl_password", "", OnUpdateString, sasl_password) + MEMC_SESSION_INI_BOOL ("persistent", "0", OnUpdateBool, persistent_enabled) + MEMC_SESSION_INI_ENTRY("prefix", "memc.sess.key.", OnUpdateSessionPrefixString, prefix) + + /* Deprecated */ + STD_PHP_INI_ENTRY("memcached.sess_lock_wait", "not set", PHP_INI_ALL, OnUpdateDeprecatedLockValue, no_effect, zend_php_memcached_globals, php_memcached_globals) + STD_PHP_INI_ENTRY("memcached.sess_lock_max_wait", "not set", PHP_INI_ALL, OnUpdateDeprecatedLockValue, no_effect, zend_php_memcached_globals, php_memcached_globals) + +#endif + + MEMC_INI_ENTRY("compression_type", "fastlz", OnUpdateCompressionType, compression_name) + MEMC_INI_ENTRY("compression_factor", "1.3", OnUpdateReal, compression_factor) + MEMC_INI_ENTRY("compression_threshold", "2000", OnUpdateLong, compression_threshold) + MEMC_INI_ENTRY("serializer", SERIALIZER_DEFAULT_NAME, OnUpdateSerializer, serializer_name) + MEMC_INI_ENTRY("store_retry_count", "2", OnUpdateLong, store_retry_count) + + MEMC_INI_BOOL ("default_consistent_hash", "0", OnUpdateBool, default_behavior.consistent_hash_enabled) + MEMC_INI_BOOL ("default_binary_protocol", "0", OnUpdateBool, default_behavior.binary_protocol_enabled) + MEMC_INI_LINK ("default_connect_timeout", "0", OnUpdateLong, default_behavior.connect_timeout) + +PHP_INI_END() +/* }}} */ + +#undef MEMC_INI_BOOL +#undef MEMC_INI_LINK +#undef MEMC_INI_ENTRY +#undef MEMC_SESSION_INI_BOOL +#undef MEMC_SESSION_INI_LINK +#undef MEMC_SESSION_INI_ENTRY + +/**************************************** + Forward declarations +****************************************/ +static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); +static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); +static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool by_key); +static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); +static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); +static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); +static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key); + +/* Invoke PHP functions */ +static zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_bool with_cas, zend_string *key, zval *value); + +/* Iterate result sets */ +typedef zend_bool (*php_memc_result_apply_fn)(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *context); + +static +memcached_return php_memc_result_apply(php_memc_object_t *intern, php_memc_result_apply_fn result_apply_fn, zend_bool fetch_delay, void *context); + +static +zend_bool php_memc_mget_apply(php_memc_object_t *intern, zend_string *server_key, + php_memc_keys_t *keys, php_memc_result_apply_fn result_apply_fn, + zend_bool with_cas, void *context); + + +/* Callback functions for different server list iterations */ +static + memcached_return s_server_cursor_list_servers_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context); + +static + memcached_return s_server_cursor_version_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context); + +static + zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, zend_string *server_key, zend_string *key, zval *value, time_t expiration); + +static + void php_memc_destroy(memcached_st *memc, php_memc_user_data_t *memc_user_data); + +static + zend_bool s_memcached_result_to_zval(memcached_st *memc, memcached_result_st *result, zval *return_value); + +static + zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t *flags); + +static + void s_hash_to_keys(php_memc_keys_t *keys_out, HashTable *hash_in, zend_bool preserve_order, zval *return_value); + +static + void s_clear_keys(php_memc_keys_t *keys); + + +/**************************************** + Exported helper functions +****************************************/ + +zend_bool php_memc_init_sasl_if_needed() +{ +#ifdef HAVE_MEMCACHED_SASL + if (MEMC_G(sasl_initialised)) { + return 1; + } + if (sasl_client_init(NULL) != SASL_OK) { + php_error_docref(NULL, E_ERROR, "Failed to initialize SASL library"); + return 0; + } + return 1; +#else + php_error_docref(NULL, E_ERROR, "Memcached not built with sasl support"); + return 0; +#endif +} + +char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) +{ + char *buffer = NULL; + + if (fci->object) { + spprintf (&buffer, 0, "%s::%s", ZSTR_VAL(fci->object->ce->name), ZSTR_VAL(fci_cache->function_handler->common.function_name)); + } else { + if (Z_TYPE (fci->function_name) == IS_OBJECT) { + spprintf (&buffer, 0, "%s", ZSTR_VAL(Z_OBJCE(fci->function_name)->name)); + } + else { + spprintf (&buffer, 0, "%s", Z_STRVAL(fci->function_name)); + } + } + return buffer; +} + + +/**************************************** + Handling error codes +****************************************/ + +static +zend_bool s_memcached_return_is_error(memcached_return status, zend_bool strict) +{ + zend_bool result = 0; + + switch (status) { + case MEMCACHED_SUCCESS: + case MEMCACHED_STORED: + case MEMCACHED_DELETED: + case MEMCACHED_STAT: + case MEMCACHED_END: + case MEMCACHED_BUFFERED: + result = 0; + break; + + case MEMCACHED_SOME_ERRORS: + result = strict; + break; + + default: + result = 1; + break; + } + return result; +} + +static +int s_memc_status_handle_result_code(php_memc_object_t *intern, memcached_return status) +{ + intern->rescode = status; + intern->memc_errno = 0; + + if (s_memcached_return_is_error(status, 1)) { + intern->memc_errno = memcached_last_error_errno(intern->memc); + return FAILURE; + } + return SUCCESS; +} + +static +void s_memc_set_status(php_memc_object_t *intern, memcached_return status, int memc_errno) +{ + intern->rescode = status; + intern->memc_errno = memc_errno; +} + +static +zend_bool s_memc_status_has_error(php_memc_object_t *intern) +{ + return s_memcached_return_is_error(intern->rescode, 1); +} + +static +zend_bool s_memc_status_has_result_code(php_memc_object_t *intern, memcached_return status) +{ + return intern->rescode == status; +} + +/**************************************** + Marshall cas tokens +****************************************/ + +static +void s_uint64_to_zval (zval *target, uint64_t value) +{ + if (value >= ((uint64_t) LONG_MAX)) { + zend_string *buffer; +#ifdef PRIu64 + buffer = strpprintf (0, "%" PRIu64, value); +#else + /* Best effort */ + buffer = strpprintf (0, "%llu", value); +#endif + ZVAL_STR(target, buffer); + } + else { + ZVAL_LONG (target, (zend_long) value); + } +} + +static +uint64_t s_zval_to_uint64 (zval *cas) +{ + switch (Z_TYPE_P (cas)) { + case IS_LONG: + return (uint64_t) zval_get_long (cas); + break; + + case IS_DOUBLE: + if (Z_DVAL_P (cas) < 0.0) + return 0; + + return (uint64_t) zval_get_double (cas); + break; + + case IS_STRING: + { + uint64_t val; + char *end; + + errno = 0; + val = (uint64_t) strtoull (Z_STRVAL_P (cas), &end, 0); + + if (*end || (errno == ERANGE && val == UINT64_MAX) || (errno != 0 && val == 0)) { + php_error_docref(NULL, E_ERROR, "Failed to unmarshall cas token"); + return 0; + } + return val; + } + break; + } + return 0; +} + + +/**************************************** + Iterate over memcached results and mget +****************************************/ + +static +memcached_return php_memc_result_apply(php_memc_object_t *intern, php_memc_result_apply_fn result_apply_fn, zend_bool fetch_delay, void *context) +{ + memcached_result_st result, *result_ptr; + memcached_return rc, status = MEMCACHED_SUCCESS; + + memcached_result_create(intern->memc, &result); + + do { + result_ptr = memcached_fetch_result(intern->memc, &result, &rc); + + if (s_memcached_return_is_error(rc, 0)) { + status = rc; + } + + /* nothing returned */ + if (!result_ptr) { + break; + } + else { + zend_string *key; + zval val, zcas; + zend_bool retval; + + uint64_t cas; + uint32_t flags; + + const char *res_key; + size_t res_key_len; + + if (!s_memcached_result_to_zval(intern->memc, &result, &val)) { + if (EG(exception)) { + status = MEMC_RES_PAYLOAD_FAILURE; + memcached_quit(intern->memc); + break; + } + status = MEMCACHED_SOME_ERRORS; + continue; + } + + res_key = memcached_result_key_value(&result); + res_key_len = memcached_result_key_length(&result); + cas = memcached_result_cas(&result); + flags = memcached_result_flags(&result); + + s_uint64_to_zval(&zcas, cas); + + key = zend_string_init (res_key, res_key_len, 0); + retval = result_apply_fn(intern, key, &val, &zcas, flags, context); + + zend_string_release(key); + zval_ptr_dtor(&val); + zval_ptr_dtor(&zcas); + + /* Stop iterating on false */ + if (!retval) { + if (!fetch_delay) { + /* Make sure we clear our results */ + while (memcached_fetch_result(intern->memc, &result, &rc)) {} + } + break; + } + } + } while (result_ptr != NULL); + + memcached_result_free(&result); + return status; +} + +static +zend_bool php_memc_mget_apply(php_memc_object_t *intern, zend_string *server_key, php_memc_keys_t *keys, + php_memc_result_apply_fn result_apply_fn, zend_bool with_cas, void *context) +{ + memcached_return status; + int mget_status; + uint64_t orig_cas_flag = 0; + + // Reset status code + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + if (!keys->num_valid_keys) { + intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; + return 0; + } + + if (with_cas) { + orig_cas_flag = memcached_behavior_get (intern->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS); + + if (!orig_cas_flag) { + memcached_behavior_set (intern->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1); + } + } + + if (server_key) { + status = memcached_mget_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), keys->mkeys, keys->mkeys_len, keys->num_valid_keys); + } else { + status = memcached_mget(intern->memc, keys->mkeys, keys->mkeys_len, keys->num_valid_keys); + } + + /* Need to handle result code before restoring cas flags, would mess up errno */ + mget_status = s_memc_status_handle_result_code(intern, status); + + if (with_cas && !orig_cas_flag) { + memcached_behavior_set (intern->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag); + } + + /* Return on failure codes */ + if (mget_status == FAILURE) { + return 0; + } + + if (!result_apply_fn) { + /* no callback, for example getDelayed */ + return 1; + } + + status = php_memc_result_apply(intern, result_apply_fn, 0, context); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + return 0; + } + + return 1; +} + +/**************************************** + Invoke callbacks +****************************************/ + +static +zend_bool s_invoke_new_instance_cb(zval *object, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, zend_string *persistent_id) +{ + zend_bool ret = 1; + zval retval; + zval params[2]; + + ZVAL_COPY(¶ms[0], object); + if (persistent_id) { + ZVAL_STR(¶ms[1], zend_string_copy(persistent_id)); + } else { + ZVAL_NULL(¶ms[1]); + } + + fci->retval = &retval; + fci->params = params; + fci->param_count = 2; + + if (zend_call_function(fci, fci_cache) == FAILURE) { + char *buf = php_memc_printable_func (fci, fci_cache); + php_error_docref(NULL, E_WARNING, "Failed to invoke 'on_new' callback %s()", buf); + efree (buf); + ret = 0; + } + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(&retval); + + return ret; +} + +static +zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_bool with_cas, zend_string *key, zval *value) +{ + zend_bool status = 0; + zval params[4]; + zval retval; + php_memc_object_t *intern = Z_MEMC_OBJ_P(zobject); + + /* Prepare params */ + ZVAL_COPY(¶ms[0], zobject); + ZVAL_STR_COPY(¶ms[1], key); /* key */ + ZVAL_NEW_REF(¶ms[2], value); /* value */ + + if (with_cas) { + fci->param_count = 3; + } else { + ZVAL_NEW_EMPTY_REF(¶ms[3]); /* expiration */ + ZVAL_NULL(Z_REFVAL(params[3])); + fci->param_count = 4; + } + + fci->retval = &retval; + fci->params = params; + + if (zend_call_function(fci, fcc) == SUCCESS) { + if (zend_is_true(&retval)) { + time_t expiration; + zval *val = Z_REFVAL(params[2]); + + if (with_cas) { + if (Z_TYPE_P(val) == IS_ARRAY) { + zval *rv = zend_hash_str_find(Z_ARRVAL_P(val), "value", sizeof("value") - 1); + if (rv) { + zval *cas = zend_hash_str_find(Z_ARRVAL_P(val), "cas", sizeof("cas") -1); + expiration = cas? Z_LVAL_P(cas) : 0; + status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, rv, expiration); + } + /* memleak? zval_ptr_dtor(value); */ + ZVAL_COPY(value, val); + } + } else { + expiration = zval_get_long(Z_REFVAL(params[3])); + status = s_memc_write_zval (intern, MEMC_OP_SET, NULL, key, val, expiration); + /* memleak? zval_ptr_dtor(value); */ + ZVAL_COPY(value, val); + } + } + } + else { + s_memc_set_status(intern, MEMCACHED_NOTFOUND, 0); + } + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + if (!with_cas) { + zval_ptr_dtor(¶ms[3]); + } + zval_ptr_dtor(&retval); + + return status; +} + +/**************************************** + Wrapper for setting from zval +****************************************/ + +static +zend_bool s_compress_value (php_memc_compression_type compression_type, zend_string **payload_in, uint32_t *flags) +{ + /* status */ + zend_bool compress_status = 0; + zend_string *payload = *payload_in; + uint32_t compression_type_flag = 0; + + /* Additional 5% for the data */ + size_t buffer_size = (size_t) (((double) ZSTR_LEN(payload) * 1.05) + 1.0); + char *buffer = emalloc(buffer_size); + + /* Store compressed size here */ + size_t compressed_size = 0; + uint32_t original_size = ZSTR_LEN(payload); + + switch (compression_type) { + + case COMPRESSION_TYPE_FASTLZ: + { + compressed_size = fastlz_compress(ZSTR_VAL(payload), ZSTR_LEN(payload), buffer); + + if (compressed_size > 0) { + compress_status = 1; + compression_type_flag = MEMC_VAL_COMPRESSION_FASTLZ; + } + } + break; + + case COMPRESSION_TYPE_ZLIB: + { + compressed_size = buffer_size; + int status = compress((Bytef *) buffer, &compressed_size, (Bytef *) ZSTR_VAL(payload), ZSTR_LEN(payload)); + + if (status == Z_OK) { + compress_status = 1; + compression_type_flag = MEMC_VAL_COMPRESSION_ZLIB; + } + } + break; + + default: + compress_status = 0; + break; + } + + /* This means the value was too small to be compressed and ended up larger */ + if (ZSTR_LEN(payload) <= (compressed_size * MEMC_G(compression_factor))) { + compress_status = 0; + } + + /* Replace the payload with the compressed copy */ + if (compress_status) { + MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED | compression_type_flag); + payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0); + + /* Copy the uin32_t at the beginning */ + memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t)); + memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size); + efree(buffer); + + zend_string_forget_hash_val(payload); + *payload_in = payload; + + return 1; + } + + /* Original payload was not modified */ + efree(buffer); + return 0; +} + +static +zend_bool s_serialize_value (php_memc_serializer_type serializer, zval *value, smart_str *buf, uint32_t *flags) +{ + switch (serializer) { + + /* + Igbinary serialization + */ +#ifdef HAVE_MEMCACHED_IGBINARY + case SERIALIZER_IGBINARY: + { + uint8_t *buffer; + size_t buffer_len; + + if (igbinary_serialize(&buffer, &buffer_len, value) != 0) { + php_error_docref(NULL, E_WARNING, "could not serialize value with igbinary"); + return 0; + } + smart_str_appendl (buf, (char *)buffer, buffer_len); + efree(buffer); + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_IGBINARY); + } + break; +#endif + + /* + JSON serialization + */ +#ifdef HAVE_JSON_API + case SERIALIZER_JSON: + case SERIALIZER_JSON_ARRAY: + { + php_json_encode(buf, value, 0); + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_JSON); + } + break; +#endif + + /* + msgpack serialization + */ +#ifdef HAVE_MEMCACHED_MSGPACK + case SERIALIZER_MSGPACK: + php_msgpack_serialize(buf, value); + if (!buf->s) { + php_error_docref(NULL, E_WARNING, "could not serialize value with msgpack"); + return 0; + } + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_MSGPACK); + break; +#endif + + /* + PHP serialization + */ + default: + { + php_serialize_data_t var_hash; + PHP_VAR_SERIALIZE_INIT(var_hash); + php_var_serialize(buf, value, &var_hash); + PHP_VAR_SERIALIZE_DESTROY(var_hash); + + if (!buf->s) { + php_error_docref(NULL, E_WARNING, "could not serialize value"); + return 0; + } + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_SERIALIZED); + } + break; + } + + /* Check for exceptions caused by serializers */ + if (EG(exception) && buf->s->len) { + return 0; + } + return 1; +} + +static +zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t *flags) +{ + zend_string *payload; + php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); + zend_bool should_compress = memc_user_data->compression_enabled; + + switch (Z_TYPE_P(value)) { + + case IS_STRING: + payload = zval_get_string(value); + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_STRING); + break; + + case IS_LONG: + { + smart_str buffer = {0}; + smart_str_append_long (&buffer, Z_LVAL_P(value)); + smart_str_0(&buffer); + payload = buffer.s; + + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_LONG); + should_compress = 0; + } + break; + + case IS_DOUBLE: + { + char buffer[40]; + php_memcached_g_fmt(buffer, Z_DVAL_P(value)); + payload = zend_string_init (buffer, strlen (buffer), 0); + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_DOUBLE); + should_compress = 0; + } + break; + + case IS_TRUE: + payload = zend_string_init ("1", 1, 0); + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL); + should_compress = 0; + break; + + case IS_FALSE: + payload = zend_string_alloc (0, 0); + MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_BOOL); + should_compress = 0; + break; + + default: + { + smart_str buffer = {0}; + + if (!s_serialize_value (memc_user_data->serializer, value, &buffer, flags)) { + smart_str_free(&buffer); + return NULL; + } + payload = buffer.s; + } + break; + } + + /* turn off compression for values below the threshold */ + if (ZSTR_LEN(payload) == 0 || ZSTR_LEN(payload) < MEMC_G(compression_threshold)) { + should_compress = 0; + } + + /* If we have compression flag, compress the value */ + if (should_compress) { + /* s_compress_value() will always leave a valid payload, even if that payload + * did not actually get compressed. The flags will be set according to the + * to the compression type or no compression. + * + * No need to check the return value because the payload is always valid. + */ + (void)s_compress_value (memc_user_data->compression_type, &payload, flags); + } + + if (memc_user_data->set_udf_flags >= 0) { + MEMC_VAL_SET_USER_FLAGS(*flags, ((uint32_t) memc_user_data->set_udf_flags)); + } + + return payload; +} + +static +zend_bool s_should_retry_write (php_memc_object_t *intern, memcached_return status) +{ + if (memcached_server_count (intern->memc) == 0) { + return 0; + } + + return s_memcached_return_is_error (status, 1); +} + +static +zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, zend_string *server_key, zend_string *key, zval *value, time_t expiration) +{ + uint32_t flags = 0; + zend_string *payload = NULL; + memcached_return status = 0; + php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); + zend_long retries = memc_user_data->store_retry_count; + + if (value) { + payload = s_zval_to_payload(intern, value, &flags); + + if (!payload) { + s_memc_set_status(intern, MEMC_RES_PAYLOAD_FAILURE, 0); + return 0; + } + } + +#define memc_write_using_fn(fn_name) payload ? fn_name(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags) : MEMC_RES_PAYLOAD_FAILURE; +#define memc_write_using_fn_by_key(fn_name) payload ? fn_name(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags) : MEMC_RES_PAYLOAD_FAILURE; + + if (server_key) { + switch (op) { + case MEMC_OP_SET: + status = memc_write_using_fn_by_key(memcached_set_by_key); + break; + + case MEMC_OP_TOUCH: + status = php_memcached_touch_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), expiration); + break; + + case MEMC_OP_ADD: + status = memc_write_using_fn_by_key(memcached_add_by_key); + break; + + case MEMC_OP_REPLACE: + status = memc_write_using_fn_by_key(memcached_replace_by_key); + break; + + case MEMC_OP_APPEND: + status = memc_write_using_fn_by_key(memcached_append_by_key); + break; + + case MEMC_OP_PREPEND: + status = memc_write_using_fn_by_key(memcached_prepend_by_key); + break; + } + + if (status == MEMCACHED_END) { + status = MEMCACHED_SUCCESS; + } + } + else { +retry: + switch (op) { + case MEMC_OP_SET: + status = memc_write_using_fn(memcached_set); + break; + + case MEMC_OP_TOUCH: + status = php_memcached_touch(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), expiration); + break; + + case MEMC_OP_ADD: + status = memc_write_using_fn(memcached_add); + break; + + case MEMC_OP_REPLACE: + status = memc_write_using_fn(memcached_replace); + break; + + case MEMC_OP_APPEND: + status = memc_write_using_fn(memcached_append); + break; + + case MEMC_OP_PREPEND: + status = memc_write_using_fn(memcached_prepend); + break; + } + if (status == MEMCACHED_END) { + status = MEMCACHED_SUCCESS; + } + } + + if (s_should_retry_write (intern, status) && retries-- > 0) { + goto retry; + } + +#undef memc_write_using_fn +#undef memc_write_using_fn_by_key + + if (payload) { + zend_string_release(payload); + } + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + return 0; + } + return 1; +} + + +/**************************************** + Methods +****************************************/ + + +/* {{{ Memcached::__construct([string persistent_id[, callback on_new[, string connection_str]]])) + Creates a Memcached object, optionally using persistent memcache connection */ +static PHP_METHOD(Memcached, __construct) +{ + php_memc_object_t *intern; + php_memc_user_data_t *memc_user_data; + + zend_string *persistent_id = NULL; + zend_string *conn_str = NULL; + zend_string *plist_key = NULL; + zend_fcall_info fci = {0}; + zend_fcall_info_cache fci_cache; + + zend_bool is_persistent = 0; + + /* "|S!f!S" */ + ZEND_PARSE_PARAMETERS_START(0, 3) + Z_PARAM_OPTIONAL + Z_PARAM_STR_EX(persistent_id, 1, 0) + Z_PARAM_FUNC_EX(fci, fci_cache, 1, 0) + Z_PARAM_STR(conn_str) + ZEND_PARSE_PARAMETERS_END(); + + intern = Z_MEMC_OBJ_P(getThis()); + intern->is_pristine = 1; + + if (persistent_id && persistent_id->len) { + zend_resource *le; + + plist_key = zend_string_alloc(sizeof("memcached:id=") + persistent_id->len - 1, 0); + snprintf(ZSTR_VAL(plist_key), plist_key->len + 1, "memcached:id=%s", ZSTR_VAL(persistent_id)); + + if ((le = zend_hash_find_ptr(&EG(persistent_list), plist_key)) != NULL) { + if (le->type == php_memc_list_entry()) { + intern->memc = le->ptr; + intern->is_pristine = 0; + zend_string_release (plist_key); + return; + } + } + is_persistent = 1; + } + + if (conn_str && conn_str->len > 0) { + intern->memc = memcached (ZSTR_VAL(conn_str), ZSTR_LEN(conn_str)); + } + else { + intern->memc = memcached (NULL, 0); + } + + if (!intern->memc) { + php_error_docref(NULL, E_ERROR, "Failed to allocate memory for memcached structure"); + /* never reached */ + } + + memc_user_data = pecalloc (1, sizeof(*memc_user_data), is_persistent); + memc_user_data->serializer = MEMC_G(serializer_type); + memc_user_data->compression_type = MEMC_G(compression_type); + memc_user_data->compression_enabled = 1; + memc_user_data->encoding_enabled = 0; + memc_user_data->store_retry_count = MEMC_G(store_retry_count); + memc_user_data->set_udf_flags = -1; + memc_user_data->is_persistent = is_persistent; + + memcached_set_user_data(intern->memc, memc_user_data); + + /* Set default behaviors */ + if (MEMC_G(default_behavior.consistent_hash_enabled)) { + memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT); + if (rc != MEMCACHED_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to turn on consistent hash: %s", memcached_strerror(intern->memc, rc)); + } + } + + if (MEMC_G(default_behavior.binary_protocol_enabled)) { + memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); + if (rc != MEMCACHED_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to turn on binary protocol: %s", memcached_strerror(intern->memc, rc)); + } + } + + if (MEMC_G(default_behavior.connect_timeout)) { + memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, MEMC_G(default_behavior.connect_timeout)); + if (rc != MEMCACHED_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to set connect timeout: %s", memcached_strerror(intern->memc, rc)); + } + } + + if (fci.size) { + if (!s_invoke_new_instance_cb(getThis(), &fci, &fci_cache, persistent_id) || EG(exception)) { + /* error calling or exception thrown from callback */ + if (plist_key) { + zend_string_release(plist_key); + } + /* + Setting intern->memc null prevents object destruction from freeing the memcached_st + We free it manually here because it might be persistent and has not been + registered to persistent_list yet + */ + php_memc_destroy(intern->memc, memc_user_data); + intern->memc = NULL; + return; + } + } + + if (plist_key) { + zend_resource le; + + le.type = php_memc_list_entry(); + le.ptr = intern->memc; + + GC_SET_REFCOUNT(&le, 1); + + /* plist_key is not a persistent allocated key, thus we use str_update here */ + if (zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(plist_key), ZSTR_LEN(plist_key), &le, sizeof(le)) == NULL) { + zend_string_release(plist_key); + php_error_docref(NULL, E_ERROR, "could not register persistent entry"); + /* not reached */ + } + zend_string_release(plist_key); + } +} +/* }}} */ + + + +static +void s_hash_to_keys(php_memc_keys_t *keys_out, HashTable *hash_in, zend_bool preserve_order, zval *return_value) +{ + size_t idx = 0, alloc_count; + zval *zv; + + keys_out->num_valid_keys = 0; + + alloc_count = zend_hash_num_elements(hash_in); + if (!alloc_count) { + return; + } + keys_out->mkeys = ecalloc (alloc_count, sizeof (char *)); + keys_out->mkeys_len = ecalloc (alloc_count, sizeof (size_t)); + keys_out->strings = ecalloc (alloc_count, sizeof (zend_string *)); + + ZEND_HASH_FOREACH_VAL(hash_in, zv) { + zend_string *key = zval_get_string(zv); + + if (preserve_order && return_value) { + add_assoc_null_ex(return_value, ZSTR_VAL(key), ZSTR_LEN(key)); + } + + if (ZSTR_LEN(key) > 0 && ZSTR_LEN(key) < MEMCACHED_MAX_KEY) { + keys_out->mkeys[idx] = ZSTR_VAL(key); + keys_out->mkeys_len[idx] = ZSTR_LEN(key); + + keys_out->strings[idx] = key; + idx++; + } + else { + zend_string_release (key); + } + + } ZEND_HASH_FOREACH_END(); + + if (!idx) { + efree (keys_out->mkeys); + efree (keys_out->mkeys_len); + efree (keys_out->strings); + } + keys_out->num_valid_keys = idx; +} + +static +void s_key_to_keys(php_memc_keys_t *keys_out, zend_string *key) +{ + zval zv_keys; + + array_init(&zv_keys); + add_next_index_str(&zv_keys, zend_string_copy(key)); + + s_hash_to_keys(keys_out, Z_ARRVAL(zv_keys), 0, NULL); + zval_ptr_dtor(&zv_keys); +} + +static +void s_clear_keys(php_memc_keys_t *keys) +{ + size_t i; + + if (!keys->num_valid_keys) { + return; + } + + for (i = 0; i < keys->num_valid_keys; i++) { + zend_string_release (keys->strings[i]); + } + efree(keys->strings); + efree(keys->mkeys); + efree(keys->mkeys_len); +} + +typedef struct { + zend_bool extended; + zval *return_value; +} php_memc_get_ctx_t; + +static +zend_bool s_get_apply_fn(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) +{ + php_memc_get_ctx_t *context = (php_memc_get_ctx_t *) in_context; + + if (context->extended) { + Z_TRY_ADDREF_P(value); + Z_TRY_ADDREF_P(cas); + + array_init (context->return_value); + add_assoc_zval (context->return_value, "value", value); + add_assoc_zval (context->return_value, "cas", cas); + add_assoc_long (context->return_value, "flags", (zend_long) MEMC_VAL_GET_USER_FLAGS(flags)); + } + else { + ZVAL_COPY(context->return_value, value); + } + return 0; /* Stop after one */ +} + +static +void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) +{ + php_memc_get_ctx_t context = {0}; + php_memc_keys_t keys = {0}; + zend_long get_flags = 0; + zend_string *key; + zend_string *server_key = NULL; + zend_bool mget_status; + memcached_return status = MEMCACHED_SUCCESS; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + MEMC_METHOD_INIT_VARS; + + if (by_key) { + /* "SS|f!l" */ + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + Z_PARAM_LONG(get_flags) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "S|f!l" */ + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + Z_PARAM_LONG(get_flags) + ZEND_PARSE_PARAMETERS_END(); + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + MEMC_CHECK_KEY(intern, key); + + context.extended = (get_flags & MEMC_GET_EXTENDED); + + context.return_value = return_value; + + s_key_to_keys(&keys, key); + mget_status = php_memc_mget_apply(intern, server_key, &keys, s_get_apply_fn, context.extended, &context); + s_clear_keys(&keys); + + if (!mget_status) { + if (s_memc_status_has_result_code(intern, MEMCACHED_NOTFOUND) && fci.size > 0) { + status = s_invoke_cache_callback(object, &fci, &fcc, context.extended, key, return_value); + + if (!status) { + zval_ptr_dtor(return_value); + RETURN_FROM_GET; + } + } + } + + if (s_memc_status_has_error(intern)) { + zval_ptr_dtor(return_value); + RETURN_FROM_GET; + } +} + +/* {{{ Memcached::get(string key [, mixed callback [, int get_flags = 0]) + Returns a value for the given key or false */ +PHP_METHOD(Memcached, get) +{ + php_memc_get_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Memcached::getByKey(string server_key, string key [, mixed callback [, int get_flags = 0]) + Returns a value for key from the server identified by the server key or false */ +PHP_METHOD(Memcached, getByKey) +{ + php_memc_get_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +static +zend_bool s_get_multi_apply_fn(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) +{ + php_memc_get_ctx_t *context = (php_memc_get_ctx_t *) in_context; + + Z_TRY_ADDREF_P(value); + + if (context->extended) { + zval node; + + Z_TRY_ADDREF_P(cas); + + array_init(&node); + add_assoc_zval(&node, "value", value); + add_assoc_zval(&node, "cas", cas); + add_assoc_long(&node, "flags", (zend_long) MEMC_VAL_GET_USER_FLAGS(flags)); + + zend_symtable_update(Z_ARRVAL_P(context->return_value), key, &node); + } + else { + zend_symtable_update(Z_ARRVAL_P(context->return_value), key, value); + } + return 1; +} + +/* {{{ -- php_memc_getMulti_impl */ +static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) +{ + php_memc_get_ctx_t context; + php_memc_keys_t keys_out; + + zval *keys = NULL; + zend_string *server_key = NULL; + zend_long flags = 0; + MEMC_METHOD_INIT_VARS; + zend_bool retval, preserve_order; + + if (by_key) { + /* "Sa|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY(keys) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "a|l" */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ARRAY(keys) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); + } + + MEMC_METHOD_FETCH_OBJECT; + + array_init(return_value); + if (zend_hash_num_elements(Z_ARRVAL_P(keys)) == 0) { + /* BC compatible */ + s_memc_set_status(intern, MEMCACHED_NOTFOUND, 0); + return; + } + + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + preserve_order = (flags & MEMC_GET_PRESERVE_ORDER); + s_hash_to_keys(&keys_out, Z_ARRVAL_P(keys), preserve_order, return_value); + + context.extended = (flags & MEMC_GET_EXTENDED); + context.return_value = return_value; + + retval = php_memc_mget_apply(intern, server_key, &keys_out, s_get_multi_apply_fn, context.extended, &context); + + s_clear_keys(&keys_out); + + if (!retval && (s_memc_status_has_result_code(intern, MEMCACHED_NOTFOUND) || s_memc_status_has_result_code(intern, MEMCACHED_SOME_ERRORS))) { + return; + } + + if (!retval || EG(exception)) { + zval_dtor(return_value); + RETURN_FROM_GET; + } +} +/* }}} */ + +/* {{{ Memcached::getMulti(array keys[, long flags = 0 ]) + Returns values for the given keys or false */ +PHP_METHOD(Memcached, getMulti) +{ + php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Memcached::getMultiByKey(string server_key, array keys[, long flags = 0 ]) + Returns values for the given keys from the server identified by the server key or false */ +PHP_METHOD(Memcached, getMultiByKey) +{ + php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ Memcached::getDelayed(array keys [, bool with_cas [, mixed callback ] ]) + Sends a request for the given keys and returns immediately */ +PHP_METHOD(Memcached, getDelayed) +{ + php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Memcached::getDelayedByKey(string server_key, array keys [, bool with_cas [, mixed callback ] ]) + Sends a request for the given keys from the server identified by the server key and returns immediately */ +PHP_METHOD(Memcached, getDelayedByKey) +{ + php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + + +static +void s_create_result_array(zend_string *key, zval *value, zval *cas, uint32_t flags, zval *return_value) +{ + Z_TRY_ADDREF_P(value); + Z_TRY_ADDREF_P(cas); + + add_assoc_str_ex(return_value, ZEND_STRL("key"), zend_string_copy(key)); + add_assoc_zval_ex(return_value, ZEND_STRL("value"), value); + + if (Z_LVAL_P(cas)) { + /* BC compatible */ + add_assoc_zval_ex(return_value, ZEND_STRL("cas"), cas); + add_assoc_long_ex(return_value, ZEND_STRL("flags"), MEMC_VAL_GET_USER_FLAGS(flags)); + } +} + +static +zend_bool s_result_callback_apply(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) +{ + zend_bool status = 1; + zval params[2]; + zval retval; + php_memc_result_callback_ctx_t *context = (php_memc_result_callback_ctx_t *) in_context; + + ZVAL_COPY(¶ms[0], context->object); + array_init(¶ms[1]); + + s_create_result_array(key, value, cas, flags, ¶ms[1]); + + context->fci.retval = &retval; + context->fci.params = params; + context->fci.param_count = 2; + + if (zend_call_function(&context->fci, &context->fcc) == FAILURE) { + php_error_docref(NULL, E_WARNING, "could not invoke result callback"); + status = 0; + } + + zval_ptr_dtor(&retval); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + + return status; +} + +/* {{{ -- php_memc_getDelayed_impl */ +static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) +{ + php_memc_keys_t keys_out = {0}; + + zval *keys = NULL; + zend_string *server_key = NULL; + zend_bool with_cas = 0; + + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + memcached_return status = MEMCACHED_SUCCESS; + MEMC_METHOD_INIT_VARS; + + + if (by_key) { + /* "Sa/|bf!" */ + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY_EX(keys, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(with_cas) + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "a/|bf!" */ + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_ARRAY_EX(keys, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(with_cas) + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + ZEND_PARSE_PARAMETERS_END(); + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + s_hash_to_keys(&keys_out, Z_ARRVAL_P(keys), 0, NULL); + + if (fci.size > 0) { + php_memc_result_callback_ctx_t context = { + getThis(), fci, fcc + }; + status = php_memc_mget_apply(intern, server_key, &keys_out, &s_result_callback_apply, with_cas, (void *) &context); + } + else { + status = php_memc_mget_apply(intern, server_key, &keys_out, NULL, with_cas, NULL); + } + + s_clear_keys(&keys_out); + RETURN_BOOL(status); +} +/* }}} */ + +static +zend_bool s_fetch_apply(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) +{ + zval *return_value = (zval *) in_context; + s_create_result_array(key, value, cas, flags, return_value); + + return 0; // stop iterating after one +} + +/* {{{ Memcached::fetch() + Returns the next result from a previous delayed request */ +PHP_METHOD(Memcached, fetch) +{ + memcached_return status = MEMCACHED_SUCCESS; + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + array_init(return_value); + status = php_memc_result_apply(intern, s_fetch_apply, 1, return_value); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + zval_ptr_dtor(return_value); + RETURN_FROM_GET; + } +} +/* }}} */ + +static +zend_bool s_fetch_all_apply(php_memc_object_t *intern, zend_string *key, zval *value, zval *cas, uint32_t flags, void *in_context) +{ + zval zv; + zval *return_value = (zval *) in_context; + + array_init (&zv); + s_create_result_array(key, value, cas, flags, &zv); + + add_next_index_zval(return_value, &zv); + return 1; +} + +/* {{{ Memcached::fetchAll() + Returns all the results from a previous delayed request */ +PHP_METHOD(Memcached, fetchAll) +{ + memcached_return status = MEMCACHED_SUCCESS; + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + array_init(return_value); + status = php_memc_result_apply(intern, s_fetch_all_apply, 0, return_value); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + zval_dtor(return_value); + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Memcached::set(string key, mixed value [, int expiration ]) + Sets the value for the given key */ +PHP_METHOD(Memcached, set) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_SET, 0); +} +/* }}} */ + +/* {{{ Memcached::setByKey(string server_key, string key, mixed value [, int expiration ]) + Sets the value for the given key on the server identified by the server key */ +PHP_METHOD(Memcached, setByKey) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_SET, 1); +} +/* }}} */ + +/* {{{ Memcached::touch(string key, [, int expiration ]) + Sets a new expiration for the given key */ +PHP_METHOD(Memcached, touch) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 0); +} +/* }}} */ + +/* {{{ Memcached::touchbyKey(string key, [, int expiration ]) + Sets a new expiration for the given key */ +PHP_METHOD(Memcached, touchByKey) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 1); +} +/* }}} */ + +/* {{{ Memcached::setMulti(array items [, int expiration ]) + Sets the keys/values specified in the items array */ +PHP_METHOD(Memcached, setMulti) +{ + php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Memcached::setMultiByKey(string server_key, array items [, int expiration ]) + Sets the keys/values specified in the items array on the server identified by the given server key */ +PHP_METHOD(Memcached, setMultiByKey) +{ + php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ -- php_memc_setMulti_impl */ +static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) +{ + zval *entries; + zend_string *server_key = NULL; + zend_long expiration = 0, ignored; + zval *value; + zend_string *skey; + zend_ulong num_key; + int tmp_len = 0; + MEMC_METHOD_INIT_VARS; + + if (by_key) { + /* "Sa|ll" */ + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY(entries) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "a|ll" */ + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_ARRAY(entries) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P(entries), num_key, skey, value) { + zend_string *str_key = NULL; + + if (skey) { + str_key = skey; + } + else { + char tmp_key[64]; + + tmp_len = snprintf(tmp_key, sizeof(tmp_key) - 1, "%ld", (long)num_key); + str_key = zend_string_init(tmp_key, tmp_len, 0); + } + + if (!s_memc_write_zval (intern, MEMC_OP_SET, server_key, str_key, value, expiration)) { + php_error_docref(NULL, E_WARNING, "failed to set key %s", ZSTR_VAL(str_key)); + } + + if (!skey) { + zend_string_release (str_key); + } + + } ZEND_HASH_FOREACH_END(); + + RETURN_BOOL(!s_memc_status_has_error(intern)); +} +/* }}} */ + +/* {{{ Memcached::add(string key, mixed value [, int expiration ]) + Sets the value for the given key, failing if the key already exists */ +PHP_METHOD(Memcached, add) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_ADD, 0); +} +/* }}} */ + +/* {{{ Memcached::addByKey(string server_key, string key, mixed value [, int expiration ]) + Sets the value for the given key on the server identified by the sever key, failing if the key already exists */ +PHP_METHOD(Memcached, addByKey) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_ADD, 1); +} +/* }}} */ + +/* {{{ Memcached::append(string key, mixed value) + Appends the value to existing one for the key */ +PHP_METHOD(Memcached, append) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_APPEND, 0); +} +/* }}} */ + +/* {{{ Memcached::appendByKey(string server_key, string key, mixed value) + Appends the value to existing one for the key on the server identified by the server key */ +PHP_METHOD(Memcached, appendByKey) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_APPEND, 1); +} +/* }}} */ + +/* {{{ Memcached::prepend(string key, mixed value) + Prepends the value to existing one for the key */ +PHP_METHOD(Memcached, prepend) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_PREPEND, 0); +} +/* }}} */ + +/* {{{ Memcached::prependByKey(string server_key, string key, mixed value) + Prepends the value to existing one for the key on the server identified by the server key */ +PHP_METHOD(Memcached, prependByKey) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_PREPEND, 1); +} +/* }}} */ + +/* {{{ Memcached::replace(string key, mixed value [, int expiration ]) + Replaces the value for the given key, failing if the key doesn't exist */ +PHP_METHOD(Memcached, replace) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_REPLACE, 0); +} +/* }}} */ + +/* {{{ Memcached::replaceByKey(string server_key, string key, mixed value [, int expiration ]) + Replaces the value for the given key on the server identified by the server key, failing if the key doesn't exist */ +PHP_METHOD(Memcached, replaceByKey) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_REPLACE, 1); +} +/* }}} */ + +/* {{{ -- php_memc_store_impl */ +static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool by_key) +{ + zend_string *key; + zend_string *server_key = NULL; + zend_string *s_value; + zval s_zvalue; + zval *value = NULL; + zend_long expiration = 0; + MEMC_METHOD_INIT_VARS; + + if (by_key) { + if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { + /* "SSS" */ + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_STR(s_value) + ZEND_PARSE_PARAMETERS_END(); + value = &s_zvalue; + ZVAL_STR(value, s_value); + } else if (op == MEMC_OP_TOUCH) { + /* "SS|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "SSz|l" */ + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + } + } else { + if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { + /* "SS" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR(key) + Z_PARAM_STR(s_value) + ZEND_PARSE_PARAMETERS_END(); + value = &s_zvalue; + ZVAL_STR(value, s_value); + } else if (op == MEMC_OP_TOUCH) { + /* "S|l */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "Sz|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + } + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + MEMC_CHECK_KEY(intern, key); + + if (memc_user_data->compression_enabled) { + /* + * When compression is enabled, we cannot do appends/prepends because that would + * corrupt the compressed values. It is up to the user to fetch the value, + * append/prepend new data, and store it again. + */ + if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { + php_error_docref(NULL, E_WARNING, "cannot append/prepend with compression turned on"); + RETURN_NULL(); + } + } + + if (!s_memc_write_zval (intern, op, server_key, key, value, expiration)) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ -- php_memc_cas_impl */ +static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) +{ + zval *zv_cas; + uint64_t cas; + zend_string *key; + zend_string *server_key = NULL; + zval *value; + zend_long expiration = 0; + zend_long ignored; + zend_string *payload; + uint32_t flags = 0; + memcached_return status; + MEMC_METHOD_INIT_VARS; + + if (by_key) { + /* "zSSz|ll" */ + ZEND_PARSE_PARAMETERS_START(4, 6) + Z_PARAM_ZVAL(zv_cas) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "zSz|ll" */ + ZEND_PARSE_PARAMETERS_START(3, 5) + Z_PARAM_ZVAL(zv_cas) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + MEMC_CHECK_KEY(intern, key); + + cas = s_zval_to_uint64(zv_cas); + + payload = s_zval_to_payload(intern, value, &flags); + if (payload == NULL) { + intern->rescode = MEMC_RES_PAYLOAD_FAILURE; + RETURN_FALSE; + } + + if (by_key) { + status = memcached_cas_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags, cas); + } else { + status = memcached_cas(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags, cas); + } + + zend_string_release(payload); + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Memcached::cas(double cas_token, string key, mixed value [, int expiration ]) + Sets the value for the given key, failing if the cas_token doesn't match the one in memcache */ +PHP_METHOD(Memcached, cas) +{ + php_memc_cas_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Memcached::casByKey(double cas_token, string server_key, string key, mixed value [, int expiration ]) + Sets the value for the given key on the server identified by the server_key, failing if the cas_token doesn't match the one in memcache */ +PHP_METHOD(Memcached, casByKey) +{ + php_memc_cas_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ Memcached::delete(string key [, int time ]) + Deletes the given key */ +PHP_METHOD(Memcached, delete) +{ + php_memc_delete_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Memcached::deleteMulti(array keys [, int time ]) + Deletes the given keys */ +PHP_METHOD(Memcached, deleteMulti) +{ + php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ Memcached::deleteByKey(string server_key, string key [, int time ]) + Deletes the given key from the server identified by the server key */ +PHP_METHOD(Memcached, deleteByKey) +{ + php_memc_delete_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ Memcached::deleteMultiByKey(array keys [, int time ]) + Deletes the given key from the server identified by the server key */ +PHP_METHOD(Memcached, deleteMultiByKey) +{ + php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ -- php_memc_delete_impl */ +static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) +{ + zend_string *key, *server_key; + zend_long expiration = 0; + memcached_return status; + MEMC_METHOD_INIT_VARS; + + if (by_key) { + /* "SS|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "S|l" */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + server_key = key; + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + MEMC_CHECK_KEY(intern, key); + + if (by_key) { + status = memcached_delete_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), + ZSTR_LEN(key), expiration); + } else { + status = memcached_delete(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), expiration); + } + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ -- php_memc_deleteMulti_impl */ +static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) +{ + zval *entries, *zv, ret; + zend_string *server_key = NULL; + zend_long expiration = 0; + zend_string *entry; + + memcached_return status; + MEMC_METHOD_INIT_VARS; + + if (by_key) { + /* "Sa/|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY_EX(entries, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "a/|l" */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ARRAY_EX(entries, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + array_init(return_value); + ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P(entries), zv) { + entry = zval_get_string(zv); + + if (ZSTR_LEN(entry) == 0) { + zend_string_release(entry); + continue; + } + + if (by_key) { + status = memcached_delete_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(entry), ZSTR_LEN(entry), expiration); + } else { + status = memcached_delete_by_key(intern->memc, ZSTR_VAL(entry), ZSTR_LEN(entry), ZSTR_VAL(entry), ZSTR_LEN(entry), expiration); + } + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + ZVAL_LONG(&ret, status); + } else { + ZVAL_TRUE(&ret); + } + zend_symtable_update(Z_ARRVAL_P(return_value), entry, &ret); + zend_string_release(entry); + } ZEND_HASH_FOREACH_END(); + + return; +} +/* }}} */ + +/* {{{ -- php_memc_incdec_impl */ +static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, zend_bool incr) +{ + zend_string *key, *server_key = NULL; + zend_long offset = 1; + zend_long expiry = 0; + zend_long initial = 0; + uint64_t value = UINT64_MAX; + memcached_return status; + int n_args = ZEND_NUM_ARGS(); + + MEMC_METHOD_INIT_VARS; + + if (!by_key) { + /* "S|lll" */ + ZEND_PARSE_PARAMETERS_START(1, 4) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(offset) + Z_PARAM_LONG(initial) + Z_PARAM_LONG(expiry) + ZEND_PARSE_PARAMETERS_END(); + } else { + /* "SS|lll" */ + ZEND_PARSE_PARAMETERS_START(2, 5) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(offset) + Z_PARAM_LONG(initial) + Z_PARAM_LONG(expiry) + ZEND_PARSE_PARAMETERS_END(); + } + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + MEMC_CHECK_KEY(intern, key); + + if (offset < 0) { + php_error_docref(NULL, E_WARNING, "offset cannot be a negative value"); + RETURN_FALSE; + } + + if ((!by_key && n_args < 3) || (by_key && n_args < 4)) { + if (by_key) { + if (incr) { + status = memcached_increment_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); + } else { + status = memcached_decrement_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); + } + } else { + /* The libmemcached API has a quirk that memcached_increment() takes only a 32-bit + * offset, but memcached_increment_by_key() and all other increment and decrement + * functions take a 64-bit offset. The memcached protocol allows increment/decrement + * greater than UINT_MAX, so we just work around memcached_increment() here. + */ + if (incr) { + status = memcached_increment_by_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); + } else { + status = memcached_decrement_by_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); + } + } + + } else { + zend_long retries = memc_user_data->store_retry_count; + +retry_inc_dec: + if (!memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { + php_error_docref(NULL, E_WARNING, "Initial value is only supported with binary protocol"); + RETURN_FALSE; + } + if (by_key) { + if (incr) { + status = memcached_increment_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); + } else { + status = memcached_decrement_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); + } + } else { + if (incr) { + status = memcached_increment_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); + } else { + status = memcached_decrement_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); + } + } + if (s_should_retry_write(intern, status) && retries-- > 0) { + goto retry_inc_dec; + } + } + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + if (value == UINT64_MAX) { + RETURN_FALSE; + } + + RETURN_LONG((long)value); +} +/* }}} */ + +/* {{{ Memcached::increment(string key [, int delta [, initial_value [, expiry time ] ] ]) + Increments the value for the given key by delta, defaulting to 1 */ +PHP_METHOD(Memcached, increment) +{ + php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1); +} +/* }}} */ + +/* {{{ Memcached::decrement(string key [, int delta [, initial_value [, expiry time ] ] ]) + Decrements the value for the given key by delta, defaulting to 1 */ +PHP_METHOD(Memcached, decrement) +{ + php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0); +} +/* }}} */ + +/* {{{ Memcached::decrementByKey(string server_key, string key [, int delta [, initial_value [, expiry time ] ] ]) + Decrements by server the value for the given key by delta, defaulting to 1 */ +PHP_METHOD(Memcached, decrementByKey) +{ + php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0); +} +/* }}} */ + +/* {{{ Memcached::increment(string server_key, string key [, int delta [, initial_value [, expiry time ] ] ]) + Increments by server the value for the given key by delta, defaulting to 1 */ +PHP_METHOD(Memcached, incrementByKey) +{ + php_memc_incdec_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 1); +} +/* }}} */ + +/* {{{ Memcached::addServer(string hostname, int port [, int weight ]) + Adds the given memcache server to the list */ +PHP_METHOD(Memcached, addServer) +{ + zend_string *host; + zend_long port, weight = 0; + memcached_return status; + MEMC_METHOD_INIT_VARS; + + /* "Sa/|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(host) + Z_PARAM_LONG(port) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(weight) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + status = memcached_server_add_with_weight(intern->memc, ZSTR_VAL(host), port, weight); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Memcached::addServers(array servers) + Adds the given memcache servers to the server list */ +PHP_METHOD(Memcached, addServers) +{ + zval *servers; + zval *entry; + zval *z_host, *z_port, *z_weight = NULL; + HashPosition pos; + int entry_size, i = 0; + memcached_server_st *list = NULL; + memcached_return status; + MEMC_METHOD_INIT_VARS; + + /* "a/" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_EX(servers, 0, 1) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P(servers), entry) { + if (Z_TYPE_P(entry) != IS_ARRAY) { + php_error_docref(NULL, E_WARNING, "server list entry #%d is not an array", i+1); + i++; + continue; + } + + entry_size = zend_hash_num_elements(Z_ARRVAL_P(entry)); + + if (entry_size > 1) { + zend_string *host; + zend_long port; + uint32_t weight; + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos); + + /* Check that we have a host */ + if ((z_host = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) == NULL) { + php_error_docref(NULL, E_WARNING, "could not get server host for entry #%d", i+1); + i++; + continue; + } + + /* Check that we have a port */ + if (zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos) == FAILURE || + (z_port = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) == NULL) { + php_error_docref(NULL, E_WARNING, "could not get server port for entry #%d", i+1); + i++; + continue; + } + + host = zval_get_string(z_host); + port = zval_get_long(z_port); + + weight = 0; + if (entry_size > 2) { + /* Try to get weight */ + if (zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos) == FAILURE || + (z_weight = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) == NULL) { + php_error_docref(NULL, E_WARNING, "could not get server weight for entry #%d", i+1); + } + + weight = zval_get_long(z_weight); + } + + list = memcached_server_list_append_with_weight(list, ZSTR_VAL(host), port, weight, &status); + + zend_string_release(host); + + if (s_memc_status_handle_result_code(intern, status) == SUCCESS) { + i++; + continue; + } + } + i++; + /* catch-all for all errors */ + php_error_docref(NULL, E_WARNING, "could not add entry #%d to the server list", i + 1); + } ZEND_HASH_FOREACH_END(); + + status = memcached_server_push(intern->memc, list); + memcached_server_list_free(list); + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Memcached::getServerList() + Returns the list of the memcache servers in use */ +PHP_METHOD(Memcached, getServerList) +{ + memcached_server_function callbacks[1]; + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + callbacks[0] = s_server_cursor_list_servers_cb; + array_init(return_value); + memcached_server_cursor(intern->memc, callbacks, return_value, 1); +} +/* }}} */ + +/* {{{ Memcached::getServerByKey(string server_key) + Returns the server identified by the given server key */ +PHP_METHOD(Memcached, getServerByKey) +{ + zend_string *server_key; + php_memcached_instance_st server_instance; + memcached_return error; + MEMC_METHOD_INIT_VARS; + + /* "S" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(server_key) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + server_instance = memcached_server_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), &error); + if (server_instance == NULL) { + s_memc_status_handle_result_code(intern, error); + RETURN_FALSE; + } + + array_init(return_value); + add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance)); + add_assoc_long(return_value, "port", memcached_server_port(server_instance)); + add_assoc_long(return_value, "weight", 0); +} +/* }}} */ + +/* {{{ Memcached::resetServerList() + Reset the server list in use */ +PHP_METHOD(Memcached, resetServerList) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + memcached_servers_reset(intern->memc); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Memcached::quit() + Close any open connections */ +PHP_METHOD(Memcached, quit) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + memcached_quit(intern->memc); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Memcached::flushBuffers() + Flush and senf buffered commands */ +PHP_METHOD(Memcached, flushBuffers) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + RETURN_BOOL(memcached_flush_buffers(intern->memc) == MEMCACHED_SUCCESS); +} +/* }}} */ + +/* {{{ Memcached::getLastErrorMessage() + Returns the last error message that occurred */ +PHP_METHOD(Memcached, getLastErrorMessage) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + RETURN_STRING(memcached_last_error_message(intern->memc)); +} +/* }}} */ + +/* {{{ Memcached::getLastErrorCode() + Returns the last error code that occurred */ +PHP_METHOD(Memcached, getLastErrorCode) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + RETURN_LONG(memcached_last_error(intern->memc)); +} +/* }}} */ + +/* {{{ Memcached::getLastErrorErrno() + Returns the last error errno that occurred */ +PHP_METHOD(Memcached, getLastErrorErrno) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + RETURN_LONG(memcached_last_error_errno(intern->memc)); +} +/* }}} */ + +/* {{{ Memcached::getLastDisconnectedServer() + Returns the last disconnected server + Was added in 0.34 according to libmemcached's Changelog */ +PHP_METHOD(Memcached, getLastDisconnectedServer) +{ + php_memcached_instance_st server_instance; + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + server_instance = memcached_server_get_last_disconnect(intern->memc); + if (server_instance == NULL) { + RETURN_FALSE; + } + + array_init(return_value); + add_assoc_string(return_value, "host", (char*) memcached_server_name(server_instance)); + add_assoc_long(return_value, "port", memcached_server_port(server_instance)); +} +/* }}} */ + + + +static +zend_bool s_long_value(const char *str, zend_long *value) +{ + char *end = (char *) str; + + errno = 0; + *value = strtol(str, &end, 10); + + if (errno || str == end || *end != '\0') { + return 0; + } + return 1; +} + +static +zend_bool s_double_value(const char *str, double *value) +{ + char *end = (char *) str; + + errno = 0; + *value = strtod(str, &end); + + if (errno || str == end || *end != '\0') { + return 0; + } + return 1; +} + +static +memcached_return s_stat_execute_cb (php_memcached_instance_st instance, const char *key, size_t key_length, const char *value, size_t value_length, void *context) +{ + zend_string *server_key; + zend_long long_val; + double d_val; + char *buffer; + + zval *return_value = (zval *) context; + zval *server_values; + + server_key = strpprintf(0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance)); + server_values = zend_hash_find(Z_ARRVAL_P(return_value), server_key); + + if (!server_values) { + zval zv; + array_init(&zv); + + server_values = zend_hash_add(Z_ARRVAL_P(return_value), server_key, &zv); + } + + spprintf (&buffer, 0, "%.*s", (int)value_length, value); + + /* Check type */ + if (s_long_value (buffer, &long_val)) { + add_assoc_long(server_values, key, long_val); + } + else if (s_double_value (buffer, &d_val)) { + add_assoc_double(server_values, key, d_val); + } + else { + add_assoc_stringl_ex(server_values, key, key_length, (char*)value, value_length); + } + efree (buffer); + zend_string_release(server_key); + + return MEMCACHED_SUCCESS; +} + +/* {{{ Memcached::getStats() + Returns statistics for the memcache servers */ +PHP_METHOD(Memcached, getStats) +{ + memcached_return status; + char *args = NULL; + zend_string *args_string = NULL; + uint64_t orig_no_block, orig_protocol; + MEMC_METHOD_INIT_VARS; + + /* "|S!" */ + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_STR_EX(args_string, 1, 0) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + + if (args_string) + args = ZSTR_VAL(args_string); + + /* stats hangs in nonblocking mode, turn off during the call. Only change the + * value if needed, because libmemcached reconnects for this behavior_set. */ + orig_no_block = memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK); + orig_protocol = memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL); + if (orig_no_block && orig_protocol) + memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0); + + array_init(return_value); + status = memcached_stat_execute(intern->memc, args, s_stat_execute_cb, return_value); + + if (orig_no_block && orig_protocol) + memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK, orig_no_block); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + zval_ptr_dtor(return_value); + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Memcached::getVersion() + Returns the version of each memcached server in the pool */ +PHP_METHOD(Memcached, getVersion) +{ + memcached_return status; + memcached_server_function callbacks[1]; + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + status = memcached_version(intern->memc); + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + callbacks[0] = s_server_cursor_version_cb; + + array_init(return_value); + status = memcached_server_cursor(intern->memc, callbacks, return_value, 1); + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + zval_dtor(return_value); + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Memcached::getAllKeys() + Returns the keys stored on all the servers */ +static +memcached_return s_dump_keys_cb(const memcached_st *ptr, const char *key, size_t key_length, void *in_context) +{ + zval *return_value = (zval*) in_context; + add_next_index_stringl(return_value, key, key_length); + + return MEMCACHED_SUCCESS; +} + +PHP_METHOD(Memcached, getAllKeys) +{ + memcached_return rc; + memcached_dump_func callback[1]; + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + callback[0] = s_dump_keys_cb; + MEMC_METHOD_FETCH_OBJECT; + + array_init(return_value); + + rc = memcached_dump(intern->memc, callback, return_value, 1); + + /* Ignore two errors. libmemcached has a hardcoded loop of 200 slab + * classes that matches memcached < 1.4.24, at which version the server + * has only 63 slabs and throws an error when requesting the 64th slab. + * + * In multi-server some non-deterministic number of elements will be dropped. + */ + if (rc != MEMCACHED_CLIENT_ERROR && rc != MEMCACHED_SERVER_ERROR + && s_memc_status_handle_result_code(intern, rc) == FAILURE) { + zval_dtor(return_value); + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Memcached::flush([ int delay ]) + Flushes the data on all the servers */ +static PHP_METHOD(Memcached, flush) +{ + zend_long delay = 0; + memcached_return status; + MEMC_METHOD_INIT_VARS; + + /* "|l" */ + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(delay) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + + status = memcached_flush(intern->memc, delay); + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Memcached::getOption(int option) + Returns the value for the given option constant */ +static PHP_METHOD(Memcached, getOption) +{ + zend_long option; + uint64_t result; + memcached_behavior flag; + MEMC_METHOD_INIT_VARS; + + /* "l" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(option) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + + switch (option) { + case MEMC_OPT_COMPRESSION_TYPE: + RETURN_LONG(memc_user_data->compression_type); + + case MEMC_OPT_COMPRESSION: + RETURN_BOOL(memc_user_data->compression_enabled); + + case MEMC_OPT_PREFIX_KEY: + { + memcached_return retval; + char *result; + + result = memcached_callback_get(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval); + if (retval == MEMCACHED_SUCCESS && result) { + RETURN_STRING(result); + } else { + RETURN_EMPTY_STRING(); + } + } + + case MEMC_OPT_SERIALIZER: + RETURN_LONG((long)memc_user_data->serializer); + break; + + case MEMC_OPT_USER_FLAGS: + RETURN_LONG(memc_user_data->set_udf_flags); + break; + + case MEMC_OPT_STORE_RETRY_COUNT: + RETURN_LONG((long)memc_user_data->store_retry_count); + break; + + case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE: + case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE: + if (memcached_server_count(intern->memc) == 0) { + php_error_docref(NULL, E_WARNING, "no servers defined"); + return; + } + + default: + /* + * Assume that it's a libmemcached behavior option. + */ + flag = (memcached_behavior) option; + result = memcached_behavior_get(intern->memc, flag); + RETURN_LONG((long)result); + } +} +/* }}} */ + +static +int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) +{ + zend_long lval; + memcached_return rc = MEMCACHED_FAILURE; + memcached_behavior flag; + php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); + + switch (option) { + case MEMC_OPT_COMPRESSION: + memc_user_data->compression_enabled = zval_get_long(value) ? 1 : 0; + break; + + case MEMC_OPT_COMPRESSION_TYPE: + lval = zval_get_long(value); + if (lval == COMPRESSION_TYPE_FASTLZ || + lval == COMPRESSION_TYPE_ZLIB) { + memc_user_data->compression_type = lval; + } else { + /* invalid compression type */ + intern->rescode = MEMCACHED_INVALID_ARGUMENTS; + return 0; + } + break; + + case MEMC_OPT_PREFIX_KEY: + { + zend_string *str; + char *key; + str = zval_get_string(value); + if (ZSTR_LEN(str) == 0) { + key = NULL; + } else { + key = ZSTR_VAL(str); + } + if (memcached_callback_set(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, key) == MEMCACHED_BAD_KEY_PROVIDED) { + zend_string_release(str); + intern->rescode = MEMCACHED_INVALID_ARGUMENTS; + php_error_docref(NULL, E_WARNING, "bad key provided"); + return 0; + } + zend_string_release(str); + } + break; + + case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED: + flag = (memcached_behavior) option; + + lval = zval_get_long(value); + rc = memcached_behavior_set(intern->memc, flag, (uint64_t)lval); + + if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { + php_error_docref(NULL, E_WARNING, "error setting memcached option: %s", memcached_strerror (intern->memc, rc)); + return 0; + } + + /* + * This is necessary because libmemcached does not reset hash/distribution + * options on false case, like it does for MEMCACHED_BEHAVIOR_KETAMA + * (non-weighted) case. We have to clean up ourselves. + */ + if (!lval) { + (void)memcached_behavior_set_key_hash(intern->memc, MEMCACHED_HASH_DEFAULT); + (void)memcached_behavior_set_distribution_hash(intern->memc, MEMCACHED_HASH_DEFAULT); + (void)memcached_behavior_set_distribution(intern->memc, MEMCACHED_DISTRIBUTION_MODULA); + } + break; + + case MEMC_OPT_SERIALIZER: + { + lval = zval_get_long(value); + /* igbinary serializer */ +#ifdef HAVE_MEMCACHED_IGBINARY + if (lval == SERIALIZER_IGBINARY) { + memc_user_data->serializer = SERIALIZER_IGBINARY; + } else +#endif +#ifdef HAVE_JSON_API + if (lval == SERIALIZER_JSON) { + memc_user_data->serializer = SERIALIZER_JSON; + } else if (lval == SERIALIZER_JSON_ARRAY) { + memc_user_data->serializer = SERIALIZER_JSON_ARRAY; + } else +#endif + /* msgpack serializer */ +#ifdef HAVE_MEMCACHED_MSGPACK + if (lval == SERIALIZER_MSGPACK) { + memc_user_data->serializer = SERIALIZER_MSGPACK; + } else +#endif + /* php serializer */ + if (lval == SERIALIZER_PHP) { + memc_user_data->serializer = SERIALIZER_PHP; + } else { + memc_user_data->serializer = SERIALIZER_PHP; + intern->rescode = MEMCACHED_INVALID_ARGUMENTS; + php_error_docref(NULL, E_WARNING, "invalid serializer provided"); + return 0; + } + break; + } + + case MEMC_OPT_USER_FLAGS: + lval = zval_get_long(value); + + if (lval < 0) { + memc_user_data->set_udf_flags = -1; + return 1; + } + + if (lval > MEMC_VAL_USER_FLAGS_MAX) { + php_error_docref(NULL, E_WARNING, "MEMC_OPT_USER_FLAGS must be < %u", MEMC_VAL_USER_FLAGS_MAX); + return 0; + } + memc_user_data->set_udf_flags = lval; + break; + + case MEMC_OPT_STORE_RETRY_COUNT: + lval = zval_get_long(value); + memc_user_data->store_retry_count = lval; + break; + + default: + /* + * Assume that it's a libmemcached behavior option. + */ + if (option < 0) { + rc = MEMCACHED_INVALID_ARGUMENTS; + } + else { + flag = (memcached_behavior) option; + lval = zval_get_long(value); + + if (flag < MEMCACHED_BEHAVIOR_MAX) { + rc = memcached_behavior_set(intern->memc, flag, (uint64_t)lval); + } + else { + rc = MEMCACHED_INVALID_ARGUMENTS; + } + } + + if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { + php_error_docref(NULL, E_WARNING, "error setting memcached option: %s", memcached_strerror (intern->memc, rc)); + return 0; + } + break; + } + return 1; +} + +static +uint32_t *s_zval_to_uint32_array (zval *input, size_t *num_elements) +{ + zval *pzval; + uint32_t *retval; + size_t i = 0; + + *num_elements = zend_hash_num_elements(Z_ARRVAL_P(input)); + + if (!*num_elements) { + return NULL; + } + + retval = ecalloc(*num_elements, sizeof(uint32_t)); + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), pzval) { + zend_long value = 0; + + value = zval_get_long(pzval); + if (value < 0) { + php_error_docref(NULL, E_WARNING, "the map must contain positive integers"); + efree (retval); + *num_elements = 0; + return NULL; + } + retval [i] = (uint32_t) value; + i++; + } ZEND_HASH_FOREACH_END(); + return retval; +} + +/* {{{ Memcached::setBucket(array host_map, array forward_map, integer replicas) + Sets the memcached virtual buckets */ + +PHP_METHOD(Memcached, setBucket) +{ + zval *zserver_map; + zval *zforward_map = NULL; + zend_long replicas = 0; + zend_bool retval = 1; + + uint32_t *server_map = NULL, *forward_map = NULL; + size_t server_map_len = 0, forward_map_len = 0; + memcached_return rc; + MEMC_METHOD_INIT_VARS; + + /* "aa!l" */ + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_ARRAY(zserver_map) + Z_PARAM_ARRAY_EX(zforward_map, 1, 0) + Z_PARAM_LONG(replicas) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + + if (zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) == 0) { + php_error_docref(NULL, E_WARNING, "server map cannot be empty"); + RETURN_FALSE; + } + + if (zforward_map && zend_hash_num_elements (Z_ARRVAL_P(zserver_map)) != zend_hash_num_elements (Z_ARRVAL_P(zforward_map))) { + php_error_docref(NULL, E_WARNING, "forward_map length must match the server_map length"); + RETURN_FALSE; + } + + if (replicas < 0) { + php_error_docref(NULL, E_WARNING, "replicas must be larger than zero"); + RETURN_FALSE; + } + + server_map = s_zval_to_uint32_array (zserver_map, &server_map_len); + + if (!server_map) { + RETURN_FALSE; + } + + if (zforward_map) { + forward_map = s_zval_to_uint32_array (zforward_map, &forward_map_len); + + if (!forward_map) { + efree (server_map); + RETURN_FALSE; + } + } + + rc = memcached_bucket_set (intern->memc, server_map, forward_map, (uint32_t) server_map_len, replicas); + + if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { + retval = 0; + } + + efree(server_map); + + if (forward_map) { + efree(forward_map); + } + RETURN_BOOL(retval); +} +/* }}} */ + +/* {{{ Memcached::setOptions(array options) + Sets the value for the given option constant */ +static PHP_METHOD(Memcached, setOptions) +{ + zval *options; + zend_bool ok = 1; + zend_string *key; + ulong key_index; + zval *value; + + MEMC_METHOD_INIT_VARS; + + /* "a" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY(options) + ZEND_PARSE_PARAMETERS_END(); + + + MEMC_METHOD_FETCH_OBJECT; + + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(options), key_index, key, value) { + if (key) { + php_error_docref(NULL, E_WARNING, "invalid configuration option"); + ok = 0; + } else { + if (!php_memc_set_option(intern, (long) key_index, value)) { + ok = 0; + } + } + } ZEND_HASH_FOREACH_END(); + + RETURN_BOOL(ok); +} +/* }}} */ + +/* {{{ Memcached::setOption(int option, mixed value) + Sets the value for the given option constant */ +static PHP_METHOD(Memcached, setOption) +{ + zend_long option; + zval *value; + MEMC_METHOD_INIT_VARS; + + /* "lz/" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(option) + Z_PARAM_ZVAL_EX(value, 0, 1) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + + RETURN_BOOL(php_memc_set_option(intern, option, value)); +} +/* }}} */ + +#ifdef HAVE_MEMCACHED_SASL +/* {{{ Memcached::setSaslAuthData(string user, string pass) + Sets sasl credentials */ +static PHP_METHOD(Memcached, setSaslAuthData) +{ + MEMC_METHOD_INIT_VARS; + memcached_return status; + zend_string *user, *pass; + + /* "SS/" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR(user) + Z_PARAM_STR(pass) + ZEND_PARSE_PARAMETERS_END(); + + if (!php_memc_init_sasl_if_needed()) { + RETURN_FALSE; + } + + MEMC_METHOD_FETCH_OBJECT; + + if (!memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { + php_error_docref(NULL, E_WARNING, "SASL is only supported with binary protocol"); + RETURN_FALSE; + } + memc_user_data->has_sasl_data = 1; + status = memcached_set_sasl_auth_data(intern->memc, ZSTR_VAL(user), ZSTR_VAL(pass)); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ +#endif /* HAVE_MEMCACHED_SASL */ + +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY +/* {{{ Memcached::setEncodingKey(string key) + Sets AES encryption key (libmemcached 1.0.6 and higher) */ +static PHP_METHOD(Memcached, setEncodingKey) +{ + MEMC_METHOD_INIT_VARS; + memcached_return status; + zend_string *key; + + /* "S" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(key) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + + // libmemcached < 1.0.18 cannot handle a change of encoding key. Warn about this and return false. +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + if (memc_user_data->encoding_enabled) { + php_error_docref(NULL, E_WARNING, "libmemcached versions less than 1.0.18 cannot change encoding key"); + RETURN_FALSE; + } +#endif + + status = memcached_set_encoding_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key)); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + memc_user_data->encoding_enabled = 1; + RETURN_TRUE; +} +/* }}} */ +#endif /* HAVE_MEMCACHED_SET_ENCODING_KEY */ + +/* {{{ Memcached::getResultCode() + Returns the result code from the last operation */ +static PHP_METHOD(Memcached, getResultCode) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + RETURN_LONG(intern->rescode); +} +/* }}} */ + +/* {{{ Memcached::getResultMessage() + Returns the result message from the last operation */ +static PHP_METHOD(Memcached, getResultMessage) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + switch (intern->rescode) { + case MEMC_RES_PAYLOAD_FAILURE: + RETURN_STRING("PAYLOAD FAILURE"); + break; + + case MEMCACHED_ERRNO: + case MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE: + case MEMCACHED_UNKNOWN_READ_FAILURE: + if (intern->memc_errno) { + zend_string *str = strpprintf(0, "%s: %s", + memcached_strerror(intern->memc, (memcached_return)intern->rescode), strerror(intern->memc_errno)); + RETURN_STR(str); + } + /* Fall through */ + default: + RETURN_STRING(memcached_strerror(intern->memc, (memcached_return)intern->rescode)); + break; + } + +} +/* }}} */ + +/* {{{ Memcached::isPersistent() + Returns the true if instance uses a persistent connection */ +static PHP_METHOD(Memcached, isPersistent) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + RETURN_BOOL(memc_user_data->is_persistent); +} +/* }}} */ + +/* {{{ Memcached::isPristine() + Returns the true if instance is recently created */ +static PHP_METHOD(Memcached, isPristine) +{ + MEMC_METHOD_INIT_VARS; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + MEMC_METHOD_FETCH_OBJECT; + + RETURN_BOOL(intern->is_pristine); +} +/* }}} */ + +/**************************************** + Internal support code +****************************************/ + +/* {{{ constructor/destructor */ +static +void php_memc_destroy(memcached_st *memc, php_memc_user_data_t *memc_user_data) +{ +#ifdef HAVE_MEMCACHED_SASL + if (memc_user_data->has_sasl_data) { + memcached_destroy_sasl_auth_data(memc); + } +#endif + + memcached_free(memc); + pefree(memc_user_data, memc_user_data->is_persistent); +} + +static +void php_memc_object_free_storage(zend_object *object) +{ + php_memc_object_t *intern = php_memc_fetch_object(object); + + if (intern->memc) { + php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); + + if (!memc_user_data->is_persistent) { + php_memc_destroy(intern->memc, memc_user_data); + } + } + + intern->memc = NULL; + zend_object_std_dtor(&intern->zo); +} + +static +zend_object *php_memc_object_new(zend_class_entry *ce) +{ + php_memc_object_t *intern = ecalloc(1, sizeof(php_memc_object_t) + zend_object_properties_size(ce)); + + zend_object_std_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); + + intern->zo.handlers = &memcached_object_handlers; + return &intern->zo; +} + +#ifdef HAVE_MEMCACHED_PROTOCOL +static +void php_memc_server_free_storage(zend_object *object) +{ + php_memc_server_t *intern = php_memc_server_fetch_object(object); + zend_object_std_dtor(&intern->zo); +} + +zend_object *php_memc_server_new(zend_class_entry *ce) +{ + php_memc_server_t *intern; + + intern = ecalloc(1, sizeof(php_memc_server_t) + zend_object_properties_size(ce)); + + zend_object_std_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); + + intern->zo.handlers = &memcached_server_object_handlers; + + return &intern->zo; +} +#endif + +ZEND_RSRC_DTOR_FUNC(php_memc_dtor) +{ + if (res->ptr) { + memcached_st *memc = (memcached_st *) res->ptr; + php_memc_destroy(memc, memcached_get_user_data(memc)); + res->ptr = NULL; + } +} + +/* }}} */ + +/* {{{ internal API functions */ +static +memcached_return s_server_cursor_list_servers_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context) +{ + zval array; + zval *return_value = (zval *) in_context; + + array_init(&array); + add_assoc_string(&array, "host", (char*)memcached_server_name(instance)); + add_assoc_long(&array, "port", memcached_server_port(instance)); + add_assoc_string(&array, "type", (char*)memcached_server_type(instance)); + /* + * API does not allow to get at this field. + add_assoc_long(array, "weight", instance->weight); + */ + + add_next_index_zval(return_value, &array); + return MEMCACHED_SUCCESS; +} + +static +memcached_return s_server_cursor_version_cb(const memcached_st *ptr, php_memcached_instance_st instance, void *in_context) +{ + zend_string *address, *version; + zval rv, *return_value = (zval *)in_context; + +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000009 + version = strpprintf(0, "%d.%d.%d", + memcached_server_major_version(instance), + memcached_server_minor_version(instance), + memcached_server_micro_version(instance)); +#else + version = strpprintf(0, "%d.%d.%d", + instance->major_version, + instance->minor_version, + instance->micro_version); +#endif + + address = strpprintf(0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance)); + + ZVAL_STR(&rv, version); + zend_hash_add(Z_ARRVAL_P(return_value), address, &rv); + + zend_string_release(address); + + return MEMCACHED_SUCCESS; +} + + +static +zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32_t flags) +{ + zend_string *buffer; + + uint32_t stored_length; + unsigned long length; + zend_bool decompress_status = 0; + zend_bool is_fastlz = 0, is_zlib = 0; + + if (payload_len < sizeof (uint32_t)) { + return NULL; + } + + is_fastlz = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_FASTLZ); + is_zlib = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_ZLIB); + + if (!is_fastlz && !is_zlib) { + php_error_docref(NULL, E_WARNING, "could not decompress value: unrecognised compression type"); + return NULL; + } + + memcpy(&stored_length, payload, sizeof (uint32_t)); + + payload += sizeof (uint32_t); + payload_len -= sizeof (uint32_t); + + buffer = zend_string_alloc (stored_length, 0); + + if (is_fastlz) { + decompress_status = ((length = fastlz_decompress(payload, payload_len, &buffer->val, buffer->len)) > 0); + } + else if (is_zlib) { + decompress_status = (uncompress((Bytef *) buffer->val, &buffer->len, (Bytef *)payload, payload_len) == Z_OK); + } + + ZSTR_VAL(buffer)[stored_length] = '\0'; + + if (!decompress_status) { + php_error_docref(NULL, E_WARNING, "could not decompress value"); + zend_string_release (buffer); + return NULL; + } + + zend_string_forget_hash_val(buffer); + return buffer; +} + +static +zend_bool s_unserialize_value (memcached_st *memc, int val_type, zend_string *payload, zval *return_value) +{ + switch (val_type) { + case MEMC_VAL_IS_SERIALIZED: + { + php_unserialize_data_t var_hash; + const unsigned char *p, *max; + + p = (const unsigned char *) ZSTR_VAL(payload); + max = p + ZSTR_LEN(payload); + + PHP_VAR_UNSERIALIZE_INIT(var_hash); + if (!php_var_unserialize(return_value, &p, max, &var_hash)) { + zval_ptr_dtor(return_value); + ZVAL_FALSE(return_value); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + php_error_docref(NULL, E_WARNING, "could not unserialize value"); + return 0; + } + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + } + break; + + case MEMC_VAL_IS_IGBINARY: +#ifdef HAVE_MEMCACHED_IGBINARY + if (igbinary_unserialize((uint8_t *) ZSTR_VAL(payload), ZSTR_LEN(payload), return_value)) { + ZVAL_FALSE(return_value); + php_error_docref(NULL, E_WARNING, "could not unserialize value with igbinary"); + return 0; + } +#else + ZVAL_FALSE(return_value); + php_error_docref(NULL, E_WARNING, "could not unserialize value, no igbinary support"); + return 0; +#endif + break; + + case MEMC_VAL_IS_JSON: +#ifdef HAVE_JSON_API + { + php_memc_user_data_t *memc_user_data = memcached_get_user_data(memc); + php_json_decode(return_value, ZSTR_VAL(payload), ZSTR_LEN(payload), (memc_user_data->serializer == SERIALIZER_JSON_ARRAY), PHP_JSON_PARSER_DEFAULT_DEPTH); + } +#else + ZVAL_FALSE(return_value); + php_error_docref(NULL, E_WARNING, "could not unserialize value, no json support"); + return 0; +#endif + break; + + case MEMC_VAL_IS_MSGPACK: +#ifdef HAVE_MEMCACHED_MSGPACK + php_msgpack_unserialize(return_value, ZSTR_VAL(payload), ZSTR_LEN(payload)); +#else + ZVAL_FALSE(return_value); + php_error_docref(NULL, E_WARNING, "could not unserialize value, no msgpack support"); + return 0; +#endif + break; + } + return 1; +} + +static +zend_bool s_memcached_result_to_zval(memcached_st *memc, memcached_result_st *result, zval *return_value) +{ + zend_string *data; + const char *payload; + size_t payload_len; + uint32_t flags; + zend_bool retval = 1; + + payload = memcached_result_value(result); + payload_len = memcached_result_length(result); + flags = memcached_result_flags(result); + + if (!payload && payload_len > 0) { + php_error_docref(NULL, E_WARNING, "Could not handle non-existing value of length %zu", payload_len); + return 0; + } + + if (MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSED)) { + data = s_decompress_value (payload, payload_len, flags); + if (!data) { + return 0; + } + } else { + data = zend_string_init(payload, payload_len, 0); + } + + switch (MEMC_VAL_GET_TYPE(flags)) { + + case MEMC_VAL_IS_STRING: + ZVAL_STR_COPY(return_value, data); + break; + + case MEMC_VAL_IS_LONG: + ZVAL_LONG(return_value, strtol(ZSTR_VAL(data), NULL, 10)); + break; + + case MEMC_VAL_IS_DOUBLE: + { + if (zend_string_equals_literal(data, "Infinity")) { + ZVAL_DOUBLE(return_value, php_get_inf()); + } + else if (zend_string_equals_literal(data, "-Infinity")) { + ZVAL_DOUBLE(return_value, -php_get_inf()); + } + else if (zend_string_equals_literal(data, "NaN")) { + ZVAL_DOUBLE(return_value, php_get_nan()); + } + else { + ZVAL_DOUBLE(return_value, zend_strtod(ZSTR_VAL(data), NULL)); + } + } + break; + + case MEMC_VAL_IS_BOOL: + ZVAL_BOOL(return_value, payload_len > 0 && ZSTR_VAL(data)[0] == '1'); + break; + + case MEMC_VAL_IS_SERIALIZED: + case MEMC_VAL_IS_IGBINARY: + case MEMC_VAL_IS_JSON: + case MEMC_VAL_IS_MSGPACK: + retval = s_unserialize_value (memc, MEMC_VAL_GET_TYPE(flags), data, return_value); + break; + + default: + php_error_docref(NULL, E_WARNING, "unknown payload type"); + retval = 0; + break; + } + zend_string_release(data); + + return retval; +} + + +PHP_MEMCACHED_API +zend_class_entry *php_memc_get_ce(void) +{ + return memcached_ce; +} + +PHP_MEMCACHED_API +zend_class_entry *php_memc_get_exception(void) +{ + return memcached_exception_ce; +} + +PHP_MEMCACHED_API +zend_class_entry *php_memc_get_exception_base(int root) +{ +#ifdef HAVE_SPL + if (!root) { + if (!spl_ce_RuntimeException) { + zend_class_entry *pce; + zval *pce_z; + + if ((pce_z = zend_hash_str_find(CG(class_table), + "runtimeexception", + sizeof("RuntimeException") - 1)) != NULL) { + pce = Z_CE_P(pce_z); + spl_ce_RuntimeException = pce; + return pce; + } + } else { + return spl_ce_RuntimeException; + } + } +#endif + return zend_exception_get_default(); +} + + +#ifdef HAVE_MEMCACHED_PROTOCOL + +static +void s_destroy_cb (zend_fcall_info *fci) +{ + if (fci->size > 0) { + zval_ptr_dtor(&fci->function_name); + if (fci->object) { + OBJ_RELEASE(fci->object); + } + } +} + +static +PHP_METHOD(MemcachedServer, run) +{ + int i; + zend_bool rc; + zend_string *address; + + php_memc_server_t *intern; + intern = Z_MEMC_SERVER_P(getThis()); + + /* "S" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(address) + ZEND_PARSE_PARAMETERS_END(); + + rc = php_memc_proto_handler_run(intern->handler, address); + + for (i = MEMC_SERVER_ON_MIN + 1; i < MEMC_SERVER_ON_MAX; i++) { + s_destroy_cb(&MEMC_SERVER_G(callbacks) [i].fci); + } + + RETURN_BOOL(rc); +} + +static +PHP_METHOD(MemcachedServer, on) +{ + zend_long event; + zend_fcall_info fci; + zend_fcall_info_cache fci_cache; + zend_bool rc = 0; + + /* "lf!" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(event) + Z_PARAM_FUNC_EX(fci, fci_cache, 1, 0) + ZEND_PARSE_PARAMETERS_END(); + + if (event <= MEMC_SERVER_ON_MIN || event >= MEMC_SERVER_ON_MAX) { + RETURN_FALSE; + } + + if (fci.size > 0) { + s_destroy_cb (&MEMC_SERVER_G(callbacks) [event].fci); + + MEMC_SERVER_G(callbacks) [event].fci = fci; + MEMC_SERVER_G(callbacks) [event].fci_cache = fci_cache; + + Z_TRY_ADDREF(fci.function_name); + if (fci.object) { + GC_ADDREF(fci.object); + } + } + RETURN_BOOL(rc); +} + +#endif + +/* {{{ methods arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0) + ZEND_ARG_INFO(0, persistent_id) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getResultCode, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getResultMessage, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_get, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, cache_cb) + ZEND_ARG_INFO(0, get_flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_getByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, cache_cb) + ZEND_ARG_INFO(0, get_flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_getMulti, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, keys, 0) + ZEND_ARG_INFO(0, get_flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_getMultiByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_ARRAY_INFO(0, keys, 0) + ZEND_ARG_INFO(0, get_flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_getDelayed, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, keys, 0) + ZEND_ARG_INFO(0, with_cas) + ZEND_ARG_INFO(0, value_cb) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_getDelayedByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_ARRAY_INFO(0, keys, 0) + ZEND_ARG_INFO(0, with_cas) + ZEND_ARG_INFO(0, value_cb) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_fetch, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_fetchAll, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_set, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_setByKey, 0, 0, 3) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_touch, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_touchByKey, 0, 0, 3) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_setMulti, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, items, 0) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_setMultiByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_ARRAY_INFO(0, items, 0) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_add, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_addByKey, 0, 0, 3) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_replace, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_replaceByKey, 0, 0, 3) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_appendByKey, 0, 0, 3) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_prepend, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_prependByKey, 0, 0, 3) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_cas, 0, 0, 3) + ZEND_ARG_INFO(0, cas_token) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_casByKey, 0, 0, 4) + ZEND_ARG_INFO(0, cas_token) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_delete, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, time) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteMulti, 0, 0, 1) + ZEND_ARG_INFO(0, keys) + ZEND_ARG_INFO(0, time) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, time) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteMultiByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, keys) + ZEND_ARG_INFO(0, time) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_increment, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, initial_value) + ZEND_ARG_INFO(0, expiry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_decrement, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, initial_value) + ZEND_ARG_INFO(0, expiry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_incrementByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, initial_value) + ZEND_ARG_INFO(0, expiry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_decrementByKey, 0, 0, 2) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, initial_value) + ZEND_ARG_INFO(0, expiry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_flush, 0, 0, 0) + ZEND_ARG_INFO(0, delay) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_addServer, 0, 0, 2) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, weight) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_getStats, 0, 0, 0) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_addServers, 0) + ZEND_ARG_ARRAY_INFO(0, servers, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getServerList, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_resetServerList, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_quit, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_flushBuffers, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getServerByKey, 0) + ZEND_ARG_INFO(0, server_key) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorMessage, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorCode, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorErrno, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getLastDisconnectedServer, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getOption, 0) + ZEND_ARG_INFO(0, option) +ZEND_END_ARG_INFO() + +#ifdef HAVE_MEMCACHED_SASL +ZEND_BEGIN_ARG_INFO(arginfo_setSaslAuthData, 0) + ZEND_ARG_INFO(0, username) + ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() +#endif + +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY +ZEND_BEGIN_ARG_INFO(arginfo_setEncodingKey, 0) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO(arginfo_setOption, 0) + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_setOptions, 0) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 3) + ZEND_ARG_INFO(0, host_map) + ZEND_ARG_INFO(0, forward_map) + ZEND_ARG_INFO(0, replicas) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getVersion, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_isPersistent, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_isPristine, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_getAllKeys, 0) +ZEND_END_ARG_INFO() +/* }}} */ + +/* {{{ memcached_class_methods */ +#define MEMC_ME(name, args) PHP_ME(Memcached, name, args, ZEND_ACC_PUBLIC) +static zend_function_entry memcached_class_methods[] = { + MEMC_ME(__construct, arginfo___construct) + + MEMC_ME(getResultCode, arginfo_getResultCode) + MEMC_ME(getResultMessage, arginfo_getResultMessage) + + MEMC_ME(get, arginfo_get) + MEMC_ME(getByKey, arginfo_getByKey) + MEMC_ME(getMulti, arginfo_getMulti) + MEMC_ME(getMultiByKey, arginfo_getMultiByKey) + MEMC_ME(getDelayed, arginfo_getDelayed) + MEMC_ME(getDelayedByKey, arginfo_getDelayedByKey) + MEMC_ME(fetch, arginfo_fetch) + MEMC_ME(fetchAll, arginfo_fetchAll) + + MEMC_ME(set, arginfo_set) + MEMC_ME(setByKey, arginfo_setByKey) + + MEMC_ME(touch, arginfo_touch) + MEMC_ME(touchByKey, arginfo_touchByKey) + + MEMC_ME(setMulti, arginfo_setMulti) + MEMC_ME(setMultiByKey, arginfo_setMultiByKey) + + MEMC_ME(cas, arginfo_cas) + MEMC_ME(casByKey, arginfo_casByKey) + MEMC_ME(add, arginfo_add) + MEMC_ME(addByKey, arginfo_addByKey) + MEMC_ME(append, arginfo_append) + MEMC_ME(appendByKey, arginfo_appendByKey) + MEMC_ME(prepend, arginfo_prepend) + MEMC_ME(prependByKey, arginfo_prependByKey) + MEMC_ME(replace, arginfo_replace) + MEMC_ME(replaceByKey, arginfo_replaceByKey) + MEMC_ME(delete, arginfo_delete) + MEMC_ME(deleteMulti, arginfo_deleteMulti) + MEMC_ME(deleteByKey, arginfo_deleteByKey) + MEMC_ME(deleteMultiByKey, arginfo_deleteMultiByKey) + + MEMC_ME(increment, arginfo_increment) + MEMC_ME(decrement, arginfo_decrement) + MEMC_ME(incrementByKey, arginfo_incrementByKey) + MEMC_ME(decrementByKey, arginfo_decrementByKey) + + MEMC_ME(addServer, arginfo_addServer) + MEMC_ME(addServers, arginfo_addServers) + MEMC_ME(getServerList, arginfo_getServerList) + MEMC_ME(getServerByKey, arginfo_getServerByKey) + MEMC_ME(resetServerList, arginfo_resetServerList) + MEMC_ME(quit, arginfo_quit) + MEMC_ME(flushBuffers, arginfo_flushBuffers) + + MEMC_ME(getLastErrorMessage, arginfo_getLastErrorMessage) + MEMC_ME(getLastErrorCode, arginfo_getLastErrorCode) + MEMC_ME(getLastErrorErrno, arginfo_getLastErrorErrno) + MEMC_ME(getLastDisconnectedServer, arginfo_getLastDisconnectedServer) + + MEMC_ME(getStats, arginfo_getStats) + MEMC_ME(getVersion, arginfo_getVersion) + MEMC_ME(getAllKeys, arginfo_getAllKeys) + + MEMC_ME(flush, arginfo_flush) + + MEMC_ME(getOption, arginfo_getOption) + MEMC_ME(setOption, arginfo_setOption) + MEMC_ME(setOptions, arginfo_setOptions) + MEMC_ME(setBucket, arginfo_setBucket) +#ifdef HAVE_MEMCACHED_SASL + MEMC_ME(setSaslAuthData, arginfo_setSaslAuthData) +#endif +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY + MEMC_ME(setEncodingKey, arginfo_setEncodingKey) +#endif + MEMC_ME(isPersistent, arginfo_isPersistent) + MEMC_ME(isPristine, arginfo_isPristine) + { NULL, NULL, NULL } +}; +#undef MEMC_ME +/* }}} */ + +#ifdef HAVE_MEMCACHED_PROTOCOL +/* {{{ */ +#define MEMC_SE_ME(name, args) PHP_ME(MemcachedServer, name, args, ZEND_ACC_PUBLIC) +static +zend_function_entry memcached_server_class_methods[] = { + MEMC_SE_ME(run, NULL) + MEMC_SE_ME(on, NULL) + { NULL, NULL, NULL } +}; +#undef MEMC_SE_ME +/* }}} */ +#endif + +/* {{{ memcached_module_entry + */ + +#if ZEND_MODULE_API_NO >= 20050922 +static const zend_module_dep memcached_deps[] = { +#ifdef HAVE_MEMCACHED_SESSION + ZEND_MOD_REQUIRED("session") +#endif +#ifdef HAVE_MEMCACHED_IGBINARY + ZEND_MOD_REQUIRED("igbinary") +#endif +#ifdef HAVE_MEMCACHED_MSGPACK + ZEND_MOD_REQUIRED("msgpack") +#endif +#ifdef HAVE_SPL + ZEND_MOD_REQUIRED("spl") +#endif + {NULL, NULL, NULL} +}; +#endif + +static +PHP_GINIT_FUNCTION(php_memcached) +{ +#ifdef HAVE_MEMCACHED_SESSION + + php_memcached_globals->session.lock_enabled = 0; + php_memcached_globals->session.lock_wait_max = 150; + php_memcached_globals->session.lock_wait_min = 150; + php_memcached_globals->session.lock_retries = 200; + php_memcached_globals->session.lock_expiration = 30; + php_memcached_globals->session.binary_protocol_enabled = 1; + php_memcached_globals->session.consistent_hash_enabled = 1; + php_memcached_globals->session.consistent_hash_type = MEMCACHED_BEHAVIOR_KETAMA; + php_memcached_globals->session.consistent_hash_name = NULL; + php_memcached_globals->session.number_of_replicas = 0; + php_memcached_globals->session.server_failure_limit = 1; + php_memcached_globals->session.randomize_replica_read_enabled = 1; + php_memcached_globals->session.remove_failed_servers_enabled = 1; + php_memcached_globals->session.connect_timeout = 1000; + php_memcached_globals->session.prefix = NULL; + php_memcached_globals->session.persistent_enabled = 0; + php_memcached_globals->session.sasl_username = NULL; + php_memcached_globals->session.sasl_password = NULL; + +#endif + php_memcached_globals->memc.serializer_name = NULL; + php_memcached_globals->memc.serializer_type = SERIALIZER_DEFAULT; + php_memcached_globals->memc.compression_name = NULL; + php_memcached_globals->memc.compression_threshold = 2000; + php_memcached_globals->memc.compression_type = COMPRESSION_TYPE_FASTLZ; + php_memcached_globals->memc.compression_factor = 1.30; + php_memcached_globals->memc.store_retry_count = 2; + + php_memcached_globals->memc.sasl_initialised = 0; + php_memcached_globals->no_effect = 0; + + /* Defaults for certain options */ + php_memcached_globals->memc.default_behavior.consistent_hash_enabled = 0; + php_memcached_globals->memc.default_behavior.binary_protocol_enabled = 0; + php_memcached_globals->memc.default_behavior.connect_timeout = 0; +} + +zend_module_entry memcached_module_entry = { + STANDARD_MODULE_HEADER_EX, NULL, + memcached_deps, + "memcached", + NULL, + PHP_MINIT(memcached), + PHP_MSHUTDOWN(memcached), + NULL, + NULL, + PHP_MINFO(memcached), + PHP_MEMCACHED_VERSION, + PHP_MODULE_GLOBALS(php_memcached), + PHP_GINIT(php_memcached), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX +}; +/* }}} */ + + +/* {{{ php_memc_register_constants */ +static void php_memc_register_constants(INIT_FUNC_ARGS) +{ + #define REGISTER_MEMC_CLASS_CONST_LONG(name, value) zend_declare_class_constant_long(php_memc_get_ce() , ZEND_STRS( #name ) - 1, value) + #define REGISTER_MEMC_CLASS_CONST_BOOL(name, value) zend_declare_class_constant_bool(php_memc_get_ce() , ZEND_STRS( #name ) - 1, value) + #define REGISTER_MEMC_CLASS_CONST_NULL(name) zend_declare_class_constant_null(php_memc_get_ce() , ZEND_STRS( #name ) - 1) + + /* + * Class options + */ + REGISTER_MEMC_CLASS_CONST_LONG(LIBMEMCACHED_VERSION_HEX, LIBMEMCACHED_VERSION_HEX); + + REGISTER_MEMC_CLASS_CONST_LONG(OPT_COMPRESSION, MEMC_OPT_COMPRESSION); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_COMPRESSION_TYPE, MEMC_OPT_COMPRESSION_TYPE); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_PREFIX_KEY, MEMC_OPT_PREFIX_KEY); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERIALIZER, MEMC_OPT_SERIALIZER); + + REGISTER_MEMC_CLASS_CONST_LONG(OPT_USER_FLAGS, MEMC_OPT_USER_FLAGS); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_STORE_RETRY_COUNT, MEMC_OPT_STORE_RETRY_COUNT); + + /* + * Indicate whether igbinary serializer is available + */ +#ifdef HAVE_MEMCACHED_IGBINARY + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_IGBINARY, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_IGBINARY, 0); +#endif + + /* + * Indicate whether json serializer is available + */ +#ifdef HAVE_JSON_API + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_JSON, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_JSON, 0); +#endif + + /* + * Indicate whether msgpack serializer is available + */ +#ifdef HAVE_MEMCACHED_MSGPACK + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_MSGPACK, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_MSGPACK, 0); +#endif + + /* + * Indicate whether set_encoding_key is available + */ +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ENCODING, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ENCODING, 0); +#endif + +#ifdef HAVE_MEMCACHED_SESSION + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SESSION, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SESSION, 0); +#endif + +#ifdef HAVE_MEMCACHED_SASL + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SASL, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SASL, 0); +#endif + + /* + * libmemcached behavior options + */ + + REGISTER_MEMC_CLASS_CONST_LONG(OPT_HASH, MEMCACHED_BEHAVIOR_HASH); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_DEFAULT, MEMCACHED_HASH_DEFAULT); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_MD5, MEMCACHED_HASH_MD5); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_CRC, MEMCACHED_HASH_CRC); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1_64, MEMCACHED_HASH_FNV1_64); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1A_64, MEMCACHED_HASH_FNV1A_64); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1_32, MEMCACHED_HASH_FNV1_32); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_FNV1A_32, MEMCACHED_HASH_FNV1A_32); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_HSIEH, MEMCACHED_HASH_HSIEH); + REGISTER_MEMC_CLASS_CONST_LONG(HASH_MURMUR, MEMCACHED_HASH_MURMUR); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_DISTRIBUTION, MEMCACHED_BEHAVIOR_DISTRIBUTION); + REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_MODULA, MEMCACHED_DISTRIBUTION_MODULA); + REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_CONSISTENT, MEMCACHED_DISTRIBUTION_CONSISTENT); + REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_VIRTUAL_BUCKET, MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_COMPATIBLE, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_HASH, MEMCACHED_BEHAVIOR_KETAMA_HASH); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_KEEPALIVE, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_BUFFER_WRITES, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_BINARY_PROTOCOL, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_NO_BLOCK, MEMCACHED_BEHAVIOR_NO_BLOCK); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_NODELAY, MEMCACHED_BEHAVIOR_TCP_NODELAY); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_SOCKET_SEND_SIZE, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_SOCKET_RECV_SIZE, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_CONNECT_TIMEOUT, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_RETRY_TIMEOUT, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT); +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000003 + REGISTER_MEMC_CLASS_CONST_LONG(OPT_DEAD_TIMEOUT, MEMCACHED_BEHAVIOR_DEAD_TIMEOUT); +#endif + REGISTER_MEMC_CLASS_CONST_LONG(OPT_SEND_TIMEOUT, MEMCACHED_BEHAVIOR_SND_TIMEOUT); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_RECV_TIMEOUT, MEMCACHED_BEHAVIOR_RCV_TIMEOUT); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_POLL_TIMEOUT, MEMCACHED_BEHAVIOR_POLL_TIMEOUT); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_CACHE_LOOKUPS, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERVER_FAILURE_LIMIT, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_AUTO_EJECT_HOSTS, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_HASH_WITH_PREFIX_KEY, MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_NOREPLY, MEMCACHED_BEHAVIOR_NOREPLY); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_SORT_HOSTS, MEMCACHED_BEHAVIOR_SORT_HOSTS); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_VERIFY_KEY, MEMCACHED_BEHAVIOR_VERIFY_KEY); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_USE_UDP, MEMCACHED_BEHAVIOR_USE_UDP); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_NUMBER_OF_REPLICAS, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_RANDOMIZE_REPLICA_READ, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_REMOVE_FAILED_SERVERS, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS); +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000018 + REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERVER_TIMEOUT_LIMIT, MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT); +#endif + + /* + * libmemcached result codes + */ + + REGISTER_MEMC_CLASS_CONST_LONG(RES_SUCCESS, MEMCACHED_SUCCESS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_FAILURE, MEMCACHED_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_HOST_LOOKUP_FAILURE, MEMCACHED_HOST_LOOKUP_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_READ_FAILURE, MEMCACHED_UNKNOWN_READ_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_PROTOCOL_ERROR, MEMCACHED_PROTOCOL_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_CLIENT_ERROR, MEMCACHED_CLIENT_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_ERROR, MEMCACHED_SERVER_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_WRITE_FAILURE, MEMCACHED_WRITE_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_DATA_EXISTS, MEMCACHED_DATA_EXISTS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTSTORED, MEMCACHED_NOTSTORED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTFOUND, MEMCACHED_NOTFOUND); + REGISTER_MEMC_CLASS_CONST_LONG(RES_PARTIAL_READ, MEMCACHED_PARTIAL_READ); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SOME_ERRORS, MEMCACHED_SOME_ERRORS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NO_SERVERS, MEMCACHED_NO_SERVERS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_END, MEMCACHED_END); + REGISTER_MEMC_CLASS_CONST_LONG(RES_ERRNO, MEMCACHED_ERRNO); + REGISTER_MEMC_CLASS_CONST_LONG(RES_BUFFERED, MEMCACHED_BUFFERED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_TIMEOUT, MEMCACHED_TIMEOUT); + REGISTER_MEMC_CLASS_CONST_LONG(RES_BAD_KEY_PROVIDED, MEMCACHED_BAD_KEY_PROVIDED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_STORED, MEMCACHED_STORED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_DELETED, MEMCACHED_DELETED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_STAT, MEMCACHED_STAT); + REGISTER_MEMC_CLASS_CONST_LONG(RES_ITEM, MEMCACHED_ITEM); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NOT_SUPPORTED, MEMCACHED_NOT_SUPPORTED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_FETCH_NOTFINISHED, MEMCACHED_FETCH_NOTFINISHED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_MARKED_DEAD, MEMCACHED_SERVER_MARKED_DEAD); + REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_STAT_KEY, MEMCACHED_UNKNOWN_STAT_KEY); + REGISTER_MEMC_CLASS_CONST_LONG(RES_INVALID_HOST_PROTOCOL, MEMCACHED_INVALID_HOST_PROTOCOL); + REGISTER_MEMC_CLASS_CONST_LONG(RES_MEMORY_ALLOCATION_FAILURE, MEMCACHED_MEMORY_ALLOCATION_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_CONNECTION_SOCKET_CREATE_FAILURE, MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE); + + REGISTER_MEMC_CLASS_CONST_LONG(RES_E2BIG, MEMCACHED_E2BIG); + REGISTER_MEMC_CLASS_CONST_LONG(RES_KEY_TOO_BIG, MEMCACHED_KEY_TOO_BIG); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_TEMPORARILY_DISABLED, MEMCACHED_SERVER_TEMPORARILY_DISABLED); + +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000008 + REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_MEMORY_ALLOCATION_FAILURE, MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE); +#endif + +#ifdef HAVE_MEMCACHED_SASL + REGISTER_MEMC_CLASS_CONST_LONG(RES_AUTH_PROBLEM, MEMCACHED_AUTH_PROBLEM); + REGISTER_MEMC_CLASS_CONST_LONG(RES_AUTH_FAILURE, MEMCACHED_AUTH_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_AUTH_CONTINUE, MEMCACHED_AUTH_CONTINUE); +#endif + + /* + * Our result codes. + */ + + REGISTER_MEMC_CLASS_CONST_LONG(RES_PAYLOAD_FAILURE, MEMC_RES_PAYLOAD_FAILURE); + + /* + * Serializer types. + */ + REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_PHP, SERIALIZER_PHP); + REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_IGBINARY, SERIALIZER_IGBINARY); + REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_JSON, SERIALIZER_JSON); + REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_JSON_ARRAY, SERIALIZER_JSON_ARRAY); + REGISTER_MEMC_CLASS_CONST_LONG(SERIALIZER_MSGPACK, SERIALIZER_MSGPACK); + + /* + * Compression types + */ + REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_FASTLZ, COMPRESSION_TYPE_FASTLZ); + REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_ZLIB, COMPRESSION_TYPE_ZLIB); + + /* + * Flags. + */ + REGISTER_MEMC_CLASS_CONST_LONG(GET_PRESERVE_ORDER, MEMC_GET_PRESERVE_ORDER); + REGISTER_MEMC_CLASS_CONST_LONG(GET_EXTENDED, MEMC_GET_EXTENDED); + +#ifdef HAVE_MEMCACHED_PROTOCOL + /* + * Server callbacks + */ + REGISTER_MEMC_CLASS_CONST_LONG(ON_CONNECT, MEMC_SERVER_ON_CONNECT); + REGISTER_MEMC_CLASS_CONST_LONG(ON_ADD, MEMC_SERVER_ON_ADD); + REGISTER_MEMC_CLASS_CONST_LONG(ON_APPEND, MEMC_SERVER_ON_APPEND); + REGISTER_MEMC_CLASS_CONST_LONG(ON_DECREMENT, MEMC_SERVER_ON_DECREMENT); + REGISTER_MEMC_CLASS_CONST_LONG(ON_DELETE, MEMC_SERVER_ON_DELETE); + REGISTER_MEMC_CLASS_CONST_LONG(ON_FLUSH, MEMC_SERVER_ON_FLUSH); + REGISTER_MEMC_CLASS_CONST_LONG(ON_GET, MEMC_SERVER_ON_GET); + REGISTER_MEMC_CLASS_CONST_LONG(ON_INCREMENT, MEMC_SERVER_ON_INCREMENT); + REGISTER_MEMC_CLASS_CONST_LONG(ON_NOOP, MEMC_SERVER_ON_NOOP); + REGISTER_MEMC_CLASS_CONST_LONG(ON_PREPEND, MEMC_SERVER_ON_PREPEND); + REGISTER_MEMC_CLASS_CONST_LONG(ON_QUIT, MEMC_SERVER_ON_QUIT); + REGISTER_MEMC_CLASS_CONST_LONG(ON_REPLACE, MEMC_SERVER_ON_REPLACE); + REGISTER_MEMC_CLASS_CONST_LONG(ON_SET, MEMC_SERVER_ON_SET); + REGISTER_MEMC_CLASS_CONST_LONG(ON_STAT, MEMC_SERVER_ON_STAT); + REGISTER_MEMC_CLASS_CONST_LONG(ON_VERSION, MEMC_SERVER_ON_VERSION); + + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_SUCCESS, PROTOCOL_BINARY_RESPONSE_SUCCESS); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_KEY_ENOENT, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_KEY_EEXISTS, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_E2BIG, PROTOCOL_BINARY_RESPONSE_E2BIG); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_EINVAL, PROTOCOL_BINARY_RESPONSE_EINVAL); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_NOT_STORED, PROTOCOL_BINARY_RESPONSE_NOT_STORED); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_DELTA_BADVAL, PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_NOT_MY_VBUCKET, PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_AUTH_ERROR, PROTOCOL_BINARY_RESPONSE_AUTH_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_AUTH_CONTINUE, PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_UNKNOWN_COMMAND, PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_ENOMEM, PROTOCOL_BINARY_RESPONSE_ENOMEM); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_NOT_SUPPORTED, PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_EINTERNAL, PROTOCOL_BINARY_RESPONSE_EINTERNAL); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_EBUSY, PROTOCOL_BINARY_RESPONSE_EBUSY); + REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_ETMPFAIL, PROTOCOL_BINARY_RESPONSE_ETMPFAIL); +#endif + + /* + * Return value from simple get errors + */ + REGISTER_MEMC_CLASS_CONST_BOOL(GET_ERROR_RETURN_VALUE, 0); + + #undef REGISTER_MEMC_CLASS_CONST_LONG + #undef REGISTER_MEMC_CLASS_CONST_BOOL + #undef REGISTER_MEMC_CLASS_CONST_NULL + +} +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION */ +PHP_MINIT_FUNCTION(memcached) +{ + zend_class_entry ce; + + memcpy(&memcached_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + memcached_object_handlers.offset = XtOffsetOf(php_memc_object_t, zo); + memcached_object_handlers.clone_obj = NULL; + memcached_object_handlers.free_obj = php_memc_object_free_storage; + + le_memc = zend_register_list_destructors_ex(NULL, php_memc_dtor, "Memcached persistent connection", module_number); + + INIT_CLASS_ENTRY(ce, "Memcached", memcached_class_methods); + memcached_ce = zend_register_internal_class(&ce); + memcached_ce->create_object = php_memc_object_new; + +#ifdef HAVE_MEMCACHED_PROTOCOL + memcpy(&memcached_server_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + memcached_server_object_handlers.offset = XtOffsetOf(php_memc_server_t, zo); + memcached_server_object_handlers.clone_obj = NULL; + memcached_server_object_handlers.free_obj = php_memc_server_free_storage; + + INIT_CLASS_ENTRY(ce, "MemcachedServer", memcached_server_class_methods); + memcached_server_ce = zend_register_internal_class(&ce); + memcached_server_ce->create_object = php_memc_server_new; +#endif + + INIT_CLASS_ENTRY(ce, "MemcachedException", NULL); + memcached_exception_ce = zend_register_internal_class_ex(&ce, php_memc_get_exception_base(0)); + /* TODO + * possibly declare custom exception property here + */ + + php_memc_register_constants(INIT_FUNC_ARGS_PASSTHRU); + REGISTER_INI_ENTRIES(); + +#ifdef HAVE_MEMCACHED_SESSION + php_memc_session_minit(module_number); +#endif + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION */ +PHP_MSHUTDOWN_FUNCTION(memcached) +{ +#ifdef HAVE_MEMCACHED_SASL + if (MEMC_G(sasl_initialised)) { + sasl_done(); + } +#endif + + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION */ +PHP_MINFO_FUNCTION(memcached) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "memcached support", "enabled"); + php_info_print_table_row(2, "Version", PHP_MEMCACHED_VERSION); + php_info_print_table_row(2, "libmemcached version", memcached_lib_version()); + +#ifdef HAVE_MEMCACHED_SASL + php_info_print_table_row(2, "SASL support", "yes"); +#else + php_info_print_table_row(2, "SASL support", "no"); +#endif + +#ifdef HAVE_MEMCACHED_SESSION + php_info_print_table_row(2, "Session support", "yes"); +#else + php_info_print_table_row(2, "Session support ", "no"); +#endif + +#ifdef HAVE_MEMCACHED_IGBINARY + php_info_print_table_row(2, "igbinary support", "yes"); +#else + php_info_print_table_row(2, "igbinary support", "no"); +#endif + +#ifdef HAVE_JSON_API + php_info_print_table_row(2, "json support", "yes"); +#else + php_info_print_table_row(2, "json support", "no"); +#endif + +#ifdef HAVE_MEMCACHED_MSGPACK + php_info_print_table_row(2, "msgpack support", "yes"); +#else + php_info_print_table_row(2, "msgpack support", "no"); +#endif + + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} +/* }}} */ + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim: noet sw=4 ts=4 fdm=marker: + */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached.h php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached.h 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached.h 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,57 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_MEMCACHED_H +#define PHP_MEMCACHED_H + +#include "php.h" +#include "Zend/zend_smart_str.h" + +#ifdef PHP_WIN32 +#include "main/config.w32.h" +#else +#include "main/php_config.h" +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#define PHP_MEMCACHED_VERSION "3.1.4" + +#if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) +#define PHP_MEMCACHED_API __declspec(dllexport) +#else +#define PHP_MEMCACHED_API PHPAPI +#endif + +PHP_MEMCACHED_API zend_class_entry *php_memc_get_ce(void); +PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception(void); +PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception_base(int root); + +extern zend_module_entry memcached_module_entry; +#define phpext_memcached_ptr &memcached_module_entry + +#endif /* PHP_MEMCACHED_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_private.h php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_private.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_private.h 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_private.h 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,248 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_MEMCACHED_PRIVATE_H +#define PHP_MEMCACHED_PRIVATE_H + +#ifdef PHP_WIN32 +#include "main/config.w32.h" +#else +#include "main/php_config.h" +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "php_libmemcached_compat.h" + +#include +#include +#include +#include + +#ifdef ZTS +# include "TSRM.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef PHP_WIN32 +# include "win32/php_stdint.h" +#else +/* Used to store the size of the block */ +# if defined(HAVE_INTTYPES_H) +# include +# elif defined(HAVE_STDINT_H) +# include +# endif +#endif + +#ifndef HAVE_INT32_T +# if SIZEOF_INT == 4 +typedef int int32_t; +# elif SIZEOF_LONG == 4 +typedef long int int32_t; +# endif +#endif + +#ifndef HAVE_UINT32_T +# if SIZEOF_INT == 4 +typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 +typedef unsigned long int uint32_t; +# endif +#endif + +/* Backwards compatibility for GC API change in PHP 7.3 */ +#if PHP_VERSION_ID < 70300 +# define GC_ADDREF(p) ++GC_REFCOUNT(p) +# define GC_DELREF(p) --GC_REFCOUNT(p) +# define GC_SET_REFCOUNT(p, rc) GC_REFCOUNT(p) = rc +#endif + +/**************************************** + Structures and definitions +****************************************/ +typedef enum { + SERIALIZER_PHP = 1, + SERIALIZER_IGBINARY = 2, + SERIALIZER_JSON = 3, + SERIALIZER_JSON_ARRAY = 4, + SERIALIZER_MSGPACK = 5 +} php_memc_serializer_type; + +typedef enum { + COMPRESSION_TYPE_ZLIB = 1, + COMPRESSION_TYPE_FASTLZ = 2 +} php_memc_compression_type; + +typedef struct { + const char *name; + php_memc_serializer_type type; +} php_memc_serializer; + +#if defined(HAVE_MEMCACHED_IGBINARY) +# define SERIALIZER_DEFAULT SERIALIZER_IGBINARY +# define SERIALIZER_DEFAULT_NAME "igbinary" +#elif defined(HAVE_MEMCACHED_MSGPACK) +# define SERIALIZER_DEFAULT SERIALIZER_MSGPACK +# define SERIALIZER_DEFAULT_NAME "msgpack" +#else +# define SERIALIZER_DEFAULT SERIALIZER_PHP +# define SERIALIZER_DEFAULT_NAME "php" +#endif /* HAVE_MEMCACHED_IGBINARY / HAVE_MEMCACHED_MSGPACK */ + +#ifdef HAVE_MEMCACHED_SASL +# include +#endif + +#ifdef HAVE_MEMCACHED_PROTOCOL +typedef enum { + MEMC_SERVER_ON_MIN = -1, + MEMC_SERVER_ON_CONNECT = 0, + MEMC_SERVER_ON_ADD = 1, + MEMC_SERVER_ON_APPEND = 2, + MEMC_SERVER_ON_DECREMENT = 3, + MEMC_SERVER_ON_DELETE = 4, + MEMC_SERVER_ON_FLUSH = 5, + MEMC_SERVER_ON_GET = 6, + MEMC_SERVER_ON_INCREMENT = 7, + MEMC_SERVER_ON_NOOP = 8, + MEMC_SERVER_ON_PREPEND = 9, + MEMC_SERVER_ON_QUIT = 10, + MEMC_SERVER_ON_REPLACE = 11, + MEMC_SERVER_ON_SET = 12, + MEMC_SERVER_ON_STAT = 13, + MEMC_SERVER_ON_VERSION = 14, + MEMC_SERVER_ON_MAX +} php_memc_event_t; + + +typedef struct { + zend_fcall_info fci; + zend_fcall_info_cache fci_cache; +} php_memc_server_cb_t; +#endif + +ZEND_BEGIN_MODULE_GLOBALS(php_memcached) + +#ifdef HAVE_MEMCACHED_SESSION + /* Session related variables */ + struct { + zend_bool lock_enabled; + zend_long lock_wait_max; + zend_long lock_wait_min; + zend_long lock_retries; + zend_long lock_expiration; + + zend_bool binary_protocol_enabled; + zend_bool consistent_hash_enabled; + char *consistent_hash_name; + int consistent_hash_type; + + zend_long server_failure_limit; + zend_long number_of_replicas; + zend_bool randomize_replica_read_enabled; + zend_bool remove_failed_servers_enabled; + + zend_long connect_timeout; + + char *prefix; + zend_bool persistent_enabled; + + char *sasl_username; + char *sasl_password; + } session; +#endif + + struct { + char *serializer_name; + char *compression_name; + zend_long compression_threshold; + double compression_factor; + zend_long store_retry_count; + + /* Converted values*/ + php_memc_serializer_type serializer_type; + php_memc_compression_type compression_type; + + /* Whether we have initialised sasl for this process */ + zend_bool sasl_initialised; + + struct { + + zend_bool consistent_hash_enabled; + zend_bool binary_protocol_enabled; + zend_long connect_timeout; + + } default_behavior; + + } memc; + + /* For deprecated values */ + zend_long no_effect; + +#ifdef HAVE_MEMCACHED_PROTOCOL + struct { + php_memc_server_cb_t callbacks [MEMC_SERVER_ON_MAX]; + } server; +#endif + +ZEND_END_MODULE_GLOBALS(php_memcached) + +/* Globals accessor macros */ +#ifdef ZTS +# define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) +# define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) +# define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v) +#else +# define MEMC_G(v) (php_memcached_globals.memc.v) +# define MEMC_SERVER_G(v) (php_memcached_globals.server.v) +# define MEMC_SESS_INI(v) (php_memcached_globals.session.v) +#endif + +#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL) + +PHP_RINIT_FUNCTION(memcached); +PHP_RSHUTDOWN_FUNCTION(memcached); +PHP_MINIT_FUNCTION(memcached); +PHP_MSHUTDOWN_FUNCTION(memcached); +PHP_MINFO_FUNCTION(memcached); + +char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache); + +memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); + +zend_bool php_memc_init_sasl_if_needed(); + +#endif /* PHP_MEMCACHED_PRIVATE_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_server.c php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_server.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_server.c 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_server.c 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,820 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Mikko Koppanen | + +----------------------------------------------------------------------+ +*/ + +#include "php_memcached.h" +#include "php_memcached_private.h" +#include "php_memcached_server.h" + +#include + +#undef NDEBUG +#undef _NDEBUG +#include + +#define MEMC_GET_CB(cb_type) (MEMC_SERVER_G(callbacks)[cb_type]) +#define MEMC_HAS_CB(cb_type) (MEMC_GET_CB(cb_type).fci.size > 0) + +#define MEMC_MAKE_ZVAL_COOKIE(my_zcookie, my_ptr) \ + do { \ + zend_string *cookie_buf; \ + cookie_buf = strpprintf(0, "%p", my_ptr); \ + ZVAL_STR(&my_zcookie, cookie_buf); \ + } while (0) + +#define MEMC_MAKE_RESULT_CAS(my_zresult_cas, my_result_cas) \ + do { \ + my_result_cas = 0; \ + my_result_cas = zval_get_double(&my_zresult_cas); \ + } while (0) + + +ZEND_EXTERN_MODULE_GLOBALS(php_memcached) + +struct _php_memc_proto_handler_t { + memcached_binary_protocol_callback_st callbacks; + struct memcached_protocol_st *protocol_handle; + struct event_base *event_base; +}; + +typedef struct { + struct memcached_protocol_client_st *protocol_client; + struct event_base *event_base; + zend_bool on_connect_invoked; +} php_memc_client_t; + +static +long s_invoke_php_callback (php_memc_server_cb_t *cb, zval *params, ssize_t param_count) +{ + zval *retval = NULL; + + cb->fci.retval = retval; + cb->fci.params = params; + cb->fci.param_count = param_count; + cb->fci.no_separation = 1; + + if (zend_call_function(&(cb->fci), &(cb->fci_cache)) == FAILURE) { + char *buf = php_memc_printable_func(&(cb->fci), &(cb->fci_cache)); + php_error_docref(NULL, E_WARNING, "Failed to invoke callback %s()", buf); + efree (buf); + } + + return retval == NULL ? PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND : zval_get_long(retval); +} + +// memcached protocol callbacks +static +protocol_binary_response_status s_add_handler(const void *cookie, const void *key, uint16_t key_len, const void *data, + uint32_t data_len, uint32_t flags, uint32_t exptime, uint64_t *result_cas) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zkey, zvalue, zflags, zexptime, zresult_cas; + zval params[6]; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_ADD)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_STRINGL(&zkey, key, key_len); + ZVAL_STRINGL(&zvalue, data, data_len); + ZVAL_LONG(&zflags, flags); + ZVAL_LONG(&zexptime, exptime); + ZVAL_NULL(&zresult_cas); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zkey); + ZVAL_COPY(¶ms[2], &zvalue); + ZVAL_COPY(¶ms[3], &zflags); + ZVAL_COPY(¶ms[4], &zexptime); + ZVAL_COPY(¶ms[5], &zresult_cas); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_ADD), params, 6); + + MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(¶ms[3]); + zval_ptr_dtor(¶ms[4]); + zval_ptr_dtor(¶ms[5]); + zval_ptr_dtor (&zcookie); + zval_ptr_dtor (&zkey); + zval_ptr_dtor (&zvalue); + zval_ptr_dtor (&zflags); + zval_ptr_dtor (&zexptime); + zval_ptr_dtor (&zresult_cas); + + return retval; +} + +static +protocol_binary_response_status s_append_prepend_handler (php_memc_event_t event, const void *cookie, const void *key, uint16_t key_len, + const void *data, uint32_t data_len, uint64_t cas, uint64_t *result_cas) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zkey, zvalue, zcas, zresult_cas; + zval params[5]; + + if (!MEMC_HAS_CB(event)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_STRINGL(&zkey, key, key_len); + ZVAL_STRINGL(&zvalue, data, data_len); + ZVAL_DOUBLE(&zcas, cas); + ZVAL_NULL(&zresult_cas); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zkey); + ZVAL_COPY(¶ms[2], &zvalue); + ZVAL_COPY(¶ms[3], &zcas); + ZVAL_COPY(¶ms[4], &zresult_cas); + + retval = s_invoke_php_callback (&MEMC_GET_CB(event), params, 5); + + MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(¶ms[3]); + zval_ptr_dtor(¶ms[4]); + zval_ptr_dtor (&zcookie); + zval_ptr_dtor (&zkey); + zval_ptr_dtor (&zvalue); + zval_ptr_dtor (&zcas); + zval_ptr_dtor (&zresult_cas); + + return retval; +} + +static +protocol_binary_response_status s_append_handler (const void *cookie, const void *key, uint16_t key_len, + const void *data, uint32_t data_len, uint64_t cas, uint64_t *result_cas) +{ + return + s_append_prepend_handler (MEMC_SERVER_ON_APPEND, cookie, key, key_len, data, data_len, cas, result_cas); +} + +static +protocol_binary_response_status s_prepend_handler (const void *cookie, const void *key, uint16_t key_len, + const void *data, uint32_t data_len, uint64_t cas, uint64_t *result_cas) +{ + return + s_append_prepend_handler (MEMC_SERVER_ON_PREPEND, cookie, key, key_len, data, data_len, cas, result_cas); +} + +static +protocol_binary_response_status s_incr_decr_handler (php_memc_event_t event, const void *cookie, const void *key, uint16_t key_len, uint64_t delta, + uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zkey, zdelta, zinital, zexpiration, zresult, zresult_cas; + zval params[7]; + + if (!MEMC_HAS_CB(event)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_STRINGL(&zkey, key, key_len); + ZVAL_LONG(&zdelta, (long) delta); + ZVAL_LONG(&zinital, (long) initial); + ZVAL_LONG(&zexpiration, (long) expiration); + ZVAL_LONG(&zresult, 0); + ZVAL_NULL(&zresult_cas); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zkey); + ZVAL_COPY(¶ms[2], &zdelta); + ZVAL_COPY(¶ms[3], &zinital); + ZVAL_COPY(¶ms[4], &zexpiration); + ZVAL_COPY(¶ms[5], &zresult); + ZVAL_COPY(¶ms[6], &zresult_cas); + + retval = s_invoke_php_callback (&MEMC_GET_CB(event), params, 7); + + *result = (uint64_t)zval_get_long(&zresult); + + MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(¶ms[3]); + zval_ptr_dtor(¶ms[4]); + zval_ptr_dtor(¶ms[5]); + zval_ptr_dtor(¶ms[6]); + zval_ptr_dtor (&zcookie); + zval_ptr_dtor (&zkey); + zval_ptr_dtor (&zdelta); + zval_ptr_dtor (&zinital); + zval_ptr_dtor (&zexpiration); + zval_ptr_dtor (&zresult); + zval_ptr_dtor (&zresult_cas); + + return retval; +} + +static +protocol_binary_response_status s_increment_handler (const void *cookie, const void *key, uint16_t key_len, uint64_t delta, + uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) +{ + return + s_incr_decr_handler (MEMC_SERVER_ON_INCREMENT, cookie, key, key_len, delta, initial, expiration, result, result_cas); +} + +static +protocol_binary_response_status s_decrement_handler (const void *cookie, const void *key, uint16_t key_len, uint64_t delta, + uint64_t initial, uint32_t expiration, uint64_t *result, uint64_t *result_cas) +{ + return + s_incr_decr_handler (MEMC_SERVER_ON_DECREMENT, cookie, key, key_len, delta, initial, expiration, result, result_cas); +} + +static +protocol_binary_response_status s_delete_handler (const void *cookie, const void *key, + uint16_t key_len, uint64_t cas) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zkey, zcas; + zval params[3]; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_DELETE)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_STRINGL(&zkey, key, key_len); + ZVAL_DOUBLE(&zcas, (double) cas); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zkey); + ZVAL_COPY(¶ms[2], &zcas); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_DELETE), params, 3); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(&zcookie); + zval_ptr_dtor(&zkey); + zval_ptr_dtor(&zcas); + return retval; +} + +static +protocol_binary_response_status s_flush_handler(const void *cookie, uint32_t when) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zwhen; + zval params[2]; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_FLUSH)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zwhen); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_FLUSH), params, 2); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(&zcookie); + zval_ptr_dtor(&zwhen); + return retval; +} + +static +protocol_binary_response_status s_get_handler (const void *cookie, const void *key, uint16_t key_len, + memcached_binary_protocol_get_response_handler response_handler) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zkey, zvalue, zflags, zresult_cas; + zval params[5]; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_GET)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zkey); + ZVAL_COPY(¶ms[2], &zvalue); + ZVAL_COPY(¶ms[3], &zflags); + ZVAL_COPY(¶ms[4], &zresult_cas); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_GET), params, 5); + + /* Succeeded in getting the key */ + if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { + uint32_t flags = 0; + uint64_t result_cas = 0; + + if (Z_TYPE(zvalue) == IS_NULL) { + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(¶ms[3]); + zval_ptr_dtor(¶ms[4]); + zval_ptr_dtor(&zcookie); + zval_ptr_dtor(&zkey); + zval_ptr_dtor(&zvalue); + zval_ptr_dtor(&zflags); + zval_ptr_dtor(&zresult_cas); + return PROTOCOL_BINARY_RESPONSE_KEY_ENOENT; + } + + if (Z_TYPE(zvalue) != IS_STRING) { + convert_to_string (&zvalue); + } + + if (Z_TYPE(zflags) == IS_LONG) { + flags = Z_LVAL(zflags); + } + + MEMC_MAKE_RESULT_CAS(zresult_cas, result_cas); + retval = response_handler(cookie, key, key_len, Z_STRVAL(zvalue), Z_STRLEN(zvalue), flags, result_cas); + } + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(¶ms[3]); + zval_ptr_dtor(¶ms[4]); + zval_ptr_dtor (&zcookie); + zval_ptr_dtor (&zkey); + zval_ptr_dtor (&zvalue); + zval_ptr_dtor (&zflags); + zval_ptr_dtor (&zresult_cas); + return retval; +} + +static +protocol_binary_response_status s_noop_handler(const void *cookie) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie; + zval params[1]; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_NOOP)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_COPY(¶ms[0], &zcookie); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_NOOP), params, 1); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor (&zcookie); + return retval; +} + +static +protocol_binary_response_status s_quit_handler(const void *cookie) +{ + zval params[1]; + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_QUIT)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_COPY(¶ms[0], &zcookie); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_QUIT), params, 1); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor (&zcookie); + return retval; +} + + + +static +protocol_binary_response_status s_set_replace_handler (php_memc_event_t event, const void *cookie, const void *key, uint16_t key_len, const void *data, + uint32_t data_len, uint32_t flags, uint32_t expiration, uint64_t cas, uint64_t *result_cas) +{ + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zkey, zdata, zflags, zexpiration, zcas, zresult_cas; + zval params[7]; + + if (!MEMC_HAS_CB(event)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_STRINGL(&zkey, key, key_len); + ZVAL_STRINGL(&zdata, ((char *) data), (int) data_len); + ZVAL_LONG(&zflags, (long) flags); + ZVAL_LONG(&zexpiration, (long) expiration); + ZVAL_DOUBLE(&zcas, (double) cas); + ZVAL_NULL(&zresult_cas); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zkey); + ZVAL_COPY(¶ms[2], &zdata); + ZVAL_COPY(¶ms[3], &zflags); + ZVAL_COPY(¶ms[4], &zexpiration); + ZVAL_COPY(¶ms[5], &zcas); + ZVAL_COPY(¶ms[6], &zresult_cas); + + retval = s_invoke_php_callback (&MEMC_GET_CB(event), params, 7); + + MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(¶ms[3]); + zval_ptr_dtor(¶ms[4]); + zval_ptr_dtor(¶ms[5]); + zval_ptr_dtor(¶ms[6]); + zval_ptr_dtor (&zcookie); + zval_ptr_dtor (&zkey); + zval_ptr_dtor (&zdata); + zval_ptr_dtor (&zflags); + zval_ptr_dtor (&zexpiration); + zval_ptr_dtor (&zcas); + zval_ptr_dtor (&zresult_cas); + + return retval; +} + +static +protocol_binary_response_status s_replace_handler (const void *cookie, const void *key, uint16_t key_len, const void *data, + uint32_t data_len, uint32_t flags, uint32_t expiration, uint64_t cas, uint64_t *result_cas) +{ + return + s_set_replace_handler (MEMC_SERVER_ON_REPLACE, cookie, key, key_len, data, data_len, flags, expiration, cas, result_cas); +} + +static +protocol_binary_response_status s_set_handler (const void *cookie, const void *key, uint16_t key_len, const void *data, + uint32_t data_len, uint32_t flags, uint32_t expiration, uint64_t cas, uint64_t *result_cas) +{ + return + s_set_replace_handler (MEMC_SERVER_ON_SET, cookie, key, key_len, data, data_len, flags, expiration, cas, result_cas); +} + +static +protocol_binary_response_status s_stat_handler (const void *cookie, const void *key, uint16_t key_len, + memcached_binary_protocol_stat_response_handler response_handler) +{ + zval params[3]; + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zkey, zbody; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_STAT)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_STRINGL(&zkey, key, key_len); + ZVAL_NULL(&zbody); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zkey); + ZVAL_COPY(¶ms[2], &zbody); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_STAT), params, 3); + + if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { + if (Z_TYPE(zbody) == IS_NULL) { + retval = response_handler(cookie, NULL, 0, NULL, 0); + } + else { + if (Z_TYPE(zbody) != IS_STRING) { + convert_to_string(&zbody); + } + retval = response_handler(cookie, key, key_len, Z_STRVAL(zbody), (uint32_t) Z_STRLEN(zbody)); + } + } + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor (&zcookie); + zval_ptr_dtor (&zkey); + zval_ptr_dtor (&zbody); + return retval; +} + +static +protocol_binary_response_status s_version_handler (const void *cookie, + memcached_binary_protocol_version_response_handler response_handler) +{ + zval params[2]; + protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; + zval zcookie, zversion; + + if (!MEMC_HAS_CB(MEMC_SERVER_ON_VERSION)) { + return retval; + } + + MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + + ZVAL_NULL(&zversion); + + ZVAL_COPY(¶ms[0], &zcookie); + ZVAL_COPY(¶ms[1], &zversion); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_VERSION), params, 2); + + if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { + if (Z_TYPE(zversion) != IS_STRING) { + convert_to_string(&zversion); + } + + retval = response_handler (cookie, Z_STRVAL(zversion), (uint32_t) Z_STRLEN(zversion)); + } + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor (&zcookie); + zval_ptr_dtor (&zversion); + return retval; +} + + +// libevent callbacks + +static +void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg) +{ + int rc; + short flags = 0; + php_memc_client_t *client = (php_memc_client_t *) arg; + memcached_protocol_event_t events; + + if (!client->on_connect_invoked) { + if (MEMC_HAS_CB(MEMC_SERVER_ON_CONNECT)) { + zval zremoteip, zremoteport; + zval params[2]; + protocol_binary_response_status retval; + + struct sockaddr_in addr_in; + socklen_t addr_in_len = sizeof(addr_in); + + if (getpeername (fd, (struct sockaddr *) &addr_in, &addr_in_len) == 0) { + ZVAL_STRING(&zremoteip, inet_ntoa (addr_in.sin_addr)); + ZVAL_LONG(&zremoteport, ntohs (addr_in.sin_port)); + } else { + php_error_docref(NULL, E_WARNING, "getpeername failed: %s", strerror (errno)); + ZVAL_NULL(&zremoteip); + ZVAL_NULL(&zremoteport); + } + + ZVAL_COPY(¶ms[0], &zremoteip); + ZVAL_COPY(¶ms[1], &zremoteport); + + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_CONNECT), params, 2); + + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(&zremoteip); + zval_ptr_dtor(&zremoteport); + + if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS) { + memcached_protocol_client_destroy (client->protocol_client); + efree (client); + evutil_closesocket (fd); + return; + } + } + client->on_connect_invoked = 1; + } + + events = memcached_protocol_client_work (client->protocol_client); + + if (events & MEMCACHED_PROTOCOL_ERROR_EVENT) { + memcached_protocol_client_destroy (client->protocol_client); + efree (client); + evutil_closesocket (fd); + return; + } + + if (events & MEMCACHED_PROTOCOL_WRITE_EVENT) { + flags = EV_WRITE; + } + + if (events & MEMCACHED_PROTOCOL_READ_EVENT) { + flags |= EV_READ; + } + + rc = event_base_once (client->event_base, fd, flags, s_handle_memcached_event, client, NULL); + if (rc != 0) { + php_error_docref (NULL, E_WARNING, "Failed to schedule events"); + } +} + +static +void s_accept_cb (evutil_socket_t fd, short what, void *arg) +{ + int rc; + php_memc_client_t *client; + struct sockaddr_storage addr; + socklen_t addr_len; + evutil_socket_t sock; + + php_memc_proto_handler_t *handler = (php_memc_proto_handler_t *) arg; + + /* Accept the connection */ + addr_len = sizeof (addr); + sock = accept (fd, (struct sockaddr *) &addr, &addr_len); + + if (sock == -1) { + php_error_docref (NULL, E_WARNING, "Failed to accept the client: %s", strerror (errno)); + return; + } + + client = ecalloc (1, sizeof (php_memc_client_t)); + client->protocol_client = memcached_protocol_create_client (handler->protocol_handle, sock); + client->event_base = handler->event_base; + client->on_connect_invoked = 0; + + if (!client->protocol_client) { + php_error_docref (NULL, E_WARNING, "Failed to allocate protocol client"); + efree (client); + evutil_closesocket (sock); + return; + } + + // TODO: this should timeout + rc = event_base_once (handler->event_base, sock, EV_READ, s_handle_memcached_event, client, NULL); + + if (rc != 0) { + php_error_docref (NULL, E_WARNING, "Failed to add event for client"); + memcached_protocol_client_destroy (client->protocol_client); + efree (client); + evutil_closesocket (sock); + return; + } +} + +php_memc_proto_handler_t *php_memc_proto_handler_new () +{ + php_memc_proto_handler_t *handler = ecalloc (1, sizeof (php_memc_proto_handler_t)); + + handler->protocol_handle = memcached_protocol_create_instance (); + assert (handler->protocol_handle); + + memset (&handler->callbacks, 0, sizeof (memcached_binary_protocol_callback_st)); + + handler->callbacks.interface_version = MEMCACHED_PROTOCOL_HANDLER_V1; + handler->callbacks.interface.v1.add = s_add_handler; + handler->callbacks.interface.v1.append = s_append_handler; + handler->callbacks.interface.v1.decrement = s_decrement_handler; + handler->callbacks.interface.v1.delete_object = s_delete_handler; + handler->callbacks.interface.v1.flush_object = s_flush_handler; + handler->callbacks.interface.v1.get = s_get_handler; + handler->callbacks.interface.v1.increment = s_increment_handler; + handler->callbacks.interface.v1.noop = s_noop_handler; + handler->callbacks.interface.v1.prepend = s_prepend_handler; + handler->callbacks.interface.v1.quit = s_quit_handler; + handler->callbacks.interface.v1.replace = s_replace_handler; + handler->callbacks.interface.v1.set = s_set_handler; + handler->callbacks.interface.v1.stat = s_stat_handler; + handler->callbacks.interface.v1.version = s_version_handler; + + memcached_binary_protocol_set_callbacks(handler->protocol_handle, &handler->callbacks); + return handler; +} + +static +evutil_socket_t s_create_listening_socket (const char *spec) +{ + evutil_socket_t sock; + struct sockaddr_storage addr; + int addr_len; + + int rc; + + addr_len = sizeof (struct sockaddr); + rc = evutil_parse_sockaddr_port (spec, (struct sockaddr *) &addr, &addr_len); + if (rc != 0) { + php_error_docref(NULL, E_WARNING, "Failed to parse bind address"); + return -1; + } + + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + php_error_docref(NULL, E_WARNING, "socket failed: %s", strerror (errno)); + return -1; + } + + rc = bind (sock, (struct sockaddr *) &addr, addr_len); + if (rc < 0) { + php_error_docref(NULL, E_WARNING, "bind failed: %s", strerror (errno)); + return -1; + } + + rc = listen (sock, 1024); + if (rc < 0) { + php_error_docref(NULL, E_WARNING, "listen failed: %s", strerror (errno)); + return -1; + } + + rc = evutil_make_socket_nonblocking (sock); + if (rc != 0) { + php_error_docref(NULL, E_WARNING, "failed to make socket non-blocking: %s", strerror (errno)); + return -1; + } + + rc = evutil_make_listen_socket_reuseable (sock); + if (rc != 0) { + php_error_docref(NULL, E_WARNING, "failed to make socket reuseable: %s", strerror (errno)); + return -1; + } + + rc = evutil_make_socket_closeonexec (sock); + if (rc != 0) { + php_error_docref(NULL, E_WARNING, "failed to make socket closeonexec: %s", strerror (errno)); + return -1; + } + return sock; +} + +zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t *handler, zend_string *address) +{ + struct event *accept_event; + evutil_socket_t sock = s_create_listening_socket (address->val); + + if (sock == -1) { + return 0; + } + + handler->event_base = event_base_new(); + if (!handler->event_base) { + php_error_docref(NULL, E_ERROR, "failed to allocate memory: %s", strerror (errno)); + } + accept_event = event_new (handler->event_base, sock, EV_READ | EV_PERSIST, s_accept_cb, handler); + if (!accept_event) { + php_error_docref(NULL, E_ERROR, "failed to allocate memory: %s", strerror (errno)); + } + event_add (accept_event, NULL); + + switch (event_base_dispatch (handler->event_base)) { + case -1: + php_error_docref(NULL, E_ERROR, "event_base_dispatch() failed: %s", strerror (errno)); + return 0; + break; + + case 1: + php_error_docref(NULL, E_ERROR, "no events registered"); + return 0; + break; + + default: + return 1; + break; + } +} + +void php_memc_proto_handler_destroy (php_memc_proto_handler_t **ptr) +{ + php_memc_proto_handler_t *handler = *ptr; + + if (handler->protocol_handle) + memcached_protocol_destroy_instance (handler->protocol_handle); + + efree (handler); + *ptr = NULL; +} +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim: noet sw=4 ts=4 fdm=marker: + */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_server.h php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_server.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_server.h 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_server.h 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,40 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Mikko Koppanen | + +----------------------------------------------------------------------+ +*/ + +#ifndef _PHP_MEMCACHED_SERVER_H_ +# define _PHP_MEMCACHED_SERVER_H_ + +#ifdef HAVE_MEMCACHED_PROTOCOL + +#include + +/* + Opaque structure +*/ +typedef struct _php_memc_proto_handler_t php_memc_proto_handler_t; + +/* + Functions +*/ +php_memc_proto_handler_t *php_memc_proto_handler_new (); + +void php_memc_proto_handler_destroy (php_memc_proto_handler_t **ptr); + +zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t *h, zend_string *address); + +#endif + +#endif diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_session.c php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_session.c --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_session.c 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_session.c 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,554 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009-2010 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#include "php_memcached.h" +#include "php_memcached_private.h" +#include "php_memcached_session.h" + +#include "Zend/zend_smart_str_public.h" + +extern ZEND_DECLARE_MODULE_GLOBALS(php_memcached) + +#define REALTIME_MAXDELTA 60*60*24*30 + +ps_module ps_mod_memcached = { + PS_MOD_UPDATE_TIMESTAMP(memcached) +}; + +typedef struct { + zend_bool is_persistent; + zend_bool has_sasl_data; + zend_bool is_locked; + zend_string *lock_key; +} php_memcached_user_data; + +#ifndef MIN +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +static + int le_memc_sess; + +static +int s_memc_sess_list_entry(void) +{ + return le_memc_sess; +} + +static +void s_destroy_mod_data(memcached_st *memc) +{ + php_memcached_user_data *user_data = memcached_get_user_data(memc); + +#ifdef HAVE_MEMCACHED_SASL + if (user_data->has_sasl_data) { + memcached_destroy_sasl_auth_data(memc); + } +#endif + + memcached_free(memc); + pefree(memc, user_data->is_persistent); + pefree(user_data, user_data->is_persistent); +} + +ZEND_RSRC_DTOR_FUNC(php_memc_sess_dtor) +{ + if (res->ptr) { + s_destroy_mod_data((memcached_st *) res->ptr); + res->ptr = NULL; + } +} + +int php_memc_session_minit(int module_number) +{ + le_memc_sess = + zend_register_list_destructors_ex(NULL, php_memc_sess_dtor, "Memcached Sessions persistent connection", module_number); + + php_session_register_module(ps_memcached_ptr); + return SUCCESS; +} + +static +time_t s_adjust_expiration(zend_long expiration) +{ + if (expiration <= REALTIME_MAXDELTA) { + return expiration; + } else { + return time(NULL) + expiration; + } +} + +static +time_t s_lock_expiration() +{ + if (MEMC_SESS_INI(lock_expiration) > 0) { + return s_adjust_expiration(MEMC_SESS_INI(lock_expiration)); + } + else { + zend_long max_execution_time = zend_ini_long(ZEND_STRL("max_execution_time"), 0); + if (max_execution_time > 0) { + return s_adjust_expiration(max_execution_time); + } + } + return 0; +} + +static +time_t s_session_expiration(zend_long maxlifetime) +{ + if (maxlifetime > 0) { + return s_adjust_expiration(maxlifetime); + } + return 0; +} + +static +zend_bool s_lock_session(memcached_st *memc, zend_string *sid) +{ + memcached_return rc; + char *lock_key; + size_t lock_key_len; + time_t expiration; + zend_long wait_time, retries; + php_memcached_user_data *user_data = memcached_get_user_data(memc); + + lock_key_len = spprintf(&lock_key, 0, "lock.%s", sid->val); + expiration = s_lock_expiration(); + + wait_time = MEMC_SESS_INI(lock_wait_min); + retries = MEMC_SESS_INI(lock_retries); + + do { + rc = memcached_add(memc, lock_key, lock_key_len, "1", sizeof ("1") - 1, expiration, 0); + + switch (rc) { + + case MEMCACHED_SUCCESS: + user_data->lock_key = zend_string_init(lock_key, lock_key_len, user_data->is_persistent); + user_data->is_locked = 1; + break; + + case MEMCACHED_NOTSTORED: + case MEMCACHED_DATA_EXISTS: + if (retries > 0) { + usleep(wait_time * 1000); + wait_time = MIN(MEMC_SESS_INI(lock_wait_max), wait_time * 2); + } + break; + + default: + php_error_docref(NULL, E_WARNING, "Failed to write session lock: %s", memcached_strerror (memc, rc)); + break; + } + } while (!user_data->is_locked && retries-- > 0); + + efree(lock_key); + return user_data->is_locked; +} + +static +void s_unlock_session(memcached_st *memc) +{ + php_memcached_user_data *user_data = memcached_get_user_data(memc); + + if (user_data->is_locked) { + memcached_delete(memc, user_data->lock_key->val, user_data->lock_key->len, 0); + user_data->is_locked = 0; + zend_string_release (user_data->lock_key); + } +} + +static +zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) +{ +#define check_set_behavior(behavior, value) \ + int b = (behavior); \ + uint64_t v = (value); \ + if (v != memcached_behavior_get(memc, b)) { \ + memcached_return rc; \ + if ((rc = memcached_behavior_set(memc, b, v)) != MEMCACHED_SUCCESS) { \ + if (!silent) { \ + php_error_docref(NULL, E_WARNING, "failed to initialise session memcached configuration: %s", memcached_strerror(memc, rc)); \ + } \ + return 0; \ + } \ + } + + if (MEMC_SESS_INI(binary_protocol_enabled)) { + check_set_behavior(MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); + } + + if (MEMC_SESS_INI(consistent_hash_enabled)) { + check_set_behavior(MEMC_SESS_INI(consistent_hash_type), 1); + } + + if (MEMC_SESS_INI(server_failure_limit)) { + check_set_behavior(MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, MEMC_SESS_INI(server_failure_limit)); + } + + if (MEMC_SESS_INI(number_of_replicas)) { + check_set_behavior(MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, MEMC_SESS_INI(number_of_replicas)); + } + + if (MEMC_SESS_INI(randomize_replica_read_enabled)) { + check_set_behavior(MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1); + } + + if (MEMC_SESS_INI(remove_failed_servers_enabled)) { + check_set_behavior(MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1); + } + + if (MEMC_SESS_INI(connect_timeout)) { + check_set_behavior(MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, MEMC_SESS_INI(connect_timeout)); + } + + if (MEMC_SESS_STR_INI(prefix)) { + memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, MEMC_SESS_STR_INI(prefix)); + } + + if (MEMC_SESS_STR_INI(sasl_username) && MEMC_SESS_STR_INI(sasl_password)) { + php_memcached_user_data *user_data; + + if (!php_memc_init_sasl_if_needed()) { + return 0; + } + + check_set_behavior(MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); + + if (memcached_set_sasl_auth_data(memc, MEMC_SESS_STR_INI(sasl_username), MEMC_SESS_STR_INI(sasl_password)) == MEMCACHED_FAILURE) { + php_error_docref(NULL, E_WARNING, "failed to set memcached session sasl credentials"); + return 0; + } + user_data = memcached_get_user_data(memc); + user_data->has_sasl_data = 1; + } + +#undef check_set_behavior + + return 1; +} + +static +void *s_pemalloc_fn(const memcached_st *memc, size_t size, void *context) +{ + zend_bool *is_persistent = memcached_get_user_data(memc); + + return + pemalloc(size, *is_persistent); +} + +static +void s_pefree_fn(const memcached_st *memc, void *mem, void *context) +{ + zend_bool *is_persistent = memcached_get_user_data(memc); + + return + pefree(mem, *is_persistent); +} + +static +void *s_perealloc_fn(const memcached_st *memc, void *mem, const size_t size, void *context) +{ + zend_bool *is_persistent = memcached_get_user_data(memc); + + return + perealloc(mem, size, *is_persistent); +} + +static +void *s_pecalloc_fn(const memcached_st *memc, size_t nelem, const size_t elsize, void *context) +{ + zend_bool *is_persistent = memcached_get_user_data(memc); + + return + pecalloc(nelem, elsize, *is_persistent); +} + + +static +memcached_st *s_init_mod_data (const memcached_server_list_st servers, zend_bool is_persistent) +{ + void *buffer; + php_memcached_user_data *user_data; + memcached_st *memc; + + buffer = pecalloc(1, sizeof(memcached_st), is_persistent); + memc = memcached_create (buffer); + + if (!memc) { + php_error_docref(NULL, E_ERROR, "failed to allocate memcached structure"); + /* not reached */ + } + + memcached_set_memory_allocators(memc, s_pemalloc_fn, s_pefree_fn, s_perealloc_fn, s_pecalloc_fn, NULL); + + user_data = pecalloc(1, sizeof(php_memcached_user_data), is_persistent); + user_data->is_persistent = is_persistent; + user_data->has_sasl_data = 0; + user_data->lock_key = NULL; + user_data->is_locked = 0; + + memcached_set_user_data(memc, user_data); + memcached_server_push (memc, servers); + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1); + return memc; +} + +PS_OPEN_FUNC(memcached) +{ + memcached_st *memc = NULL; + char *plist_key = NULL; + size_t plist_key_len = 0; + + memcached_server_list_st servers; + + // Fail on incompatible PERSISTENT identifier (removed in php-memcached 3.0) + if (strstr(save_path, "PERSISTENT=")) { + php_error_docref(NULL, E_WARNING, "failed to parse session.save_path: PERSISTENT is replaced by memcached.sess_persistent = On"); + PS_SET_MOD_DATA(NULL); + return FAILURE; + } + + // First parse servers + servers = memcached_servers_parse(save_path); + + if (!servers) { + php_error_docref(NULL, E_WARNING, "failed to parse session.save_path"); + PS_SET_MOD_DATA(NULL); + return FAILURE; + } + + if (MEMC_SESS_INI(persistent_enabled)) { + zend_resource *le_p; + + plist_key_len = spprintf(&plist_key, 0, "memc-session:%s", save_path); + + if ((le_p = zend_hash_str_find_ptr(&EG(persistent_list), plist_key, plist_key_len)) != NULL) { + if (le_p->type == s_memc_sess_list_entry()) { + memc = (memcached_st *) le_p->ptr; + + if (!s_configure_from_ini_values(memc, 1)) { + // Remove existing plist entry + zend_hash_str_del(&EG(persistent_list), plist_key, plist_key_len); + memc = NULL; + } + else { + efree(plist_key); + PS_SET_MOD_DATA(memc); + memcached_server_list_free(servers); + return SUCCESS; + } + } + } + } + + memc = s_init_mod_data(servers, MEMC_SESS_INI(persistent_enabled)); + memcached_server_list_free(servers); + + if (!s_configure_from_ini_values(memc, 0)) { + if (plist_key) { + efree(plist_key); + } + s_destroy_mod_data(memc); + PS_SET_MOD_DATA(NULL); + return FAILURE; + } + + if (plist_key) { + zend_resource le; + + le.type = s_memc_sess_list_entry(); + le.ptr = memc; + + GC_SET_REFCOUNT(&le, 1); + + /* plist_key is not a persistent allocated key, thus we use str_update here */ + if (zend_hash_str_update_mem(&EG(persistent_list), plist_key, plist_key_len, &le, sizeof(le)) == NULL) { + php_error_docref(NULL, E_ERROR, "Could not register persistent entry for the memcached session"); + /* not reached */ + } + efree(plist_key); + } + PS_SET_MOD_DATA(memc); + return SUCCESS; +} + +PS_CLOSE_FUNC(memcached) +{ + php_memcached_user_data *user_data; + memcached_st *memc = PS_GET_MOD_DATA(); + + if (!memc) { + php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); + return FAILURE; + } + + user_data = memcached_get_user_data(memc); + + if (user_data->is_locked) { + s_unlock_session(memc); + } + + if (!user_data->is_persistent) { + s_destroy_mod_data(memc); + } + + PS_SET_MOD_DATA(NULL); + return SUCCESS; +} + +PS_READ_FUNC(memcached) +{ + char *payload = NULL; + size_t payload_len = 0; + uint32_t flags = 0; + memcached_return status; + memcached_st *memc = PS_GET_MOD_DATA(); + + if (!memc) { + php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); + return FAILURE; + } + + if (MEMC_SESS_INI(lock_enabled)) { + if (!s_lock_session(memc, key)) { + php_error_docref(NULL, E_WARNING, "Unable to clear session lock record"); + return FAILURE; + } + } + + payload = memcached_get(memc, key->val, key->len, &payload_len, &flags, &status); + + if (status == MEMCACHED_SUCCESS) { + zend_bool *is_persistent = memcached_get_user_data(memc); + *val = zend_string_init(payload, payload_len, 0); + pefree(payload, *is_persistent); + return SUCCESS; + } else if (status == MEMCACHED_NOTFOUND) { + *val = ZSTR_EMPTY_ALLOC(); + return SUCCESS; + } else { + php_error_docref(NULL, E_WARNING, "error getting session from memcached: %s", memcached_last_error_message(memc)); + return FAILURE; + } +} + +PS_WRITE_FUNC(memcached) +{ + zend_long retries = 1; + memcached_st *memc = PS_GET_MOD_DATA(); + time_t expiration = s_session_expiration(maxlifetime); + + if (!memc) { + php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); + return FAILURE; + } + + /* Set the number of write retry attempts to the number of replicas times the number of attempts to remove a server plus the initial write */ + if (MEMC_SESS_INI(remove_failed_servers_enabled)) { + zend_long replicas, failure_limit; + + replicas = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS); + failure_limit = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT); + + retries = 1 + replicas * (failure_limit + 1); + } + + do { + if (memcached_set(memc, key->val, key->len, val->val, val->len, expiration, 0) == MEMCACHED_SUCCESS) { + return SUCCESS; + } else { + php_error_docref(NULL, E_WARNING, "error saving session to memcached: %s", memcached_last_error_message(memc)); + } + } while (--retries > 0); + + return FAILURE; +} + +PS_DESTROY_FUNC(memcached) +{ + php_memcached_user_data *user_data; + memcached_st *memc = PS_GET_MOD_DATA(); + + if (!memc) { + php_error_docref(NULL, E_WARNING, "Session is not allocated, check session.save_path value"); + return FAILURE; + } + + memcached_delete(memc, key->val, key->len, 0); + user_data = memcached_get_user_data(memc); + + if (user_data->is_locked) { + s_unlock_session(memc); + } + return SUCCESS; +} + +PS_GC_FUNC(memcached) +{ + return SUCCESS; +} + +PS_CREATE_SID_FUNC(memcached) +{ + zend_string *sid; + memcached_st *memc = PS_GET_MOD_DATA(); + + if (!memc) { + sid = php_session_create_id(NULL); + } + else { + int retries = 3; + while (retries-- > 0) { + sid = php_session_create_id((void **) &memc); + + if (memcached_add (memc, sid->val, sid->len, NULL, 0, s_lock_expiration(), 0) == MEMCACHED_SUCCESS) { + break; + } + zend_string_release(sid); + sid = NULL; + } + } + return sid; +} + +PS_VALIDATE_SID_FUNC(memcached) +{ + memcached_st *memc = PS_GET_MOD_DATA(); + + if (php_memcached_exist(memc, key) == MEMCACHED_SUCCESS) { + return SUCCESS; + } else { + return FAILURE; + } +} + +PS_UPDATE_TIMESTAMP_FUNC(memcached) +{ + memcached_st *memc = PS_GET_MOD_DATA(); + time_t expiration = s_session_expiration(maxlifetime); + + if (php_memcached_touch(memc, key->val, key->len, expiration) == MEMCACHED_FAILURE) { + return FAILURE; + } + return SUCCESS; +} +/* }}} */ + diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_session.h php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_session.h --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/php_memcached_session.h 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/php_memcached_session.h 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,42 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009-2010 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_MEMCACHED_SESSION_H +#define PHP_MEMCACHED_SESSION_H + +/* session handler struct */ + +#include "ext/session/php_session.h" + +extern ps_module ps_mod_memcached; +#define ps_memcached_ptr &ps_mod_memcached + +PS_FUNCS_UPDATE_TIMESTAMP(memcached); + +PS_OPEN_FUNC(memcached); +PS_CLOSE_FUNC(memcached); +PS_READ_FUNC(memcached); +PS_WRITE_FUNC(memcached); +PS_DESTROY_FUNC(memcached); +PS_GC_FUNC(memcached); +PS_CREATE_SID_FUNC(memcached); +PS_VALIDATE_SID_FUNC(memcached); +PS_UPDATE_TIMESTAMP_FUNC(memcached); + +/* Called from php_memcached.c */ +int php_memc_session_minit(int module_number); + +#endif /* PHP_MEMCACHED_SESSION_H */ diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/README.markdown php-memcached-3.1.4+2.2.0/memcached-3.1.4/README.markdown --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/README.markdown 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/README.markdown 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,51 @@ +Build Status +------------ +[![Build Status](https://travis-ci.org/php-memcached-dev/php-memcached.png)](https://travis-ci.org/php-memcached-dev/php-memcached) + +Description +----------- +This is the [PECL memcached](https://pecl.php.net/package/memcached) extension, +using the libmemcached library to connect to memcached servers. + +[memcached](https://memcached.org) is a high-performance, distributed memory +object caching system, generic in nature, but intended for use in speeding up +dynamic web applications by alleviating database load. + +Building +-------- + + $ phpize + $ ./configure + $ make + $ make test + +Dependencies +------------ + +php-memcached 3.x: +* Supports PHP 7.0 - 7.4. +* Requires libmemcached 1.x or higher. +* Optionally supports igbinary 2.0 or higher. +* Optionally supports msgpack 2.0 or higher. + +php-memcached 2.x: +* Supports PHP 5.2 - 5.6. +* Requires libmemcached 0.44 or higher. +* Optionally supports igbinary 1.0 or higher. +* Optionally supports msgpack 0.5 or higher. + +[libmemcached](http://libmemcached.org/libMemcached.html) version 1.0.18 or +higher is recommended for best performance and compatibility with memcached +servers. + +[igbinary](https://github.com/igbinary/igbinary) is a faster and more compact +binary serializer for PHP data structures. When installing php-memcached from +source code, the igbinary module must be installed first so that php-memcached +can access its C header files. Load both modules in your `php.ini` at runtime +to begin using igbinary. + +[msgpack](https://msgpack.org) is a faster and more compact data structure +representation that is interoperable with msgpack implementations for other +languages. When installing php-memcached from source code, the msgpack module +must be installed first so that php-memcached can access its C header files. +Load both modules in your `php.ini` at runtime to begin using msgpack. diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/001.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/001.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/001.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/001.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,10 @@ +--TEST-- +Check for memcached presence +--SKIPIF-- + +--FILE-- + +--EXPECT-- +memcached extension is available diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/add.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/add.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/add.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/add.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,21 @@ +--TEST-- +Memcached::add() +--SKIPIF-- + +--FILE-- +delete('foo'); +var_dump($m->add('foo', 1, 60)); +var_dump($m->get('foo')); +var_dump($m->add('foo', 2, 60)); +var_dump($m->get('foo')); + + +--EXPECT-- +bool(true) +int(1) +bool(false) +int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/append.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/append.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/append.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/append.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,30 @@ +--TEST-- +Memcached::append() +--SKIPIF-- + +--FILE-- +delete('foo'); +$m->setOption(Memcached::OPT_COMPRESSION, true); +var_dump($m->append('foo', 'a')); +echo error_get_last()["message"], "\n"; + +$m->setOption(Memcached::OPT_COMPRESSION, false); +$m->delete('foo'); +var_dump($m->append('foo', 'a')); +var_dump($m->get('foo')); +$m->set('foo', 'a'); +var_dump($m->append('foo', 'b')); +var_dump($m->get('foo')); + +--EXPECTF-- +NULL +%s: cannot append/prepend with compression turned on +bool(false) +bool(false) +bool(true) +string(2) "ab" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bad_construct.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bad_construct.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bad_construct.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bad_construct.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,32 @@ +--TEST-- +Memcached construct with bad arguments +--SKIPIF-- + +--FILE-- +setOption (Memcached::OPT_BINARY_PROTOCOL, true)); + +echo "OK" . PHP_EOL; + +--EXPECTF-- +Warning: Memcached::__construct() expects parameter 1 to be string, object given in %s on line 3 +Memcached::__construct() expects parameter 1 to be string, object given +object(Memcached)#1 (0) { +} + +Warning: Memcached::setOption(): Memcached constructor was not called in %s on line 14 +NULL +OK + diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_16084.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_16084.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_16084.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_16084.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,20 @@ +--TEST-- +Memcached: Bug #16084 (Crash when addServers is called with an associative array) +--SKIPIF-- + +--FILE-- + array ( 'KEYHERE' => 'localhost', 11211, 3 ), ); +$m = new memcached(); +var_dump($m->addServers($servers)); +$list = $m->getServerList(); + +var_dump ($list[0]["host"], $list[0]["port"]); +echo "OK"; + +?> +--EXPECT-- +bool(true) +string(9) "localhost" +int(11211) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_16959.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_16959.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_16959.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_16959.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,56 @@ +--TEST-- +Memcached: Bug #16959 (getMulti + BINARY_PROTOCOL problem) +--SKIPIF-- + +--FILE-- + true + )); + +$cache->set('key_0', 'value0'); +$cache->set('key_0_additional', 'value0_additional'); + +// -------------- NORMAL +echo "NORMAL\n"; +$keys = array( 'key_0', 'key_0_additional' ); +$values = $cache->getMulti($keys); +echo $cache->getResultMessage(), "\n"; +echo "Values:\n"; +foreach ($values as $k => $v) { + var_dump($k); + var_dump($v); + var_dump($values[$k]); +} +// --------------- REVERSED KEY ORDER +echo "REVERSED KEY ORDER\n"; +$keys = array( 'key_0_additional', 'key_0' ); +$values = $cache->getMulti($keys); +echo $cache->getResultMessage(), "\n"; +echo "Values:\n"; +foreach ($values as $k => $v) { + var_dump($k); + var_dump($v); + var_dump($values[$k]); +} + +--EXPECT-- +NORMAL +SUCCESS +Values: +string(5) "key_0" +string(6) "value0" +string(6) "value0" +string(16) "key_0_additional" +string(17) "value0_additional" +string(17) "value0_additional" +REVERSED KEY ORDER +SUCCESS +Values: +string(16) "key_0_additional" +string(17) "value0_additional" +string(17) "value0_additional" +string(5) "key_0" +string(6) "value0" +string(6) "value0" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_17137.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_17137.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_17137.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_17137.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,39 @@ +--TEST-- +Change prefix, pecl bug #17137 +--SKIPIF-- + +--FILE-- + true, + Memcached::OPT_PREFIX_KEY => 'prefix1', + )); + +$memcache2 = memc_get_instance (array ( + Memcached::OPT_BINARY_PROTOCOL => true, + Memcached::OPT_PREFIX_KEY => 'prefix2', + )); + +var_dump($memcache->getOption(Memcached::OPT_PREFIX_KEY)); + +var_dump($memcache->set('test', "val_prefix1", 120)); +var_dump($memcache->get('test')); + + +var_dump($memcache2->getOption(Memcached::OPT_PREFIX_KEY)); + +var_dump($memcache2->set('test', "val_prefix2", 120)); +var_dump($memcache2->get('test')); + + +var_dump($memcache->get('test')); +--EXPECT-- +string(7) "prefix1" +bool(true) +string(11) "val_prefix1" +string(7) "prefix2" +bool(true) +string(11) "val_prefix2" +string(11) "val_prefix1" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_18639.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_18639.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/bug_18639.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/bug_18639.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,22 @@ +--TEST-- +Memcached::getServerByKey(): Bug pecl#18639 (Segfault in getServerByKey) +--SKIPIF-- + +--FILE-- +set('test', 'test1')); +var_dump($m->getServerByKey('1')); + +--EXPECTF-- +bool(true) +array(3) { + ["host"]=> + string(9) "%s" + ["port"]=> + int(%d) + ["weight"]=> + int(%r[01]%r) +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/cachecallback.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/cachecallback.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/cachecallback.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/cachecallback.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,63 @@ +--TEST-- +Memcached::get() with cache callback +--SKIPIF-- + +--FILE-- +delete($first_key); +$m->delete($second_key); +$m->delete($third_key); + +var_dump ( +$m->get ($first_key, function (Memcached $memc, $key, &$value, &$expiration) { + $value = "hello"; + $expiration = 10; + return true; + }) +); + +var_dump ($m->get ($first_key)); + +var_dump ( +$m->get ($second_key, function (Memcached $memc, $key, &$value, &$expiration) { + $value = "hello"; + $expiration = 10; + return false; + }) +); + +var_dump ($m->get ($second_key)); + +try { + $m->get ($third_key, function (Memcached $memc, $key, &$value, &$expiration) { + $value = "hello"; + $expiration = 10; + throw new Exception ('this is a test'); + return true; + }); +} catch (Exception $e) { + echo 'Got exception' . PHP_EOL; +} + +var_dump ($m->get ($third_key)); + + +echo "OK" . PHP_EOL; + +--EXPECT-- +string(5) "hello" +string(5) "hello" +bool(false) +bool(false) +Got exception +bool(false) +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/callback_exception_2.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/callback_exception_2.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/callback_exception_2.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/callback_exception_2.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,54 @@ +--TEST-- +Callback initializer throws and dies +--SKIPIF-- + +--FILE-- +isPersistent()); + throw new RuntimeException('Cb exception'); +} + +function init_cb_die($m, $id) { + echo "ran quitting cb\n"; + die("quit in cb"); +} + +error_reporting(0); + +echo "cb with exception\n"; +try { + $m1 = new Memcached(null, 'init_cb'); +} catch (RuntimeException $e) { + echo $e->getMessage(), "\n"; +} + +echo "cb persistent with exception\n"; +try { + $m2 = new Memcached('foo', 'init_cb'); +} catch (RuntimeException $e) { + echo $e->getMessage(), "\n"; +} + +echo "cb persistent dies\n"; +try { + $m3 = new Memcached('bar', 'init_cb_die'); +} catch (RuntimeException $e) { + echo $e->getMessage(), "\n"; +} +echo "not run\n"; + +--EXPECT-- +cb with exception +ran throwing cb +bool(false) +Cb exception +cb persistent with exception +ran throwing cb +bool(true) +Cb exception +cb persistent dies +ran quitting cb +quit in cb diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/callback_exception.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/callback_exception.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/callback_exception.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/callback_exception.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,54 @@ +--TEST-- +make sure that callback exception behaves correctly +--SKIPIF-- + +--FILE-- + +--EXPECT-- +success +success +empty_cb called +success +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/cas_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/cas_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/cas_multi.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/cas_multi.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,58 @@ +--TEST-- +Memcached multi fetch cas & set cas +--SKIPIF-- + +--FILE-- + 1, + 'cas_test_2' => 2, +); + +foreach ($data as $key => $v) { + $m->delete($key); +} + +$m->setMulti($data, 10); +$actual = $m->getMulti(array_keys($data), Memcached::GET_EXTENDED); + +foreach ($actual as $key => $v) { + if (is_null($v['cas'])) { + echo "missing cas token(s)\n"; + echo "data: "; + var_dump($data); + echo "actual data: "; + var_dump($actual); + return; + } + + $v = $m->cas($v['cas'], $key, 11); + if (!$v) { + echo "Error setting key: $key value: 11 with CAS: ", $v['cas'], "\n"; + return; + } + $v = $m->get($key); + if ($v !== 11) { + echo "Wanted $key to be 11, value is: "; + var_dump($v); + return; + } +} + +if (array_keys($actual) !== array_keys($data)) { + echo "missing value(s)\n"; + echo "data :"; + var_dump($data); + echo "actual data: "; + var_dump($actual); + return; +} + +echo "OK\n"; + +?> +--EXPECT-- +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/cas.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/cas.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/cas.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/cas.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,23 @@ +--TEST-- +Memcached fetch cas & set cas +--SKIPIF-- + +--FILE-- +delete('cas_test'); + +$m->set('cas_test', 'hello'); +$cas_token = $m->get('cas_test', null, Memcached::GET_EXTENDED)['cas']; + +$v = $m->cas($cas_token, 'cas_test', 0); +if ($v != true) { + echo "CAS failed"; +} + +echo "OK\n"; +?> +--EXPECT-- +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/check_if_persistent.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/check_if_persistent.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/check_if_persistent.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/check_if_persistent.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,37 @@ +--TEST-- +Check if persistent object is persistent +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_PREFIX_KEY, "foo_"); + +var_dump($m1->isPersistent()); + +$m1 = new Memcached('id1'); +var_dump($m1->isPersistent()); + +$m2 = new Memcached('id1'); +var_dump($m2->isPersistent()); +// this change affects $m1 +$m2->setOption(Memcached::OPT_PREFIX_KEY, "bar_"); + +$m3 = new Memcached('id2'); +var_dump($m3->isPersistent()); + +$m3 = new Memcached(); +var_dump($m3->isPersistent()); + +// objects have the same resource, but they are not the same object. +var_dump($m1 === $m2); +var_dump($m1->getOption(Memcached::OPT_PREFIX_KEY)); +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +bool(false) +string(4) "bar_" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/check_if_pristine.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/check_if_pristine.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/check_if_pristine.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/check_if_pristine.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,31 @@ +--TEST-- +Check if persistent object is new or an old persistent one +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_PREFIX_KEY, "foo_"); + +var_dump($m1->isPristine()); + +$m1 = new Memcached('id1'); +var_dump($m1->isPristine()); + +$m2 = new Memcached('id1'); +var_dump($m2->isPristine()); +// this change affects $m1 +$m2->setOption(Memcached::OPT_PREFIX_KEY, "bar_"); + +$m3 = new Memcached('id2'); +var_dump($m3->isPristine()); + +$m3 = new Memcached(); +var_dump($m3->isPristine()); +--EXPECT-- +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/clone.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/clone.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/clone.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/clone.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,18 @@ +--TEST-- +Test cloning +--SKIPIF-- + +--FILE-- + +--FILE-- +setOption(Memcached::OPT_COMPRESSION, false); + } else { + $m->setOption(Memcached::OPT_COMPRESSION, true); + $m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($set_compression)); + } + + $m->set($key, $value, 1800); + + $value_back = $m->get($key); + var_dump($value === $value_back); +} + +fetch_with_compression($m, 'hello01', $data, 'zlib', 1.3, 4); +fetch_with_compression($m, 'hello02', $data, 'fastlz', 1.3, 4); +fetch_with_compression($m, 'hello03', $data, '', 1.3, 4); +fetch_with_compression($m, 'hello04', $short_data, 'zlib', 1.3, 4); +fetch_with_compression($m, 'hello05', $short_data, 'fastlz', 1.3, 4); +fetch_with_compression($m, 'hello06', $short_data, '', 1.3, 4); +fetch_with_compression($m, 'hello11', $data, 'zlib', 0.3, 4); +fetch_with_compression($m, 'hello12', $data, 'fastlz', 0.3, 4); +fetch_with_compression($m, 'hello13', $data, '', 0.3, 4); +fetch_with_compression($m, 'hello14', $short_data, 'zlib', 0.3, 4); +fetch_with_compression($m, 'hello15', $short_data, 'fastlz', 0.3, 4); +fetch_with_compression($m, 'hello16', $short_data, '', 0.3, 4); +fetch_with_compression($m, 'hello21', $data, 'zlib', 1.3, 2000); +fetch_with_compression($m, 'hello22', $data, 'fastlz', 1.3, 2000); +fetch_with_compression($m, 'hello23', $data, '', 1.3, 2000); +fetch_with_compression($m, 'hello24', $short_data, 'zlib', 1.3, 2000); +fetch_with_compression($m, 'hello25', $short_data, 'fastlz', 1.3, 2000); +fetch_with_compression($m, 'hello26', $short_data, '', 1.3, 2000); +fetch_with_compression($m, 'hello31', $data, 'zlib', 0.3, 2000); +fetch_with_compression($m, 'hello32', $data, 'fastlz', 0.3, 2000); +fetch_with_compression($m, 'hello33', $data, '', 0.3, 2000); +fetch_with_compression($m, 'hello34', $short_data, 'zlib', 0.3, 2000); +fetch_with_compression($m, 'hello35', $short_data, 'fastlz', 0.3, 2000); +fetch_with_compression($m, 'hello36', $short_data, '', 0.3, 2000); +?> +--EXPECT-- +len=[4877] set=[zlib] factor=[1.3] threshold=[4] +bool(true) +len=[4877] set=[fastlz] factor=[1.3] threshold=[4] +bool(true) +len=[4877] set=[] factor=[1.3] threshold=[4] +bool(true) +len=[7] set=[zlib] factor=[1.3] threshold=[4] +bool(true) +len=[7] set=[fastlz] factor=[1.3] threshold=[4] +bool(true) +len=[7] set=[] factor=[1.3] threshold=[4] +bool(true) +len=[4877] set=[zlib] factor=[0.3] threshold=[4] +bool(true) +len=[4877] set=[fastlz] factor=[0.3] threshold=[4] +bool(true) +len=[4877] set=[] factor=[0.3] threshold=[4] +bool(true) +len=[7] set=[zlib] factor=[0.3] threshold=[4] +bool(true) +len=[7] set=[fastlz] factor=[0.3] threshold=[4] +bool(true) +len=[7] set=[] factor=[0.3] threshold=[4] +bool(true) +len=[4877] set=[zlib] factor=[1.3] threshold=[2000] +bool(true) +len=[4877] set=[fastlz] factor=[1.3] threshold=[2000] +bool(true) +len=[4877] set=[] factor=[1.3] threshold=[2000] +bool(true) +len=[7] set=[zlib] factor=[1.3] threshold=[2000] +bool(true) +len=[7] set=[fastlz] factor=[1.3] threshold=[2000] +bool(true) +len=[7] set=[] factor=[1.3] threshold=[2000] +bool(true) +len=[4877] set=[zlib] factor=[0.3] threshold=[2000] +bool(true) +len=[4877] set=[fastlz] factor=[0.3] threshold=[2000] +bool(true) +len=[4877] set=[] factor=[0.3] threshold=[2000] +bool(true) +len=[7] set=[zlib] factor=[0.3] threshold=[2000] +bool(true) +len=[7] set=[fastlz] factor=[0.3] threshold=[2000] +bool(true) +len=[7] set=[] factor=[0.3] threshold=[2000] +bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/compression_types.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/compression_types.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/compression_types.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/compression_types.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,76 @@ +--TEST-- +Memcached compression test +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_COMPRESSION, false); + } else { + $m->setOption(Memcached::OPT_COMPRESSION, true); + $m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($set_compression)); + } + + $m->set($key, $value, 1800); + + if (!$get_compression) { + $m->setOption(Memcached::OPT_COMPRESSION, true); + } else { + $m->setOption(Memcached::OPT_COMPRESSION, true); + $m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($get_compression)); + } + + $value_back = $m->get($key); + var_dump($value === $value_back); +} + +fetch_with_compression($m, 'hello1', $data, 'zlib', 'zlib'); +fetch_with_compression($m, 'hello2', $data, 'zlib', 'fastlz'); +fetch_with_compression($m, 'hello3', $data, 'fastlz', 'fastlz'); +fetch_with_compression($m, 'hello4', $data, 'fastlz', 'zlib'); +fetch_with_compression($m, 'hello5', $data, '', 'zlib'); +fetch_with_compression($m, 'hello6', $data, '', 'fastlz'); +fetch_with_compression($m, 'hello7', $data, 'zlib', ''); +fetch_with_compression($m, 'hello8', $data, 'fastlz', ''); +fetch_with_compression($m, 'hello9', $data, '', ''); +?> +--EXPECT-- +set=[zlib] get=[zlib] +bool(true) +set=[zlib] get=[fastlz] +bool(true) +set=[fastlz] get=[fastlz] +bool(true) +set=[fastlz] get=[zlib] +bool(true) +set=[] get=[zlib] +bool(true) +set=[] get=[fastlz] +bool(true) +set=[zlib] get=[] +bool(true) +set=[fastlz] get=[] +bool(true) +set=[] get=[] +bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/config.inc php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/config.inc --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/config.inc 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/config.inc 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,73 @@ +setOptions ($opts) == false) + echo "Failed to set options" . PHP_EOL; + + $memcached->addServer($host, $port); + if ($memcached->flush() === false) { + return NULL; + } + return $memcached; +} + +function memc_get_instance (array $opts = array (), $persistent_id = null) +{ + return memc_create_instance(MEMC_SERVER_HOST, MEMC_SERVER_PORT, $opts, $persistent_id); +} + +function memc_get_sasl_instance (array $opts = array (), $persistent_id = null) +{ + return memc_create_instance(MEMC_SASL_SERVER_HOST, MEMC_SASL_SERVER_PORT, $opts, $persistent_id); +} + +function memc_run_test ($test_function, $options = array ()) +{ + foreach ($options as $option_set) { + $memc = memc_get_instance ($option_set ['options']); + $test_function ($memc, $option_set); + } + echo "TEST DONE" . PHP_EOL; +} + +function memc_create_combinations ($name, $serializer, $ignore_object_type = false) +{ + return array ( + array ( + 'title' => "$name serializer, ascii protocol", + 'options' => array ( + Memcached::OPT_SERIALIZER => $serializer + ), + 'ignore_object_type' => $ignore_object_type + ), + array ( + 'title' => "$name serializer, binary protocol", + 'options' => array ( + Memcached::OPT_BINARY_PROTOCOL => true, + Memcached::OPT_SERIALIZER => $serializer + ), + 'ignore_object_type' => $ignore_object_type + ), + ); +} + +function memc_get_version($memc) { + $version = $memc->getVersion(); + return array_pop($version); +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/conf_persist.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/conf_persist.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/conf_persist.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/conf_persist.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,35 @@ +--TEST-- +Conf settings persist. +--SKIPIF-- + +--FILE-- + 'php' +), 'id1'); + +$m1->set('foo', 'bar'); + +for ($i = 1000; $i > 0; $i--) { + $m1 = new Memcached('id1'); + $rv = $m1->get('foo'); + if ($rv !== 'bar') { + echo "Expected bar got:"; + var_dump($rv); + die(); + } + + $prefix = $m1->getOption(Memcached::OPT_PREFIX_KEY); + if ($prefix !== 'php') { + echo "Expected prefix php got:"; + var_dump($prefix); + die(); + } +} + +echo "OK\n"; + +?> +--EXPECT-- +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/construct_persistent.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/construct_persistent.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/construct_persistent.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/construct_persistent.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,20 @@ +--TEST-- +persistent memcached connection +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_PREFIX_KEY, 'php'); +var_dump($m1->getOption(Memcached::OPT_PREFIX_KEY)); + +$m2 = new Memcached('id1'); +var_dump($m1->getOption(Memcached::OPT_PREFIX_KEY)); + +$m3 = new Memcached(); +var_dump($m3->getOption(Memcached::OPT_PREFIX_KEY)); +?> +--EXPECT-- +string(3) "php" +string(3) "php" +string(0) "" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/construct.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/construct.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/construct.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/construct.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,11 @@ +--TEST-- +Memcached constructor +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Memcached diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/default_behavior.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/default_behavior.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/default_behavior.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/default_behavior.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,32 @@ +--TEST-- +Default behaviors +--SKIPIF-- + +--FILE-- +getOption(Memcached::OPT_DISTRIBUTION) == Memcached::DISTRIBUTION_MODULA); +var_dump ($m->getOption(Memcached::OPT_BINARY_PROTOCOL) == false); +var_dump ($m->getOption(Memcached::OPT_CONNECT_TIMEOUT) != 0); + +ini_set('memcached.default_consistent_hash', true); +ini_set('memcached.default_binary_protocol', true); +ini_set('memcached.default_connect_timeout', 1212); + +$m = new Memcached(); +var_dump ($m->getOption(Memcached::OPT_DISTRIBUTION) == Memcached::DISTRIBUTION_CONSISTENT); +var_dump ($m->getOption(Memcached::OPT_BINARY_PROTOCOL) == true); +var_dump ($m->getOption(Memcached::OPT_CONNECT_TIMEOUT) == 1212); + +echo "OK"; + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/deleted.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/deleted.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/deleted.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/deleted.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,25 @@ +--TEST-- +Memcached store & fetch type correctness +--SKIPIF-- + +--FILE-- +set('eisaleeoo', "foo"); +$m->delete('eisaleeoo'); +$v = $m->get('eisaleeoo'); + +if ($v !== Memcached::GET_ERROR_RETURN_VALUE) { + echo "Wanted: "; + var_dump(Memcached::GET_ERROR_RETURN_VALUE); + echo "Got: "; + var_dump($v); +} + +echo "OK\n"; + +?> +--EXPECT-- +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/deletemulti.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/deletemulti.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/deletemulti.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/deletemulti.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,82 @@ +--TEST-- +Delete multi +--SKIPIF-- + +--FILE-- + 'foo-data', + 'bar' => 'bar-data', + 'baz' => 'baz-data', + 'lol' => 'lol-data', + 'kek' => 'kek-data', +); + +$keys = array_keys($data); + +$null = null; +$m->setMulti($data, 3600); + +/* Check that all keys were stored */ +var_dump(has_all_keys($keys, $m->getMulti($keys))); + +/* Check that all keys get deleted */ +$deleted = $m->deleteMulti($keys); +var_dump(has_all_keys($keys, $deleted, true)); + +/* Try to get the deleted keys, should give empty array */ +var_dump($m->getMulti($keys)); + +/* ---- same tests for byKey variants ---- */ +$m->setMultiByKey("hi", $data, 3600); + +var_dump(has_all_keys($keys, $m->getMultiByKey('hi', $keys))); + +/* Check that all keys get deleted */ +$deleted = $m->deleteMultiByKey('hi', $keys); +var_dump(has_all_keys($keys, $deleted, true)); + +/* Try to get the deleted keys, should give empty array */ +var_dump($m->getMultiByKey('hi', $keys)); + +/* Test deleting non-existent keys */ +$keys = array(); +$keys[] = "nothere"; +$keys[] = "nothere2"; + +$retval = $m->deleteMulti($keys); + +foreach ($retval as $key => $value) { + if ($value === Memcached::RES_NOTFOUND) { + echo "$key NOT FOUND\n"; + } +} + + +?> +--EXPECT-- +bool(true) +bool(true) +array(0) { +} +bool(true) +bool(true) +array(0) { +} +nothere NOT FOUND +nothere2 NOT FOUND \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/deletemultitypes.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/deletemultitypes.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/deletemultitypes.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/deletemultitypes.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,25 @@ +--TEST-- +Delete multi key types +--SKIPIF-- + +--FILE-- +deleteMulti($keys); +array_walk($keys, 'dump_types'); + +?> +--EXPECT-- +integer +string +integer +string \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/expire.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/expire.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/expire.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/expire.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,71 @@ +--TEST-- +Memcached store, fetch & touch expired key +--XFAIL-- +https://code.google.com/p/memcached/issues/detail?id=275 +--SKIPIF-- + +--FILE-- +set($key, "foo", 2); + $v = $m->get($key); + if (!$set || $v != 'foo') { + echo "Error setting key to \"foo\" with 2s expiry.\n"; + return; + } + + sleep(1); + $res = $m->touch($key, 2); + $v = $m->get($key); + + if(!$res || $v != 'foo') { + echo "Error touching key for another 2s expiry.\n"; + var_dump($res); + var_dump($m->getResultMessage()); + var_dump($v); + return; + } + + sleep(3); + $v = $m->get($key); + + if ($v !== Memcached::GET_ERROR_RETURN_VALUE) { + echo "Wanted:\n"; + var_dump(Memcached::GET_ERROR_RETURN_VALUE); + echo "from get of expired value. Got:\n"; + var_dump($v); + return; + } + echo "All OK" . PHP_EOL; +} + +$m = memc_get_instance (array ( + Memcached::OPT_BINARY_PROTOCOL => true + )); + +echo '-- binary protocol' . PHP_EOL; +run_expiry_test ($m); + +$m = memc_get_instance (); + +echo '-- text protocol' . PHP_EOL; +run_expiry_test ($m); + +echo "DONE TEST\n"; +?> +--EXPECT-- +-- binary protocol +All OK +-- text protocol +All OK +DONE TEST diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/flush_buffers.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/flush_buffers.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/flush_buffers.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/flush_buffers.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,32 @@ +--TEST-- +Test flushing buffers +--SKIPIF-- + +--FILE-- + 1, + Memcached::OPT_BUFFER_WRITES => 1, + )); + +$key = uniqid ('flush_key_'); + +var_dump ($m->set($key, 'test_val')); + +$m2 = memc_get_instance (); + +var_dump ($m2->get ($key)); +var_dump ($m->flushBuffers ()); +sleep (1); +var_dump ($m2->get ($key)); + +echo "OK" . PHP_EOL; +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +string(8) "test_val" +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getdelayed.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getdelayed.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getdelayed.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getdelayed.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,82 @@ +--TEST-- +Memcached getDelayed callback +--SKIPIF-- + +--FILE-- + 'foo-data', + 'bar' => 'bar-data', + 'baz' => 'baz-data', + 'lol' => 'lol-data', + 'kek' => 'kek-data', +); + +foreach ($data as $k => $v) { + $m->set($k, $v, 3600); +} + +function myfunc() { + $datas = func_get_args(); + if (isset($datas[1])) { + var_dump($datas[1]); + } +} + +$m->getDelayed(array_keys($data), true, 'myfunc'); + +?> +--EXPECTF-- +array(4) { + ["key"]=> + string(3) "foo" + ["value"]=> + string(8) "foo-data" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) +} +array(4) { + ["key"]=> + string(3) "bar" + ["value"]=> + string(8) "bar-data" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) +} +array(4) { + ["key"]=> + string(3) "baz" + ["value"]=> + string(8) "baz-data" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) +} +array(4) { + ["key"]=> + string(3) "lol" + ["value"]=> + string(8) "lol-data" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) +} +array(4) { + ["key"]=> + string(3) "kek" + ["value"]=> + string(8) "kek-data" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) +} \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/get_flags.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/get_flags.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/get_flags.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/get_flags.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,65 @@ +--TEST-- +Memcached::get/getMulti() flags +--SKIPIF-- + +--FILE-- +set ($key1, 'hello1', 20); +$m->set ($key2, 'hello2', 20); + +$value = $m->get($key1); +$extended = $m->get($key1, null, Memcached::GET_EXTENDED); + +var_dump ($value); +var_dump ($extended); + +$values = $m->getMulti(array ($key1, $key2), Memcached::GET_PRESERVE_ORDER); +$extended = $m->getMulti(array ($key1, $key2), Memcached::GET_EXTENDED | Memcached::GET_PRESERVE_ORDER); + +var_dump ($values); +var_dump ($extended); +echo "OK"; + +--EXPECTF-- +string(6) "hello1" +array(3) { + ["value"]=> + string(6) "hello1" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) +} +array(2) { + ["memc.test.%s"]=> + string(6) "hello1" + ["memc.test.%s"]=> + string(6) "hello2" +} +array(2) { + ["memc.test.%s"]=> + array(3) { + ["value"]=> + string(6) "hello1" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) + } + ["memc.test.%s"]=> + array(3) { + ["value"]=> + string(6) "hello2" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) + } +} +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getmulti.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getmulti.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getmulti.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getmulti.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,47 @@ +--TEST-- +Memcached::getMulti() +--SKIPIF-- + +--FILE-- +setMulti($data)); + +$keys = array_keys($data); +$keys['last'] = new Foo(); + +$v = $m->getMulti($keys); +var_dump(is_array($v)); +var_dump($m->getResultCode() == Memcached::RES_SUCCESS); +if (is_array($v)) { + foreach ($v as $key => $value) { + if (!isset($data[$key]) or $value !== $data[$key]) { + echo "mismatch \$data['$key'] = \n"; + var_dump($data[$key]); + var_dump($value); + } + } +} else { + echo "Result not an array\n"; +} + +var_dump(is_object($keys['last'])); + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getserverbykey.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getserverbykey.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getserverbykey.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getserverbykey.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,59 @@ +--TEST-- +Memcached::getServerByKey() +--SKIPIF-- + +--FILE-- +getServerByKey("a")); + +$m->addServer('localhost', 11211, 1); +$m->addServer('localhost', 11212, 1); +$m->addServer('localhost', 11213, 1); +$m->addServer('localhost', 11214, 1); +$m->addServer('localhost', 11215, 1); + +var_dump($m->getServerByKey("")); +echo $m->getResultMessage(), "\n"; +var_dump($m->getServerByKey("a")); +var_dump($m->getServerByKey("b")); +var_dump($m->getServerByKey("c")); +var_dump($m->getServerByKey("d")); +--EXPECTF-- +bool(false) +bool(false) +A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE +array(%d) { + ["host"]=> + string(%d) "%s" + ["port"]=> + int(%d) + ["weight"]=> + int(0) +} +array(%d) { + ["host"]=> + string(%d) "%s" + ["port"]=> + int(%d) + ["weight"]=> + int(0) +} +array(%d) { + ["host"]=> + string(%d) "%s" + ["port"]=> + int(%d) + ["weight"]=> + int(0) +} +array(%d) { + ["host"]=> + string(%d) "%s" + ["port"]=> + int(%d) + ["weight"]=> + int(0) +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getserverlist.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getserverlist.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/getserverlist.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/getserverlist.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,65 @@ +--TEST-- +getServerList +--SKIPIF-- + +--FILE-- + array ( 'KEYHERE' => 'localhost', 11211, 3 ), ); +$m = new memcached(); +var_dump($m->getServerList()); +$m->addServers($servers); +var_dump($m->getServerList()); +$m->addServers($servers); +var_dump($m->getServerList()); +$m = new memcached(); +$m->addServer('127.0.0.1', 11211); +var_dump($m->getServerList()); + +echo "OK"; +?> +--EXPECT-- +array(0) { +} +array(1) { + [0]=> + array(3) { + ["host"]=> + string(9) "localhost" + ["port"]=> + int(11211) + ["type"]=> + string(3) "TCP" + } +} +array(2) { + [0]=> + array(3) { + ["host"]=> + string(9) "localhost" + ["port"]=> + int(11211) + ["type"]=> + string(3) "TCP" + } + [1]=> + array(3) { + ["host"]=> + string(9) "localhost" + ["port"]=> + int(11211) + ["type"]=> + string(3) "TCP" + } +} +array(1) { + [0]=> + array(3) { + ["host"]=> + string(9) "127.0.0.1" + ["port"]=> + int(11211) + ["type"]=> + string(3) "TCP" + } +} +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_155.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_155.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_155.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_155.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,48 @@ +--TEST-- +Test for bug 155 +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_BINARY_PROTOCOL, true); +$m->addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); + +$key = 'bug_155_' . uniqid(); + +$m->set ($key, 'test', time() + 86400); + +$m->get ($key); +echo "GET: " . $m->getResultMessage() . PHP_EOL; + +$m->touch ($key, time() + 86400); +echo "TOUCH: " . $m->getResultMessage() . PHP_EOL; + +$m->touch ($key, time() + 86400); +echo "TOUCH: " . $m->getResultMessage() . PHP_EOL; + +$m->get ($key); +echo "GET: " . $m->getResultMessage() . PHP_EOL; + +$m->get ($key); +echo "GET: " . $m->getResultMessage() . PHP_EOL; + +echo "DONE" . PHP_EOL; + +--EXPECT-- +GET: SUCCESS +TOUCH: SUCCESS +TOUCH: SUCCESS +GET: SUCCESS +GET: SUCCESS +DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_21.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_21.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_21.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_21.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,36 @@ +--TEST-- +Test for Github issue 21 +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_BINARY_PROTOCOL, true); + +$m->addServers($newServers); + +$d = $m->get('foo'); + +$m->set('counter', 5); +$n = $m->decrement('counter'); +var_dump($n); + +$n = $m->decrement('counter', 10); +var_dump($n); + +var_dump($m->get('counter')); + +$m->set('counter', 'abc'); +$n = $m->increment('counter'); +var_dump($n); +?> +--EXPECT-- +int(4) +int(0) +int(0) +bool(false) \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_77.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_77.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_77.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_77.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,30 @@ +--TEST-- +Test for Github issue #77 +--SKIPIF-- + +--FILE-- +touch($key, 5); +var_dump ($mc->getResultCode() == Memcached::RES_NOTFOUND); +$mc->set($key, 1, 5); + +$mc->set($key, 1, 5); +var_dump ($mc->getResultCode() == Memcached::RES_SUCCESS); + +echo "OK\n"; + +?> +--EXPECT-- +bool(true) +bool(true) +OK + diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_90.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_90.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_90.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_90.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,91 @@ +--TEST-- +Test for GH #90 +--SKIPIF-- + +--FILE-- + true + )); + +// Create a key for use as a lock. If this key already exists, wait till it doesn't exist. +{ + $key = 'LockKey'; + $lockToken = mt_rand(0, mt_getrandmax()); //Random value for ownership verification + + while (true) + { + $casToken = null; + $data = $memcached->get($key, $casToken); + if ($memcached->getResultCode() == Memcached::RES_NOTFOUND) + { + if ($memcached->add($key, $lockToken, 5)) + { + break; + } + } + elseif ($data === false) + { + if ($memcached->cas($casToken, $key, $lockToken, 5)) + { + break; + } + } + + //Sleep 10 milliseconds + usleep(10 * 1000); + } +} + +//Do something here that requires exclusive access to this key + +//Effectively delete our key lock. +{ + $casToken = null; + if ($lockToken == $memcached->get($key, $casToken)) + { + $memcached->cas($casToken, $key, false, 1); + } +} + +//Create 10 keys and then increment them. The first value returned will be wrong. +{ + $keyList = array(); + for ($i = 0; $i < 10; $i++) + { + $keyList[] = $i . '_' . uniqid ('count_value_'); + } + + $valueList = array(); + foreach ($keyList as $key) + { + $valueList[$key] = $memcached->increment($key, 1, 1); + } + + var_dump ($valueList); +} + +--EXPECTF-- +array(10) { + ["0_%s"]=> + int(1) + ["1_%s"]=> + int(1) + ["2_%s"]=> + int(1) + ["3_%s"]=> + int(1) + ["4_%s"]=> + int(1) + ["5_%s"]=> + int(1) + ["6_%s"]=> + int(1) + ["7_%s"]=> + int(1) + ["8_%s"]=> + int(1) + ["9_%s"]=> + int(1) +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_93.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_93.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/gh_93.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/gh_93.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,46 @@ +--TEST-- +Test for Github issue #93 (double and long overflow) +--SKIPIF-- + +--FILE-- + false + )); + +function testOverflow($m, $value) { + $m->delete('overflow'); + if (true !== $m->set('overflow', $value)) { + echo "Error storing 'overflow' variable\n"; + return false; + } + + if (true !== $m->prepend('overflow', str_repeat('0', 128))) { + echo "Error prepending key\n"; + return false; + } + + $v = @$m->get('overflow'); + if ($v !== $value) { + // At least it doesn't segfault, so we're happy for now + // echo "Error receiving 'overflow' variable\n"; + // return false; + return true; + } + + return true; +} + +if (!testOverflow($m, 10)) { + return; +} + +if (!testOverflow($m, 9.09)) { + return; +} + +echo "OK\n"; +?> +--EXPECT-- +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_64.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_64.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_64.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_64.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,39 @@ +--TEST-- +64-bit Memcached::increment() decrement() incrementByKey() decrementByKey() +--SKIPIF-- + +--FILE-- +set('foo', 1); +var_dump($m->get('foo')); + +echo "Enormous offset 64-bit\n"; +$m->increment('foo', 0x100000000); +var_dump($m->get('foo')); + +$m->decrement('foo', 0x100000000); +var_dump($m->get('foo')); + +echo "Enormous offset 64-bit by key\n"; +$m->incrementByKey('foo', 'foo', 0x100000000); +var_dump($m->get('foo')); + +$m->decrementByKey('foo', 'foo', 0x100000000); +var_dump($m->get('foo')); + +--EXPECT-- +Normal +int(1) +Enormous offset 64-bit +int(4294967297) +int(1) +Enormous offset 64-bit by key +int(4294967297) +int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_bykey.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_bykey.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_bykey.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_bykey.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,66 @@ +--TEST-- +Memcached::incrementByKey() Memcached::decrementByKey() +--SKIPIF-- + +--FILE-- +delete('foo'); +var_dump($m->incrementByKey('foo', 'foo', 1)); +var_dump($m->decrementByKey('foo', 'foo', 1)); +var_dump($m->get('foo')); + +echo "Normal\n"; +$m->set('foo', 1); +var_dump($m->get('foo')); +$m->incrementByKey('foo', 'foo'); +var_dump($m->get('foo')); +$m->incrementByKey('foo', 'foo', 2); +var_dump($m->get('foo')); +$m->decrementByKey('foo', 'foo'); +var_dump($m->get('foo')); +$m->decrementByKey('foo', 'foo', 2); +var_dump($m->get('foo')); + +error_reporting(0); + +echo "Negative offset\n"; +error_clear_last(); +$m->incrementByKey('foo', 'foo', -1); +echo error_get_last()["message"], "\n"; +var_dump($m->get('foo')); + +error_clear_last(); +$m->decrementByKey('foo', 'foo', -1); +echo error_get_last()["message"], "\n"; +var_dump($m->get('foo')); + +echo "Enormous offset\n"; +$m->incrementByKey('foo', 'foo', 0x7f000000); +var_dump($m->get('foo')); + +$m->decrementByKey('foo', 'foo', 0x7f000000); +var_dump($m->get('foo')); + +--EXPECT-- +Not there +bool(false) +bool(false) +bool(false) +Normal +int(1) +int(2) +int(4) +int(3) +int(1) +Negative offset +Memcached::incrementByKey(): offset cannot be a negative value +int(1) +Memcached::decrementByKey(): offset cannot be a negative value +int(1) +Enormous offset +int(2130706433) +int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_initial.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_initial.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_initial.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_initial.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,52 @@ +--TEST-- +Memcached::increment() Memcached::decrement() with initial support +--SKIPIF-- + +--FILE-- + true + )); + +$m->delete('foo'); +var_dump($m->increment('foo', 1, 1)); +var_dump($m->increment('foo', 0)); +$m->delete('foo'); + +var_dump($m->increment('foo', 1, 1)); +var_dump($m->increment('foo', 1, 1)); +var_dump($m->increment('foo', 1, 1)); + +var_dump($m->decrement('foo', 1, 1)); +var_dump($m->decrement('foo', 0)); +$m->delete('foo'); + +$m->deleteByKey('foo', 'foo'); +var_dump($m->incrementByKey('foo', 'foo', 1, 1)); +var_dump($m->incrementByKey('foo', 'foo', 0)); +$m->deleteByKey('foo', 'foo'); + +var_dump($m->incrementByKey('foo', 'foo', 1, 1)); +var_dump($m->incrementByKey('foo', 'foo', 1, 1)); +var_dump($m->incrementByKey('foo', 'foo', 1, 1)); + +var_dump($m->decrementByKey('foo', 'foo', 1, 1)); +var_dump($m->decrementByKey('foo', 'foo', 0)); +$m->deleteByKey('foo', 'foo'); + +--EXPECT-- +int(1) +int(1) +int(1) +int(2) +int(3) +int(2) +int(2) +int(1) +int(1) +int(1) +int(2) +int(3) +int(2) +int(2) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_invalid_key.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_invalid_key.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr_invalid_key.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr_invalid_key.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,15 @@ +--TEST-- +Memcached::increment() Memcached::decrement() with invalid key +--SKIPIF-- + +--FILE-- +increment('', 1)); +var_dump($m->decrement('', 1)); +?> +--EXPECT-- +bool(false) +bool(false) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/incrdecr.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/incrdecr.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,72 @@ +--TEST-- +Memcached::increment() Memcached::decrement() +--SKIPIF-- + +--FILE-- +delete('foo'); +var_dump($m->increment('foo', 1)); +var_dump($m->getResultCode()); +var_dump($m->decrement('foo', 1)); +var_dump($m->getResultCode()); +var_dump($m->get('foo')); +var_dump($m->getResultCode()); + +echo "Normal\n"; +$m->set('foo', 1); +var_dump($m->get('foo')); +$m->increment('foo'); +var_dump($m->get('foo')); +$m->increment('foo', 2); +var_dump($m->get('foo')); +$m->decrement('foo'); +var_dump($m->get('foo')); +$m->decrement('foo', 2); +var_dump($m->get('foo')); + +error_reporting(0); + +echo "Negative offset\n"; +error_clear_last(); +$m->increment('foo', -1); +echo error_get_last()["message"], "\n"; +var_dump($m->get('foo')); + +error_clear_last(); +$m->decrement('foo', -1); +echo error_get_last()["message"], "\n"; +var_dump($m->get('foo')); + +echo "Enormous offset\n"; +$m->increment('foo', 0x7f000000); +var_dump($m->get('foo')); + +$m->decrement('foo', 0x7f000000); +var_dump($m->get('foo')); + +--EXPECT-- +Not there +bool(false) +int(16) +bool(false) +int(16) +bool(false) +int(16) +Normal +int(1) +int(2) +int(4) +int(3) +int(1) +Negative offset +Memcached::increment(): offset cannot be a negative value +int(1) +Memcached::decrement(): offset cannot be a negative value +int(1) +Enormous offset +int(2130706433) +int(1) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invalid_options.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invalid_options.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invalid_options.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invalid_options.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,18 @@ +--TEST-- +Get version +--SKIPIF-- + +--FILE-- +setOption(500, 23423); +var_dump ($m->getResultCode ()); + +echo "OK" . PHP_EOL; +?> +--EXPECTF-- +Warning: Memcached::setOption(): error setting memcached option: INVALID ARGUMENTS in %s on line %d +int(38) +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invoke_callback_2.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invoke_callback_2.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invoke_callback_2.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invoke_callback_2.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,87 @@ +--TEST-- +Use callback initializer +--SKIPIF-- + +--FILE-- +isPersistent()); + var_dump($id); +} + +function init_cb_fail($m, $id) { + echo "configured, should not be called.\n"; +} + +function init_cb_arg($m, $id) { + var_dump(func_num_args()); + var_dump($id); +} + +function init_nopersist_cb($m, $id) { + var_dump($m->isPersistent()); + var_dump($id); +} + +class Foo extends Memcached { + function __construct($id = null) { + parent::__construct($id, array($this, 'init')); + } + + function init($obj, $id) { + var_dump(func_num_args()); + var_dump($this->isPristine()); + var_dump($this->isPersistent()); + var_dump($id); + } +} + +echo "cb call\n"; +$m1 = new Memcached('foo1', 'init_cb'); + +echo "cb not run\n"; +$m1 = new Memcached('foo1', 'init_cb_fail'); + +echo "cb arg without arg\n"; +$m1 = new Memcached('foo3', 'init_cb_arg'); + +echo "cb arg not persistent\n"; +$m1 = new Memcached(null, 'init_nopersist_cb'); + +echo "cb in object\n"; +$m1 = new Foo(); + +echo "cb persistent in object\n"; +$m1 = new Foo('baz'); + +echo "cb second persistent in object\n"; +$m1 = new Foo('baz'); +?> +--EXPECT-- +cb call +string(9) "Memcached" +bool(true) +string(4) "foo1" +cb not run +cb arg without arg +int(2) +string(4) "foo3" +cb arg not persistent +bool(false) +NULL +cb in object +int(2) +bool(true) +bool(false) +NULL +cb persistent in object +int(2) +bool(true) +bool(true) +string(3) "baz" +cb second persistent in object diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invoke_callback.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invoke_callback.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invoke_callback.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invoke_callback.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,34 @@ +--TEST-- +Test that callback is invoked on new object +--SKIPIF-- + +--FILE-- +addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); +} + +$m = new Memcached('hi', 'my_func'); +$m = new Memcached('hi', 'my_func'); + +var_dump($m->getServerList()); + +echo "OK\n"; + +--EXPECTF-- +array(1) { + [0]=> + array(3) { + ["host"]=> + string(9) "%s" + ["port"]=> + int(%d) + ["type"]=> + string(3) "TCP" + } +} +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invoke_callback_twice.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invoke_callback_twice.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/invoke_callback_twice.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/invoke_callback_twice.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,20 @@ +--TEST-- +Test that callback is invoked on new object only once +--SKIPIF-- + +--FILE-- + +--FILE-- + false, + Memcached::OPT_VERIFY_KEY => false + )); +// libmemcached can verify keys, but these are tests are for our own +// function s_memc_valid_key_ascii, so explicitly disable the checks +// that libmemcached can perform. + +echo 'ASCII: SPACES' . PHP_EOL; +var_dump ($ascii->set ('ascii key with spaces', 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: NEWLINE' . PHP_EOL; +var_dump ($ascii->set ('asciikeywithnewline' . PHP_EOL, 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: EMPTY' . PHP_EOL; +var_dump ($ascii->set (''/*empty key*/, 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: TOO LONG' . PHP_EOL; +var_dump ($ascii->set (str_repeat ('1234567890', 512), 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: GET' . PHP_EOL; +for ($i=0;$i<32;$i++) { + var_dump ($ascii->get ('asciikeywithnonprintablechar-' . chr($i) . '-here')); + var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +} + +echo 'ASCII: SET' . PHP_EOL; +for ($i=0;$i<32;$i++) { + var_dump ($ascii->set ('asciikeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); + var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +} + +echo 'OK' . PHP_EOL; + +--EXPECT-- +ASCII: SPACES +bool(false) +bool(true) +ASCII: NEWLINE +bool(false) +bool(true) +ASCII: EMPTY +bool(false) +bool(true) +ASCII: TOO LONG +bool(false) +bool(true) +ASCII: GET +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +ASCII: SET +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/keys_binary.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/keys_binary.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/keys_binary.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/keys_binary.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,190 @@ +--TEST-- +Test valid and invalid keys - binary +--SKIPIF-- + +--FILE-- + true, + )); + +echo 'BINARY: SPACES' . PHP_EOL; +var_dump ($binary->set ('binary key with spaces', 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_SUCCESS); + +echo 'BINARY: NEWLINE' . PHP_EOL; +var_dump ($binary->set ('binarykeywithnewline' . PHP_EOL, 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'BINARY: EMPTY' . PHP_EOL; +var_dump ($binary->set (''/*empty key*/, 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'BINARY: TOO LONG' . PHP_EOL; +var_dump ($binary->set (str_repeat ('1234567890', 512), 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'BINARY: GET' . PHP_EOL; +// Only newline fails in binary mode (char 10) +for ($i=0;$i<32;$i++) { + $binary->delete ('binarykeywithnonprintablechar-' . chr($i) . '-here'); + var_dump ($binary->get ('binarykeywithnonprintablechar-' . chr($i) . '-here')); + var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +} + +echo 'BINARY: SET' . PHP_EOL; +// Only newline fails in binary mode (char 10) +for ($i=0;$i<32;$i++) { + var_dump ($binary->set ('binarykeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); + var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + $binary->delete ('binarykeywithnonprintablechar-' . chr($i) . '-here'); +} + +echo 'OK' . PHP_EOL; + +--EXPECT-- +BINARY: SPACES +bool(true) +bool(true) +BINARY: NEWLINE +bool(false) +bool(true) +BINARY: EMPTY +bool(false) +bool(true) +BINARY: TOO LONG +bool(false) +bool(true) +BINARY: GET +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +BINARY: SET +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/localserver.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/localserver.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/localserver.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/localserver.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,21 @@ +--TEST-- +Memcached local server test +--SKIPIF-- + +--FILE-- +set($key, array( + 'foo' => 'bar' +), 360); + +var_dump($m->get($key)); +?> +--EXPECT-- +array(1) { + ["foo"]=> + string(3) "bar" +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/multi_order.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/multi_order.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/multi_order.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/multi_order.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,39 @@ +--TEST-- +Memcached GET_PRESERVE_ORDER flag in getMulti +--SKIPIF-- + +--FILE-- +addServer (MEMC_SERVER_HOST, MEMC_SERVER_PORT); + +$data = array( + 'foo' => 'foo-data', + 'bar' => 'bar-data', + 'baz' => 'baz-data', + 'lol' => 'lol-data', + 'kek' => 'kek-data', +); + +//$m->setMulti($data, 3600); +foreach ($data as $k => $v) { + $m->set($k, $v, 3600); +} + +$keys = array_keys($data); +$keys[] = 'zoo'; +$got = $m->getMulti($keys, Memcached::GET_PRESERVE_ORDER); + +foreach ($got as $k => $v) { + echo "$k $v\n"; +} + +?> +--EXPECT-- +foo foo-data +bar bar-data +baz baz-data +lol lol-data +kek kek-data +zoo diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/no-not-found.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/no-not-found.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/no-not-found.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/no-not-found.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,23 @@ +--TEST-- +Test that correct return value is returned +--SKIPIF-- + +--FILE-- +addServer('localhost', 5555); // Server should not exist + +$result = $memcached->get('foo_not_exists'); +var_dump ($result === Memcached::GET_ERROR_RETURN_VALUE); + +$result = $memcached->get('foo_not_exists'); +var_dump ($result === Memcached::GET_ERROR_RETURN_VALUE); + +echo "OK\n"; + +?> +--EXPECT-- +bool(true) +bool(true) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/options.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/options.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/options.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/options.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,43 @@ +--TEST-- +Memcached options +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_PHP); + +var_dump($m->getOption(Memcached::OPT_COMPRESSION)); +var_dump($m->getOption(Memcached::OPT_SERIALIZER)); +var_dump($m->getOption(Memcached::OPT_SOCKET_SEND_SIZE)); + +$m->setOption(Memcached::OPT_PREFIX_KEY, "\x01"); + +var_dump($m->getOption(Memcached::OPT_HASH) == Memcached::HASH_DEFAULT); +$m->setOption(Memcached::OPT_HASH, Memcached::HASH_MURMUR); +var_dump($m->getOption(Memcached::OPT_HASH) == Memcached::HASH_MURMUR); + + +$m->setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_ZLIB); +var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSION_ZLIB); + +$m->setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_FASTLZ); +var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSION_FASTLZ); + +var_dump($m->setOption(Memcached::OPT_COMPRESSION_TYPE, 0)); +var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSION_FASTLZ); +?> +--EXPECTF-- +bool(true) +int(1) + +Warning: Memcached::getOption(): no servers defined in %s on line %d +NULL + +Warning: Memcached::setOption(): bad key provided in %s on line %d +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/pr_75.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/pr_75.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/pr_75.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/pr_75.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,29 @@ +--TEST-- +Wrong return values for binary protocol +--SKIPIF-- + +--FILE-- + true + )); + +$client->set('key1', 'value1'); +echo "set result code: ".$client->getResultCode()."\n"; + +$value = $client->get('key1'); +echo "got $value with result code: ".$client->getResultCode()."\n"; + +var_dump ($client->add('key2', 'value2')); +echo "add result code: ".$client->getResultCode()."\n"; + +echo "OK\n"; + +?> +--EXPECT-- +set result code: 0 +got value1 with result code: 0 +bool(true) +add result code: 0 +OK \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/prepend.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/prepend.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/prepend.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/prepend.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,28 @@ +--TEST-- +Memcached::prepend() +--SKIPIF-- + +--FILE-- +delete('foo'); +$m->setOption(Memcached::OPT_COMPRESSION, true); +var_dump($m->prepend('foo', 'a')); + +$m->setOption(Memcached::OPT_COMPRESSION, false); +$m->delete('foo'); +var_dump($m->prepend('foo', 'a')); +var_dump($m->get('foo')); +$m->set('foo', 'a'); +var_dump($m->prepend('foo', 'b')); +var_dump($m->get('foo')); + +--EXPECTF-- +Warning: Memcached::prepend(): cannot append/prepend with compression turned on in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +string(2) "ba" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/replace.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/replace.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/replace.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/replace.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,22 @@ +--TEST-- +Memcached::replace() +--SKIPIF-- + +--FILE-- +delete('foo'); +var_dump($m->replace('foo', 'bar', 60)); +var_dump($m->get('foo')); + +$m->set('foo', 'kef'); +var_dump($m->replace('foo', 'bar', 60)); +var_dump($m->get('foo')); + +--EXPECT-- +bool(false) +bool(false) +bool(true) +string(3) "bar" diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/rescode.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/rescode.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/rescode.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/rescode.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,91 @@ +--TEST-- +Memcached result codes. +--SKIPIF-- + +--FILE-- +getResultMessage(), "\n"; + +$m->addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT, 1); +echo $m->getResultCode(), "\n"; +echo $m->getResultMessage(), "\n"; + +$m->set('bar_foo', 10); +echo $m->getResultMessage(), "\n"; + +$m->delete('bar_foo'); +echo $m->getResultMessage(), "\n"; + +$m->delete('bar_foo'); +echo $m->getResultCode(), "\n"; +echo $m->getResultMessage(), "\n"; + +$m->set ('asdf_a', 'aa'); +$m->getMulti(array('asdf_a', 'jkhjkhjkb', 'nbahsdgc')); +echo $m->getResultMessage(), "\n"; +$code = $m->getResultCode(); + +$m2 = new Memcached(); +$m2->getMulti(array('asdf_a', 'jkhjkhjkb', 'nbahsdgc')); +echo $m2->getResultCode(), "\n"; +echo $m2->getResultMessage(), "\n"; + +$m2->addServer('127.0.0.1', 7312, 1); +echo $m2->getResultCode(), "\n"; +echo $m2->getResultMessage(), "\n"; + +$m2->delete('bar_foo'); +echo $m2->getResultCode(), "\n"; +echo $m2->getResultMessage(), "\n"; + +var_dump($m->getResultCode() == $code); + +$m = memc_get_instance (array (), 'test1'); +$m2 = new Memcached('test1'); + +$m->delete('moikkamitakuuluu'); +echo $m->getResultMessage(), "\n"; +$m2->set('minapaasetannih', 10, 1); +echo $m->getResultMessage(), "\n"; +echo $m2->getResultMessage(), "\n"; + +$m->delete('bar_foo'); +// clearly "NOT FOUND" +$m->delete('bar_foo'); +$res_m = $m->getResultMessage(); +echo $res_m, "\n"; + +$m2->set('bar_foo', 10); +echo $m->getResultMessage(), "\n"; +echo $m2->getResultMessage(), "\n"; + +$m->delete('bar_foo'); +echo $m->getResultMessage(), "\n"; + +?> +--EXPECTF-- +SUCCESS +%d +SUCCESS +SUCCESS +SUCCESS +%d +NOT FOUND +SUCCESS +%d +NO SERVERS DEFINED +%d +SUCCESS +%d +%rSYSTEM ERROR|WRITE FAILURE|CONNECTION FAILURE%r +bool(true) +NOT FOUND +NOT FOUND +SUCCESS +NOT FOUND +NOT FOUND +SUCCESS +SUCCESS diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/reset_keyprefix.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/reset_keyprefix.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/reset_keyprefix.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/reset_keyprefix.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,38 @@ +--TEST-- +Cannot reset OPT_PREFIX_KEY #293 +--SKIPIF-- + +--FILE-- +set('key1', 'abc'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, false); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, ''); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, null); +var_dump($m->get('key1')); +--EXPECTF-- +string(3) "abc" +bool(false) +string(3) "abc" +bool(false) +string(3) "abc" +bool(false) +string(3) "abc" \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/sasl_basic.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/sasl_basic.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/sasl_basic.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/sasl_basic.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,32 @@ +--TEST-- +Test SASL authentication +--SKIPIF-- + +--INI-- +memcached.use_sasl = on +--FILE-- + true + )); + +var_dump ($m->setSaslAuthData (MEMC_SASL_USER, MEMC_SASL_PASS)); + +$key = uniqid ('sasl_test_'); +var_dump ($m->set ($key, 'set using sasl')); +var_dump ($m->get ($key)); + + +echo "OK" . PHP_EOL; +?> +--EXPECT-- +bool(true) +bool(true) +string(14) "set using sasl" +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_badconf_emptyprefix.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_badconf_emptyprefix.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_badconf_emptyprefix.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_badconf_emptyprefix.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,28 @@ +--TEST-- +Session bad configurations, prefix +--SKIPIF-- + +--INI-- +memcached.sess_locking = on +memcached.sess_prefix = "memc.sess.key." +session.save_handler = "memcached" + +--FILE-- + +--INI-- +memcached.sess_locking = on +memcached.sess_lock_wait = -1 +memcached.sess_prefix = "memc.sess.key." +session.save_path="127.0.0.1:51312" +session.save_handler = memcached + +--FILE-- + +--INI-- +session.save_handler = "memcached" +session.save_path = "PERSISTENT=1 hello:11211,world:11211" + +--FILE-- + +--INI-- +session.save_handler = memcached +--FILE-- + +--INI-- +session.save_handler = memcached +--FILE-- + 70100) print "skip"; +?> +--INI-- +session.save_handler = memcached +--FILE-- + +--INI-- +session.save_handler = memcached +memcached.sess_binary_protocol = Off +--FILE-- +TRUE]); +$_SESSION['foo'] = 1; +session_write_close(); + +$_SESSION = NULL; + +var_dump($_SESSION); +session_start(); +var_dump($_SESSION); +session_write_close(); + +session_start(); +session_destroy(); + +session_start(); +var_dump($_SESSION); +session_write_close(); + + +--EXPECT-- +NULL +array(1) { + ["foo"]=> + int(1) +} +array(0) { +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_basic3.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_basic3.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_basic3.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_basic3.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,46 @@ +--TEST-- +Session basic open, write, destroy +--SKIPIF-- + +--INI-- +session.save_handler = memcached +memcached.sess_binary_protocol = Off +--FILE-- + true +]); +var_dump($_SESSION); +session_write_close(); + +session_start(); +session_destroy(); + +session_start(); +var_dump($_SESSION); +session_write_close(); + + +--EXPECT-- +NULL +array(1) { + ["foo"]=> + int(1) +} +array(0) { +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_basic.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_basic.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_basic.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_basic.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,44 @@ +--TEST-- +Session basic open, write, destroy +--SKIPIF-- + +--INI-- +session.save_handler = memcached +memcached.sess_binary_protocol = Off +--FILE-- + + int(1) +} +array(0) { +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_lazy_warning.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_lazy_warning.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_lazy_warning.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_lazy_warning.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,47 @@ +--TEST-- +Session lazy binary warning old libmemcached +--SKIPIF-- += 0x01000018) die ('skip too recent libmemcached'); +?> +--INI-- +session.save_handler = memcached +memcached.sess_binary_protocol = On +--FILE-- +TRUE]); +$_SESSION['foo'] = 1; +session_write_close(); + +$_SESSION = NULL; + +var_dump($_SESSION); +session_start(); +var_dump($_SESSION); +session_write_close(); + +session_start(); +session_destroy(); + +session_start(); +var_dump($_SESSION); +session_write_close(); + + +--EXPECTF-- +NULL +array(1) { + ["foo"]=> + int(1) +} + +Warning: session_write_close(): using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached in %s on line %d +array(0) { +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_lock-php71.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_lock-php71.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_lock-php71.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_lock-php71.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,66 @@ +--TEST-- +Session lock +--SKIPIF-- + +--INI-- +memcached.sess_locking = true +memcached.sess_lock_wait_min = 500 +memcached.sess_lock_wait_max = 1000 +memcached.sess_lock_retries = 3 +memcached.sess_prefix = "memc.test." + +# Turn off binary protocol while the test matrix has older versions of +# libmemcached for which the extension warns of a broken touch command. +memcached.sess_binary_protocol = Off + +session.save_handler = memcached + +--FILE-- +addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); + +ob_start(); +ini_set ('session.save_path', MEMC_SERVER_HOST . ':' . MEMC_SERVER_PORT); + +session_start(); +$session_id = session_id(); + +$_SESSION["test"] = "hello"; +session_write_close(); + +session_start(); +var_dump ($m->get ('memc.test.' . session_id())); +var_dump ($m->get ('memc.test.lock.' . session_id())); +session_write_close(); +var_dump ($m->get ('memc.test.lock.' . session_id())); + +// Test lock min / max +$m->set ('memc.test.lock.' . $session_id, '1'); + +$time_start = microtime(true); +session_start(); +$time = microtime(true) - $time_start; + +if (round ($time, 1) != 2.5) { + echo "Waited longer than expected: $time" . PHP_EOL; +} +echo "OK"; + +--EXPECTF-- +string(17) "test|s:5:"hello";" +string(1) "1" +bool(false) + +Warning: session_start(): Unable to clear session lock record in %s on line %d + +Warning: session_start(): Failed to read session data: memcached (path: 127.0.0.1:11211) in %s on line %d +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_lock.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_lock.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_lock.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_lock.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,64 @@ +--TEST-- +Session lock +--SKIPIF-- += 70100) print "skip"; +?> +--INI-- +memcached.sess_locking = true +memcached.sess_lock_wait_min = 500 +memcached.sess_lock_wait_max = 1000 +memcached.sess_lock_retries = 3 +memcached.sess_prefix = "memc.test." + +# Turn off binary protocol while the test matrix has older versions of +# libmemcached for which the extension warns of a broken touch command. +memcached.sess_binary_protocol = Off + +session.save_handler = memcached + +--FILE-- +addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); + +ob_start(); +ini_set ('session.save_path', MEMC_SERVER_HOST . ':' . MEMC_SERVER_PORT); + +session_start(); +$session_id = session_id(); + +$_SESSION["test"] = "hello"; +session_write_close(); + +session_start(); +var_dump ($m->get ('memc.test.' . session_id())); +var_dump ($m->get ('memc.test.lock.' . session_id())); +session_write_close(); +var_dump ($m->get ('memc.test.lock.' . session_id())); + +// Test lock min / max +$m->set ('memc.test.lock.' . $session_id, '1'); + +$time_start = microtime(true); +session_start(); +$time = microtime(true) - $time_start; + +if (round ($time, 1) != 2.5) { + echo "Waited longer than expected: $time" . PHP_EOL; +} +echo "OK"; + +--EXPECTF-- +string(17) "test|s:5:"hello";" +string(1) "1" +bool(false) + +Warning: session_start(): Unable to clear session lock record in %s on line %d +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_persistent.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_persistent.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_persistent.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_persistent.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,28 @@ +--TEST-- +Session persistent +--SKIPIF-- + +--INI-- +session.save_handler=memcached +memcached.sess_persistent=1 +--FILE-- + +--EXPECT-- +array(1) { + ["test"]=> + bool(true) +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_regenerate.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_regenerate.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/session_regenerate.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/session_regenerate.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,26 @@ +--TEST-- +Session regenerate +--SKIPIF-- + +--INI-- +session.save_handler = memcached +--FILE-- += 0x01000018) die ("skip test for libmemcached lower than 1.0.18"); +?> +--FILE-- +setEncodingKey("Hello")); +var_dump ($m->set ($key, 'set using encoding')); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# libmemcached < 1.0.18 goes into a bad state when the encoding key is changed, +# so php-memcached warns and returns false when trying to change the key. +var_dump ($m->setEncodingKey("World")); + +echo "OK" . PHP_EOL; + +?> +--EXPECTF-- +bool(true) +bool(true) +string(18) "set using encoding" +OK + +Warning: Memcached::setEncodingKey(): libmemcached versions less than 1.0.18 cannot change encoding key in %s on line %d +bool(false) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/set_encoding_key.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/set_encoding_key.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/set_encoding_key.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/set_encoding_key.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,59 @@ +--TEST-- +Test libmemcached encryption +--SKIPIF-- + +--FILE-- +setEncodingKey("Hello")); +var_dump ($m->set ($key, 'set using encoding')); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# Change the encryption key. The old value will be inaccessible. +var_dump ($m->setEncodingKey("World")); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# Restore the original key to retrieve old values again. +var_dump ($m->setEncodingKey("Hello")); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# With a new encoding key we can still write new values, +# this works as expected with libmemcached 1.0.18 and higher. +var_dump ($m->setEncodingKey("World")); +var_dump ($m->get ($key)); +var_dump ($m->set ($key, 'set using encoding')); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +?> +--EXPECT-- +bool(true) +bool(true) +string(18) "set using encoding" +OK +bool(true) +bool(false) +OK +bool(true) +string(18) "set using encoding" +OK +bool(true) +bool(false) +bool(true) +string(18) "set using encoding" +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/set_large.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/set_large.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/set_large.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/set_large.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,17 @@ +--TEST-- +set large data +--SKIPIF-- + +--FILE-- +set($key, $value, 360)); +var_dump($m->get($key) === $value); +?> +--EXPECT-- +bool(true) +bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/setmulti.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/setmulti.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/setmulti.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/setmulti.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,70 @@ +--TEST-- +Memcached::setMulti() +--SKIPIF-- + +--FILE-- +deleteMulti($keys); +echo "set keys: "; +var_dump($m->setMulti($data, 10)); + +echo "get: "; +$r = $m->getMulti($keys); +var_dump($r); + +echo "Equal: "; +var_dump($r === $data); + +--EXPECTF-- +Data: array(%d) { + ["foo"]=> + string(3) "bar" + [%i]=> + string(7) "int-max" + [%i]=> + string(7) "int-min" + [%i]=> + string(7) "int-min" + [0]=> + string(4) "zero" + [123]=> + string(11) "onetwothree" + [-123]=> + string(14) "negonetwothree" +} +set keys: bool(true) +get: array(%d) { + ["foo"]=> + string(3) "bar" + [%i]=> + string(7) "int-max" + [%i]=> + string(7) "int-min" + [%i]=> + string(7) "int-min" + [0]=> + string(4) "zero" + [123]=> + string(11) "onetwothree" + [-123]=> + string(14) "negonetwothree" +} +Equal: bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/setoptions.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/setoptions.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/setoptions.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/setoptions.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,45 @@ +--TEST-- +Set options using setOptions +--SKIPIF-- + +--FILE-- +setOptions(array( + Memcached::OPT_PREFIX_KEY => 'a_prefix', + Memcached::OPT_SERIALIZER => Memcached::SERIALIZER_PHP, + Memcached::OPT_COMPRESSION => 0, + Memcached::OPT_LIBKETAMA_COMPATIBLE => 1, + Memcached::OPT_CONNECT_TIMEOUT => 5000, +))); + +var_dump($m->getOption(Memcached::OPT_PREFIX_KEY) == 'a_prefix'); +var_dump($m->getOption(Memcached::OPT_SERIALIZER) == Memcached::SERIALIZER_PHP); +var_dump($m->getOption(Memcached::OPT_COMPRESSION) == 0); +var_dump($m->getOption(Memcached::OPT_LIBKETAMA_COMPATIBLE) == 1); + +echo "test invalid options\n"; + +var_dump($m->setOptions(array( + "asdf" => 123 +))); + +var_dump($m->setOptions(array( + -1 => 123 +))); + +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +test invalid options + +Warning: Memcached::setOptions(): invalid configuration option in %s on line %d +bool(false) + +Warning: Memcached::setOptions(): error setting memcached option: %s in %s on line %d +bool(false) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/skipif.inc php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/skipif.inc --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/skipif.inc 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/skipif.inc 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,16 @@ + +--FILE-- +setOption(Memcached::OPT_NO_BLOCK, true); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +// If either or both options are false no need to reconnect +$m->setOption(Memcached::OPT_NO_BLOCK, false); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +// If either or both options are false no need to reconnect +$m->setOption(Memcached::OPT_NO_BLOCK, true); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, false); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +// If either or both options are false no need to reconnect +$m->setOption(Memcached::OPT_NO_BLOCK, false); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, false); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +?> +--EXPECT-- +bool(false) +int(1) +int(1) +OK +bool(true) +int(0) +int(1) +OK +bool(true) +int(1) +int(0) +OK +bool(true) +int(0) +int(0) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/stats.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/stats.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/stats.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/stats.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,25 @@ +--TEST-- +Check stats +--SKIPIF-- + +--FILE-- +getStats(); +$key = MEMC_SERVER_HOST . ':' . MEMC_SERVER_PORT; + +var_dump (count ($stats) === 1); +var_dump (isset ($stats[$key])); +var_dump (count ($stats[$key]) > 0); +var_dump (is_int ($stats[$key]['cmd_get'])); + +echo "OK"; +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/testdata.res php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/testdata.res --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/testdata.res 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/testdata.res 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,9 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut malesuada purus vel diam congue condimentum. Vivamus diam erat, commodo eget lacinia venenatis, tempor at nulla. Praesent dapibus aliquam lectus. Aliquam erat volutpat. Praesent congue elementum ipsum, eu bibendum nisi ullamcorper nec. Aenean mattis metus quis libero hendrerit blandit accumsan nisi lacinia. Aenean varius sollicitudin nisl, tempor condimentum turpis congue id. Nunc vulputate purus non nunc dignissim tincidunt. Curabitur adipiscing est in ligula interdum a ultrices nibh ultricies. Aliquam a dapibus lectus. + +Ut eleifend, dui nec aliquam lobortis, quam est luctus lectus, nec hendrerit augue quam ac odio. Nam condimentum, ligula et rhoncus vulputate, lorem urna adipiscing mauris, non mollis velit arcu non urna. Donec sodales ultrices risus, sed hendrerit libero fringilla vitae. Maecenas magna nisl, vehicula scelerisque hendrerit id, fermentum at lorem. Curabitur eu nisl tincidunt arcu venenatis ultricies. Vivamus velit lorem, hendrerit non imperdiet sit amet, eleifend nec mauris. Donec eget condimentum purus. Cras sed lorem sagittis augue faucibus tincidunt. Pellentesque vitae lorem ac orci dignissim tempor. Maecenas diam elit, pulvinar sed gravida rutrum, ultrices vel mauris. In adipiscing placerat eros imperdiet euismod. Nunc quis ante non lectus dictum porta. Nullam orci felis, tristique ut posuere at, tempor sed eros. Pellentesque accumsan posuere magna eu condimentum. Phasellus adipiscing cursus fringilla. Donec diam ipsum, pharetra quis tempus sit amet, mollis in dolor. Pellentesque volutpat vestibulum nulla quis ultricies. Pellentesque scelerisque erat eu nulla ullamcorper tincidunt. + +Nullam commodo lobortis lacus, ac scelerisque diam dignissim eget. Cras eu metus sed tellus accumsan rutrum id ac nunc. Duis rutrum ipsum quis sapien dictum tincidunt. Duis gravida augue et sapien laoreet at pretium eros vulputate. Duis pulvinar lectus quis libero ultricies consequat a id felis. Morbi imperdiet venenatis ipsum eget ultricies. Vivamus fermentum urna sed massa tristique euismod. Pellentesque sed justo ut mi tincidunt luctus semper et elit. In hac habitasse platea dictumst. Praesent suscipit, elit quis fermentum luctus, magna dolor volutpat tellus, nec blandit nulla metus a lacus. Duis gravida, ipsum eu posuere congue, massa augue semper sapien, vel bibendum mi odio nec lectus. Vivamus lacinia urna vitae justo tincidunt dictum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sed libero metus, in imperdiet nibh. + +Integer sapien mauris, pretium sed sodales at, blandit in lacus. Etiam a nisl semper enim pellentesque posuere vitae quis lectus. Etiam ut libero at tortor molestie feugiat non ut ligula. Suspendisse fermentum ipsum vel mauris aliquet convallis. Fusce velit turpis, sollicitudin sit amet luctus id, porta nec ipsum. Fusce consequat, risus vel congue sollicitudin, orci sem auctor nisl, eu consectetur neque tortor id neque. Nunc in odio velit. Duis vitae lacus elit, eu fringilla nulla. Phasellus non mi tellus, volutpat commodo lorem. Pellentesque vel ligula enim. Morbi suscipit, orci sed gravida convallis, nunc leo eleifend lacus, quis elementum dui mi nec risus. Mauris faucibus arcu scelerisque tellus semper dictum. Suspendisse vel posuere turpis. Curabitur ipsum ligula, auctor ut dignissim vel, scelerisque vel mauris. Vivamus est dolor, bibendum ac vestibulum a, congue id felis. Mauris rutrum pharetra tempus. Sed ornare congue purus, id adipiscing mi tincidunt at. Maecenas blandit, lorem in malesuada adipiscing, dolor arcu suscipit magna, ut mollis leo nibh non orci. Sed non massa ipsum, et lobortis tortor. Aliquam et egestas velit. + +Mauris ac sem eget elit imperdiet faucibus at non turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent vel dui vitae enim imperdiet sodales. Maecenas a tristique mauris. Praesent consectetur risus sit amet lacus dictum ut egestas nibh lacinia. Mauris quam augue, fringilla ac pretium a, consectetur sed risus. Sed ullamcorper eleifend dolor, id tempor arcu sodales at. Vestibulum eget sagittis libero. Cras ornare dui ac ante pretium fringilla. Morbi eu tincidunt felis. Vivamus ultrices diam in eros elementum luctus. Aenean eu neque nibh. Mauris neque est, euismod ut rutrum nec, vehicula at magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce sit amet neque ac justo pretium laoreet. Duis non sapien ut eros tristique porttitor vel et lacus. Donec molestie nunc malesuada ante porta ac pretium magna dictum. Nam dolor orci, lacinia egestas ornare eget, viverra et mi. Vivamus convallis lobortis dui, ac sagittis urna mattis sit amet. Duis interdum, est sed dignissim blandit, metus elit scelerisque mauris, sit amet egestas velit arcu quis nunc. diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/touch_binary.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/touch_binary.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/touch_binary.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/touch_binary.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,73 @@ +--TEST-- +Touch in binary mode +--SKIPIF-- + +--FILE-- +getConstants (); + + foreach ($c as $name => $value) { + if (strpos ($name, 'RES_') === 0 && $value == $code) + return $name; + } +} + +function status_print ($op, $mem, $expected) +{ + $code = $mem->getResultcode(); + + if ($code == $expected) + echo "${op} status code as expected" . PHP_EOL; + else { + $expected = resolve_to_constant ($expected); + $code = resolve_to_constant ($code); + + echo "${op} status code mismatch, expected ${expected} but got ${code}" . PHP_EOL; + } +} + +include dirname (__FILE__) . '/config.inc'; +$mem = memc_get_instance (array (Memcached::OPT_BINARY_PROTOCOL => true)); + +$key = uniqid ('touch_t_'); + +$mem->get($key); +status_print ('get', $mem, Memcached::RES_NOTFOUND); + +$mem->set ($key, 1); +status_print ('set', $mem, Memcached::RES_SUCCESS); + +$mem->get($key); +status_print ('get', $mem, Memcached::RES_SUCCESS); + +$mem->touch ($key, 10); +status_print ('touch', $mem, Memcached::RES_SUCCESS); + +$mem->get($key); +status_print ('get', $mem, Memcached::RES_SUCCESS); + +$mem->get($key); +status_print ('get', $mem, Memcached::RES_SUCCESS); + +echo "OK\n"; + +?> +--EXPECT-- +get status code as expected +set status code as expected +get status code as expected +touch status code as expected +get status code as expected +get status code as expected +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_igbinary_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_igbinary_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_igbinary_multi.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_igbinary_multi.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,19 @@ +--TEST-- +Memcached multi store & multi fetch type and value correctness using igbinary serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_igbinary.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_igbinary.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_igbinary.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_igbinary.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,19 @@ +--TEST-- +Memcached store & fetch type and value correctness using igbinary serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types.inc php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types.inc --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types.inc 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types.inc 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,129 @@ + "1","b" => "2","c" => "3")), + array('object_dummy', new testclass()), + ); + + foreach ($data as $key => $value) { + $m->delete($key); + } + + foreach ($data as $types) { + $key = $types [0]; + $value = $types [1]; + + $m->set($key, $value); + + $actual = $m->get($key); + if ($value !== $actual) { + if (is_object($actual)) { + if ($options['ignore_object_type']) { + $value = (object) (array) $value; + if ($value == $actual) + continue; + } + + if ($value == $actual && get_class($value) == get_class($actual)) + continue; + } + echo "=== {$key} ===\n"; + echo "Expected: "; + var_dump($value); + echo "Actual: "; + var_dump($actual); + + } + } + + $m->flush(); + + if (($actual = $m->get(uniqid ('random_key_'))) !== false) { + echo "Expected: null"; + echo "Actual: " . gettype($actual); + } +} + +function memc_types_test_multi ($m, $options) +{ + $data = array( + 'boolean_true' => true, + 'boolean_false' => false, + + 'string' => "just a string", + 'string_empty' => "", + 'string_large' => str_repeat ('abcdef0123456789', 500), + + 'integer_positive_integer' => 10, + 'integer_negative_integer' => -10, + 'integer_zero_integer' => 0, + + 'float_positive1' => 3.912131, + 'float_positive2' => 1.2131E+52, + 'float_negative' => -42.123312, + 'float_zero' => 0.0, + + 'null' => null, + + 'array_empty' => array(), + 'array' => array(1,2,3,"foo"), + + 'object_array_empty' => (object)array(), + 'object_array' => (object)array('a' => 1, 'b' => 2, 'c' => 3), + 'object_dummy' => new testclass(), + ); + + foreach ($data as $key => $value) { + $m->delete($key); + } + $m->setMulti($data); + $actual = $m->getMulti(array_keys($data)); + + foreach ($data as $key => $value) { + if ($value !== $actual[$key]) { + if (is_object($value)) { + if ($options['ignore_object_type']) { + $value = (object) (array) $value; + if ($value == $actual[$key]) + continue; + } + + if ($value == $actual[$key] && get_class($value) == get_class($actual[$key])) + continue; + } + + echo "=== $key ===\n"; + echo "Expected: "; + var_dump($value); + echo "Actual: "; + var_dump($actual[$key]); + } + } +} diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_json_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_json_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_json_multi.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_json_multi.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,19 @@ +--TEST-- +Memcached multi store & multi fetch type and value correctness using JSON serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_json.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_json.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_json.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_json.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,19 @@ +--TEST-- +Memcached store & fetch type and value correctness using JSON serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_msgpack_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_msgpack_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_msgpack_multi.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_msgpack_multi.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,19 @@ +--TEST-- +Memcached multi store & fetch type and value correctness using msgpack serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_msgpack.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_msgpack.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_msgpack.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_msgpack.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,19 @@ +--TEST-- +Memcached store & fetch type and value correctness using msgpack serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_php_multi.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_php_multi.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_php_multi.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_php_multi.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,16 @@ +--TEST-- +Memcached multi store & fetch type and value correctness using PHP serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_php.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_php.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/types_php.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/types_php.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,16 @@ +--TEST-- +Memcached store & fetch type and value correctness using PHP serializer +--SKIPIF-- + +--FILE-- + +--EXPECT-- +TEST DONE diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/undefined_set.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/undefined_set.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/undefined_set.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/undefined_set.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,39 @@ +--TEST-- +Set with undefined key and value +--SKIPIF-- + +--FILE-- + 'bar'); + +$rv = $m->set($no_key, $value, 360); +var_dump($rv); + + +$rv = $m->set($key, $no_value, 360); +var_dump($rv); + +$rv = $m->set($no_key, $no_value, 360); +var_dump($rv); + +$rv = $m->set($key, $value, $no_time); +var_dump($rv); +?> +--EXPECTF-- +Notice: Undefined variable: no_key in %s +bool(false) + +Notice: Undefined variable: no_value in %s +bool(true) + +Notice: Undefined variable: no_key in %s + +Notice: Undefined variable: no_value in %s +bool(false) + +Notice: Undefined variable: no_time in %s +bool(true) diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/user-flags.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/user-flags.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/user-flags.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/user-flags.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,107 @@ +--TEST-- +Memcached user flags +--SKIPIF-- + +--FILE-- +get($key, null, Memcached::GET_EXTENDED)['flags']; +} + +define ('FLAG_1', 1); +define ('FLAG_2', 2); +define ('FLAG_4', 4); +define ('FLAG_32', 32); +define ('FLAG_64', 64); +define ('FLAG_TOO_LARGE', pow(2, 16)); + +include dirname (__FILE__) . '/config.inc'; +$m = memc_get_instance (array (Memcached::OPT_BINARY_PROTOCOL => true)); + +$key = uniqid ('udf_test_'); + +// Set with flags off +$m->set ($key, '1', 10); +$v = $m->get($key, null, Memcached::GET_EXTENDED); +var_dump($v); + +// Set flags on +$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1); +$m->set ($key, '1', 10); +$m->get($key); +check_flags(get_flags($m, $key), array(FLAG_1)); + +// Multiple flags +$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1 | FLAG_2 | FLAG_4); +$m->set ($key, '1', 10); +$m->get($key); +check_flags(get_flags($m, $key), array(FLAG_1, FLAG_2, FLAG_4)); + +// Even more flags +$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1 | FLAG_2 | FLAG_4 | FLAG_32 | FLAG_64); +$m->set ($key, '1', 10); +$m->get($key); +check_flags(get_flags($m, $key), array(FLAG_1, FLAG_2, FLAG_4, FLAG_32, FLAG_64)); + +// User flags with get multi +$values = array( + uniqid ('udf_test_multi_') => "first", + uniqid ('udf_test_multi_') => "second", + uniqid ('udf_test_multi_') => "third", +); + +$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_2 | FLAG_4); +$m->setMulti($values); +$m->getMulti(array_keys($values)); +$flags = $m->getMulti(array_keys($values), Memcached::GET_EXTENDED); + +foreach (array_keys($values) as $key) { + check_flags($flags[$key]['flags'], array(FLAG_2, FLAG_4)); +} + +// User flags with compression on +$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_1 | FLAG_2 | FLAG_4); +$m->setOption(Memcached::OPT_COMPRESSION, true); +$m->setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_FASTLZ); + +$m->set ($key, '1', 10); +$m->get($key); +check_flags(get_flags($m, $key), array(FLAG_1, FLAG_2, FLAG_4)); + + +// Too large flags +$m->setOption(Memcached::OPT_USER_FLAGS, FLAG_TOO_LARGE); + +echo "DONE TEST\n"; +?> +--EXPECTF-- +array(3) { + ["value"]=> + string(1) "1" + ["cas"]=> + int(%d) + ["flags"]=> + int(0) +} +Flags OK +Flags OK +Flags OK +Flags OK +Flags OK +Flags OK +Flags OK + +Warning: Memcached::setOption(): MEMC_OPT_USER_FLAGS must be < 65535 in %s on line %d +DONE TEST \ No newline at end of file diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/vbucket.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/vbucket.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/vbucket.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/vbucket.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,48 @@ +--TEST-- +Memcached virtual buckets +--SKIPIF-- + +--FILE-- + Memcached::DISTRIBUTION_VIRTUAL_BUCKET + )); + +var_dump ($m->setBucket (array (1, 2, 3), null, 2)); + +var_dump ($m->setBucket (array (1,2,2), array (1,2,2), 2)); + +var_dump ($m->setBucket (array ('a', 'b', 'c'), null, 2)); + +var_dump ($m->setBucket (array (), null, 2)); + +var_dump ($m->setBucket (array (), array (), -1)); + +var_dump ($m->setBucket (null, array (), -1)); + +var_dump ($m->setBucket (array (-1), array (-1), 1)); + +echo "OK\n"; + +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) + +Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d +bool(false) + +Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d +bool(false) + +Warning: Memcached::setBucket() expects parameter 1 to be array, null given in %s on line %d +NULL + +Warning: Memcached::setBucket(): the map must contain positive integers in %s on line %d +bool(false) +OK diff -Nru php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/version.phpt php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/version.phpt --- php-memcached-3.1.3+2.2.0/memcached-3.1.4/tests/version.phpt 1970-01-01 00:00:00.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/memcached-3.1.4/tests/version.phpt 2019-10-06 16:04:32.000000000 +0000 @@ -0,0 +1,18 @@ +--TEST-- +Get version +--SKIPIF-- + +--FILE-- +getVersion ()); + +echo "OK" . PHP_EOL; +?> +--EXPECTF-- +array(1) { + ["%s:%d"]=> + string(%d) "%d.%d.%d" +} +OK diff -Nru php-memcached-3.1.3+2.2.0/package.xml php-memcached-3.1.4+2.2.0/package.xml --- php-memcached-3.1.3+2.2.0/package.xml 2018-12-24 21:41:46.000000000 +0000 +++ php-memcached-3.1.4+2.2.0/package.xml 2019-10-06 16:04:32.000000000 +0000 @@ -1,5 +1,5 @@ - + memcached pecl.php.net PHP extension for interfacing with memcached via libmemcached library @@ -22,10 +22,10 @@ aaron@serendipity.cx yes - 2018-12-24 - + 2019-10-06 + - 3.1.3 + 3.1.4 3.0.0 @@ -34,13 +34,16 @@ PHP -PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for +PHP 7.0 - 7.1 - 7.2 - 7.3 - 7.4 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued and the oldest actively tested version is 1.0.8. It is highly recommended to use version 1.0.18 of libmemcached. Fixes - * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) + * Test on PHP 7.4 as well as 8.0 (#440) + * Fix segfault for unknown memcached flags (#431) + * Update documented defaults for sess_lock_retries (#432) + * Remove stray instances of the TSRMLS_CC macro for PHP 8 compatibility (#444) @@ -140,19 +143,19 @@ - + - + - + - - + + - + @@ -200,6 +203,26 @@ stable + stable + + + 3.1.3 + 3.0.0 + + 2018-12-22 + +PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.8. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) + + + + + stable stable