Giter Club home page Giter Club logo

php-memcached's Introduction

Build Status

Build Status

Description

This is the PECL memcached extension, using the libmemcached library to connect to memcached servers.

memcached 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 - 8.3 or higher.
  • 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 or the new libmemcached-awesome version 1.0.18 or higher is recommended for best performance and compatibility with memcached servers.

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 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.

php-memcached's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-memcached's Issues

JSON serialization doesn't appear to work

I'm trying to use JSON serialization, by setting memcached.serializer = "json". However, when checking in memcached, I can see the serialisation is using PHP:

userid|i:1;username|s:3:"bob";

Whereas what I was expecting was:

{"userid":1,"username":"bob"}

Am I understanding the usage of memcached.serializer correctly? Should the data in memcached be JSON formatted?

Here are my php.ini settings:

memcached

memcached support => enabled
Version => 2.0.1
libmemcached version => 0.44
Session support => yes
igbinary support => no
json support => yes

Directive => Local Value => Master Value
memcached.compression_factor => 1.3 => 1.3
memcached.compression_threshold => 2000 => 2000
memcached.compression_type => fastlz => fastlz
memcached.serializer => json_array => json_array
memcached.sess_binary => 0 => 0
memcached.sess_lock_wait => 150000 => 150000
memcached.sess_locking => 1 => 1
memcached.sess_prefix => memc.sess.key. => memc.sess.key.

session

Session Support => enabled
Registered save handlers => files user memcache memcached redis 
Registered serializer handlers => php php_binary wddx 

Directive => Local Value => Master Value
session.auto_start => Off => Off
session.bug_compat_42 => Off => Off
session.bug_compat_warn => Off => Off
session.cache_expire => 180 => 180
session.cache_limiter => nocache => nocache
session.cookie_domain => no value => no value
session.cookie_httponly => Off => Off
session.cookie_lifetime => 0 => 0
session.cookie_path => / => /
session.cookie_secure => Off => Off
session.entropy_file => no value => no value
session.entropy_length => 0 => 0
session.gc_divisor => 1000 => 1000
session.gc_maxlifetime => 1440 => 1440
session.gc_probability => 0 => 0
session.hash_bits_per_character => 5 => 5
session.hash_function => 0 => 0
session.name => PHPSESSID => PHPSESSID
session.referer_check => no value => no value
session.save_handler => memcached => memcached
session.save_path => localhost:11211 => localhost:11211
session.serialize_handler => php => php
session.use_cookies => On => On
session.use_only_cookies => On => On
session.use_trans_sid => 0 => 0

And PHP version:

php --version
PHP 5.3.10-1ubuntu3.5 with Suhosin-Patch (cli) (built: Jan 18 2013 23:40:19) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

I'm not sure why it says with Suhosin patch, I've checked and I don't have the suhosin extension installed.

Error during Memcached::get() masked by NOTFOUND

From pecl-memcached Bug #61466:

Description:

If an error occurs while attempting to perform a Memcached::get(), the result code will be set to RES_NOTFOUND. However, that result is actually masking the more important error (such as connection failure, timed out, server is marked dead, etc...)

Replacing the Memcached::get() call with a Memcached::set() call results in the correct result code being reported.

Test script:

<?php

$mc = new Memcached();
$mc->addServer('10.2.3.4', 5555); // Server should not exist

$mc->setOption( Memcached::OPT_RETRY_TIMEOUT, 1 );

while (true)
{
  // Note how it changes if you remove either the get() call or the set() call.
  // Having only get(), results in "NOT FOUND" printed repeatedly.

  $result = $mc->get('foo');
  echo var_export( $result, true ), "; ", $mc->getResultCode( ), ': ', $mc->getResultMessage( ), "\n";

  $result = $mc->set('foo', 1, 0);
  echo var_export( $result, true ), "; ", $mc->getResultCode( ), ': ', $mc->getResultMessage( ), "\n";

  usleep(250000);
}

Expected result:

false; 3: CONNECTION FAILURE
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 3: CONNECTION FAILURE
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 35: SERVER IS MARKED DEAD
false; 3: CONNECTION FAILURE
...

Actual result:

false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
false; 16: NOT FOUND
false; 35: SERVER IS MARKED DEAD
...

Additional Info

Try commenting out the get() lines and see that the expected result is achieved (because set() does not mask the error). And commenting out the set() lines results in only "NOT FOUND" being printed.

increment function adds white space to value

memcached-server - 1.4.5
php-memcached - 2.0.1
libmemcached - 1.0.8
php - 5.3.6

When I increment a key using default value, it's size is shown as 22 in telnet interface. Subsequent increments add white-spaces to the value.
Here's the code:

$bucketOps = new Memcached();
$bucketOps->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$bucketOps->addServer('10.90.15.104', 11211);
$bucketOps->addServer('10.90.15.104', 11311);

$bucketOps->set('foo2', 'bar2');
$bucketOps->increment('sample-cnt', 1, 1);

Here's how it looks in telnet

get sample-cnt
VALUE sample-cnt 0 22
1END

Notice the size of the value. Then I run the code again, so this time it should increment the value to 2. It does that but here's how it looks in telnet again

get sample-cnt
VALUE sample-cnt 0 22
2 END

Notice the white spaces between the value and END.
I don't know why this is happening. Please help

Support for more granular session lock behaviors [possible patch]

I do programing with a large LMS, Moodle (moodle.org), and support has been added for memcached sessions to improve performance, but something we have noticed is that both lock max wait and lock expiration are tied to max_execution_time at the time of session_start(), which is not optimal for us (and I'm sure we're not alone).

I propose two new settings, memcached.sess_lock_max_wait and memcached.sess_lock_expire which allow the setting of the max time to wait for a lock before dying, and the time for a lock to expire, respectively.

I've done a first pass of the patch at:
https://github.com/merrill-oakland/php-memcached/compare/c10de3699faa3ecb4cb6861d6c92157e0c7e18ce...sessionlocks

Current behavior should be maintained with settings of 0 (or unset).
I've never written stuff for this project, so I followed the coding styles that I observed, but I may have missed something. I also need to look at the test system to see about adding tests, but the same tests pass/fail both before and after this patch.

Thoughts? Recommendations? Is this a possibility?

getMulti can return non-unique keys

Description:

When the binary protocol is enabled and when passing the 3rd
parameter, Memcached::GET_PRESERVE_ORDER, to getMulti(), the
resulting array contains non-unique keys.

In other words, each key is represented twice in the result.
One is set to null and the other is set to the value of
whatever was stored in memcached.

getResultMessage() shows "SUCCESS".

I'm actually on php 5.3.8

Reproduce code:

$MC = new Memcached;
$MC->setOption(Memcached::OPT_BINARY_PROTOCOL, true); // Removing this
causes the code to work, but at the 'expense' of reverting to the ASCII
protocol
$MC->addServer('localhost', 11211);

$KeyList = Array (
'key1'
,'key2'
,'key3'
,'key4'
);

$Test = Array();
foreach ($KeyList as $k) {
$Test[$k] = 'stored value for '.$k;
}

// This block uses the *Multi() functions
$MC->setMulti($Test, 3600);

sleep(1);
$null = null;
$theList = $MC->getMulti($KeyList, $null, Memcached::GET_PRESERVE_ORDER);

var_dump($theList);

Expected result:

var_dump should shows:

array
'key1' => 'stored value for key1'
'key2' => 'stored value for key2'
'key3' => 'stored value for key3'
'key4' => 'stored value for key4'

Actual result:

var_dump shows:

array
'key1' => null
'key2' => null
'key3' => null
'key4' => null
'key1' => 'stored value for key1'
'key2' => 'stored value for key2'
'key3' => 'stored value for key3'
'key4' => 'stored value for key4'

Compile of 2.1.0 fails on Ubuntu Precise

Make fails on

In file included from /tmp/memcached-2.1.0/php_memcached.h:22:0,
                 from /tmp/memcached-2.1.0/php_memcached.c:47:
/tmp/memcached-2.1.0/php_libmemcached_compat.h:5:40: fatal error: libmemcached-1.0/memcached.h: No such file or directory

The best I can tell is the use of #include <libmemcached-1.0/memcached.h> is what is causing the issue when my libmemcached is installed at /usr/include/libmemcached/memcached.h. Even specifying the prefix using --with-libmemcached-dir= does not fix the issue.

Rolling back to 2.0.1 will install properly via PECL or using a manual compile/install (i.e. pecl install -f memcached-2.0.1).

Installed dependencies:

apt-show-versions libmemcached-dev
libmemcached-dev/precise uptodate 0.44-1.1build1
apt-show-versions libevent-dev
libevent-dev/precise uptodate 2.0.16-stable-1

Failed to write, and not due to blocking: Connection reset by peer

I am using memcached sessions on 10 web heads. My memcached logs are filled with the following error message:

Failed to write, and not due to blocking: Connection reset by peer

It's very inconsistent whether the sessions work or not. Typically everything is fine and then all of a sudden some users are logged out.

Any suggestions on how to debug this issue?

Memcached 2.0.1 build failed

The following error happens when executing make:

/bin/sh /root/build/memcached-2.0.1/libtool --mode=compile cc -I/opt/php-5.4.0/include/php -I/opt/php-5.4.0/include/php -I. -I/root/build/memcached-2.0.1 -DPHP_ATOM_INC -I/root/build/memcached-2.0.1/include -I/root/build/memcached-2.0.1/main -I/root/build/memcached-2.0.1 -I/opt/php-5.4.0/include/php -I/opt/php-5.4.0/include/php/main -I/opt/php-5.4.0/include/php/TSRM -I/opt/php-5.4.0/include/php/Zend -I/opt/php-5.4.0/include/php/ext -I/opt/php-5.4.0/include/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /root/build/memcached-2.0.1/php_memcached.c -o php_memcached.lo
mkdir .libs
cc -I/opt/php-5.4.0/include/php -I/opt/php-5.4.0/include/php -I. -I/root/build/memcached-2.0.1 -DPHP_ATOM_INC -I/root/build/memcached-2.0.1/include -I/root/build/memcached-2.0.1/main -I/root/build/memcached-2.0.1 -I/opt/php-5.4.0/include/php -I/opt/php-5.4.0/include/php/main -I/opt/php-5.4.0/include/php/TSRM -I/opt/php-5.4.0/include/php/Zend -I/opt/php-5.4.0/include/php/ext -I/opt/php-5.4.0/include/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /root/build/memcached-2.0.1/php_memcached.c -fPIC -DPIC -o .libs/php_memcached.o
/root/build/memcached-2.0.1/php_memcached.c: In function ‘zim_Memcached___construct’:
/root/build/memcached-2.0.1/php_memcached.c:415: warning: assignment makes pointer from integer without a cast
/root/build/memcached-2.0.1/php_memcached.c: In function ‘php_memc_get_impl’:
/root/build/memcached-2.0.1/php_memcached.c:554: warning: passing argument 4 of ‘memcached_mget_by_key’ from incompatible pointer type
/usr/include/libmemcached/memcached_get.h:38: note: expected ‘char *’ but argument is of type ‘const char *
/root/build/memcached-2.0.1/php_memcached.c:615: warning: passing argument 4 of ‘memcached_mget_by_key’ from incompatible pointer type
/usr/include/libmemcached/memcached_get.h:38: note: expected ‘char *’ but argument is of type ‘const char *
/root/build/memcached-2.0.1/php_memcached.c: In function ‘php_memc_getMulti_impl’:
/root/build/memcached-2.0.1/php_memcached.c:762: warning: passing argument 4 of ‘memcached_mget_by_key’ from incompatible pointer type
/usr/include/libmemcached/memcached_get.h:38: note: expected ‘char *’ but argument is of type ‘const char *
/root/build/memcached-2.0.1/php_memcached.c: In function ‘php_memc_getDelayed_impl’:
/root/build/memcached-2.0.1/php_memcached.c:936: warning: passing argument 4 of ‘memcached_mget_by_key’ from incompatible pointer type
/usr/include/libmemcached/memcached_get.h:38: note: expected ‘char *’ but argument is of type ‘const char *
/root/build/memcached-2.0.1/php_memcached.c: In function ‘zim_Memcached_getServerList’:
/root/build/memcached-2.0.1/php_memcached.c:1944: warning: assignment from incompatible pointer type
/root/build/memcached-2.0.1/php_memcached.c: In function ‘zim_Memcached_getStats’:
/root/build/memcached-2.0.1/php_memcached.c:2058: warning: assignment from incompatible pointer type
/root/build/memcached-2.0.1/php_memcached.c: In function ‘zim_Memcached_getVersion’:
/root/build/memcached-2.0.1/php_memcached.c:2091: warning: assignment from incompatible pointer type
/root/build/memcached-2.0.1/php_memcached.c: In function ‘zim_Memcached_getAllKeys’:
/root/build/memcached-2.0.1/php_memcached.c:2115: warning: assignment from incompatible pointer type
/root/build/memcached-2.0.1/php_memcached.c: In function ‘php_memc_do_serverlist_callback’:
/root/build/memcached-2.0.1/php_memcached.c:2585: warning: passing argument 4 of ‘add_assoc_string_ex’ discards qualifiers from pointer target type
/opt/php-5.4.0/include/php/Zend/zend_API.h:374: note: expected ‘char ’ but argument is of type ‘const char *’
/root/build/memcached-2.0.1/php_memcached.c: In function ‘php_memc_register_constants’:
/root/build/memcached-2.0.1/php_memcached.c:3680: error: ‘MEMCACHED_BEHAVIOR_TCP_KEEPALIVE’ undeclared (first use in this function)
/root/build/memcached-2.0.1/php_memcached.c:3680: error: (Each undeclared identifier is reported only once
/root/build/memcached-2.0.1/php_memcached.c:3680: error: for each function it appears in.)
make: *
* [php_memcached.lo] Error 1

I'm using libmemcached and libmemcached-devel versions 0.31-1.
Note: configure was executed with the "--enable-igbinary" option (igbinary installed from pecl).

increment can't bigger than 4294967295

$o = new Memcached();
$o->addServers( array(
array('127.0.0.1', 11211, 100)
));
$o->set('ddd', 0, 0);

$x = $o->increment('ddd', 4294967295); //OK
$x = $o->increment('ddd', 4294967296); //Error.

system is 64Bit.

persistent_id doesn't works as expected

What does persistent_id means,
it could reuse/share the same existed connection in one foo.php script?

I have read following documentations couple of times, it doesn't help.
http://www.php.net/manual/en/class.memcached.php
https://github.com/php-memcached-dev/php-memcached/blob/master/tests/construct_persistent.phpt

I do some tests, everything I do is making me more confused.


Test envorinment:

  • memcached-1.4.15
  • php-5.4.10
  • libmemcached-1.0.11
  • Ubuntu 12.04 64bit

TCP conn state watch script

cat watch_tw.sh 
#!/usr/bin/env bash

while true; do
    ss -s | grep ^TCP:
    sleep 1
done

Start memcached

memcached -v  -c 4096 -m 64 -p 11211 -u www-data

Tset I

ab -c 100 -n 1000 http://t.m.com/index-without-pool.php

ab reports

Percentage of the requests served within a certain time (ms)
  50%     38
  66%     41
  75%     42
  80%     43
  90%     45
  95%     46
  98%     52
  99%     56
100%     59 (longest request)

ss reports

TCP:   2024 (estab 3, closed 2001, orphaned 0, synrecv 0, timewait 2001/0), ports 0

after 40 seconds, ss reports

TCP:   23 (estab 3, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0

It is as expected.

Test II

ab -c 100 -n 1000 http://t.m.com/index-pool.php

ab reports

Percentage of the requests served within a certain time (ms)
  50%    558
  66%    607
  75%    626
  80%    636
  90%    664
  95%    690
  98%    723
  99%    744
100%    772 (longest request)

ss reports

TCP:   2247 (estab 451, closed 1776, orphaned 0, synrecv 0, timewait 1776/0), ports 0

after 40 seconds, ss reports

TCP:   471 (estab 451, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0

Questions

  • Why it is slowly?
  • Why memcached keep connection after php-fpm process has terminated?

Environment settings

index-without-pool.php

<?php

$mc = new Memcached();
$mc->addServer("127.0.0.1", 11211);
$mc->setOption(Memcached::OPT_CONNECT_TIMEOUT, 5);

$mc->set("a", "b");
$val = $mc->get("a");

if (!$val) {
   echo "get val failed";
}

$stats = $mc->getStats();

$curr_conns = $stats["127.0.0.1:11211"]["curr_connections"];
echo $curr_conns;

echo "\n";

index-pool.php

<?php

$mc = new Memcached("pool_test");
if (empty($sl)) {
  $mc->addServer("127.0.0.1", 11211);
  $mc->setOption(Memcached::OPT_CONNECT_TIMEOUT, 5);
}

$mc->set("a", "b");
$val = $mc->get("a");

if (!$val) {
   echo "get val failed";
}

$stats = $mc->getStats();
$curr_conns = $stats["127.0.0.1:11211"]["curr_connections"];
echo $curr_conns;

echo "\n";

php.ini

[PHP]
engine = On
short_open_tag = Off
asp_tags = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 17
disable_functions =
disable_classes =
zend.enable_gc = On
expose_php = On
max_execution_time = 10
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = On
html_errors = On
error_log = /usr/local/php/var/log/error.log
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 8M
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 2M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
[CLI Server]
cli_server.color = On
[Date]
date.timezone="UTC"
[filter]
[iconv]
[intl]
[sqlite]
[sqlite3]
[Pcre]
[Pdo]
[Pdo_mysql]
pdo_mysql.cache_size = 2000
pdo_mysql.default_socket=
[Phar]
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = On
[SQL]
sql.safe_mode = Off
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"
[MySQL]
mysql.allow_local_infile = On
mysql.allow_persistent = On
mysql.cache_size = 2000
mysql.max_persistent = -1
mysql.max_links = -1
mysql.default_port =
mysql.default_socket =
mysql.default_host =
mysql.default_user =
mysql.default_password =
mysql.connect_timeout = 60
mysql.trace_mode = Off
[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = On
[OCI8]
[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
[Sybase-CT]
sybct.allow_persistent = On
sybct.max_persistent = -1
sybct.max_links = -1
sybct.min_server_severity = 10
sybct.min_client_severity = 10
[bcmath]
bcmath.scale = 0
[browscap]
[Session]
session.save_handler = files
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.bug_compat_42 = On
session.bug_compat_warn = On
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
[MSSQL]
mssql.allow_persistent = On
mssql.max_persistent = -1
mssql.max_links = -1
mssql.min_error_severity = 10
mssql.min_message_severity = 10
mssql.compatability_mode = Off
mssql.secure_connection = Off
[Assertion]
[COM]
[mbstring]
[gd]
[exif]
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
[sysvshm]
[ldap]
ldap.max_links = -1
[mcrypt]
[dba]
[xhprof]
extension=xhprof.so
xhprof.output_dir=/tmp/xhprof
[memcached]
extension=memcached.so

php-fpm.conf

[global]
pid = /usr/local/php/var/run/php-fpm.pid
error_log = /usr/local/php/var/log/php-fpm.log
log_level = warning

rlimit_files = 10240

rlimit_core = 0
[www]
user = www-data
group = www-data
listen = /dev/shm/php-fpm.sock

pm = dynamic
pm.max_children = 512
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

pm.status_path = /status

ping.path = /ping
ping.response = pong

slowlog = /usr/local/php/var/log/$pool.log.slow

request_slowlog_timeout = 3
request_terminate_timeout = 10

chdir = /var/www

sysctl -a

net.ipv4.route.gc_thresh = 131072
net.ipv4.route.max_size = 2097152
net.ipv4.route.gc_min_interval = 0
net.ipv4.route.gc_min_interval_ms = 500
net.ipv4.route.gc_timeout = 300
net.ipv4.route.gc_interval = 60
net.ipv4.route.redirect_load = 5
net.ipv4.route.redirect_number = 9
net.ipv4.route.redirect_silence = 5120
net.ipv4.route.gc_elasticity = 8
net.ipv4.route.mtu_expires = 600
net.ipv4.route.min_pmtu = 552
net.ipv4.route.min_adv_mss = 256
net.ipv4.neigh.default.mcast_solicit = 3
net.ipv4.neigh.default.ucast_solicit = 3
net.ipv4.neigh.default.app_solicit = 0
net.ipv4.neigh.default.retrans_time = 100
net.ipv4.neigh.default.base_reachable_time = 30
net.ipv4.neigh.default.delay_first_probe_time = 5
net.ipv4.neigh.default.gc_stale_time = 60
net.ipv4.neigh.default.unres_qlen = 3
net.ipv4.neigh.default.proxy_qlen = 64
net.ipv4.neigh.default.anycast_delay = 100
net.ipv4.neigh.default.proxy_delay = 80
net.ipv4.neigh.default.locktime = 100
net.ipv4.neigh.default.retrans_time_ms = 1000
net.ipv4.neigh.default.base_reachable_time_ms = 30000
net.ipv4.neigh.default.gc_interval = 30
net.ipv4.neigh.default.gc_thresh1 = 128
net.ipv4.neigh.default.gc_thresh2 = 512
net.ipv4.neigh.default.gc_thresh3 = 1024
net.ipv4.neigh.lo.mcast_solicit = 3
net.ipv4.neigh.lo.ucast_solicit = 3
net.ipv4.neigh.lo.app_solicit = 0
net.ipv4.neigh.lo.retrans_time = 100
net.ipv4.neigh.lo.base_reachable_time = 30
net.ipv4.neigh.lo.delay_first_probe_time = 5
net.ipv4.neigh.lo.gc_stale_time = 60
net.ipv4.neigh.lo.unres_qlen = 3
net.ipv4.neigh.lo.proxy_qlen = 64
net.ipv4.neigh.lo.anycast_delay = 100
net.ipv4.neigh.lo.proxy_delay = 80
net.ipv4.neigh.lo.locktime = 100
net.ipv4.neigh.lo.retrans_time_ms = 1000
net.ipv4.neigh.lo.base_reachable_time_ms = 30000
net.ipv4.neigh.eth0.mcast_solicit = 3
net.ipv4.neigh.eth0.ucast_solicit = 3
net.ipv4.neigh.eth0.app_solicit = 0
net.ipv4.neigh.eth0.retrans_time = 100
net.ipv4.neigh.eth0.base_reachable_time = 30
net.ipv4.neigh.eth0.delay_first_probe_time = 5
net.ipv4.neigh.eth0.gc_stale_time = 60
net.ipv4.neigh.eth0.unres_qlen = 3
net.ipv4.neigh.eth0.proxy_qlen = 64
net.ipv4.neigh.eth0.anycast_delay = 100
net.ipv4.neigh.eth0.proxy_delay = 80
net.ipv4.neigh.eth0.locktime = 100
net.ipv4.neigh.eth0.retrans_time_ms = 1000
net.ipv4.neigh.eth0.base_reachable_time_ms = 30000
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_retrans_collapse = 1
net.ipv4.ip_default_ttl = 64
net.ipv4.ip_no_pmtu_disc = 0
net.ipv4.ip_nonlocal_bind = 0
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.ip_dynaddr = 0
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 15
net.ipv4.tcp_fin_timeout = 60
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_abort_on_overflow = 0
net.ipv4.tcp_stdurg = 0
net.ipv4.tcp_rfc1337 = 0
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.ip_local_port_range = 32768    61000
net.ipv4.ip_local_reserved_ports = 
net.ipv4.igmp_max_memberships = 20
net.ipv4.igmp_max_msf = 10
net.ipv4.inet_peer_threshold = 65664
net.ipv4.inet_peer_minttl = 120
net.ipv4.inet_peer_maxttl = 600
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_fack = 1
net.ipv4.tcp_reordering = 3
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_mem = 90411    120551  180822
net.ipv4.tcp_wmem = 4096    16384   3857632
net.ipv4.tcp_rmem = 4096    87380   3857632
net.ipv4.tcp_app_win = 31
net.ipv4.tcp_adv_win_scale = 1
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_frto = 2
net.ipv4.tcp_frto_response = 0
net.ipv4.tcp_low_latency = 0
net.ipv4.tcp_no_metrics_save = 0
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_tso_win_divisor = 3
net.ipv4.tcp_congestion_control = cubic
net.ipv4.tcp_abc = 0
net.ipv4.tcp_mtu_probing = 0
net.ipv4.tcp_base_mss = 512
net.ipv4.tcp_workaround_signed_windows = 0
net.ipv4.tcp_dma_copybreak = 4096
net.ipv4.tcp_slow_start_after_idle = 1
net.ipv4.cipso_cache_enable = 1
net.ipv4.cipso_cache_bucket_size = 10
net.ipv4.cipso_rbm_optfmt = 0
net.ipv4.cipso_rbm_strictvalid = 1
net.ipv4.tcp_available_congestion_control = cubic reno
net.ipv4.tcp_allowed_congestion_control = cubic reno
net.ipv4.tcp_max_ssthresh = 0
net.ipv4.tcp_cookie_size = 0
net.ipv4.tcp_thin_linear_timeouts = 0
net.ipv4.tcp_thin_dupack = 0
net.ipv4.udp_mem = 90411    120551  180822
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096
net.ipv4.conf.all.forwarding = 0
net.ipv4.conf.all.mc_forwarding = 0
net.ipv4.conf.all.accept_redirects = 1
net.ipv4.conf.all.secure_redirects = 1
net.ipv4.conf.all.shared_media = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.send_redirects = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_local = 0
net.ipv4.conf.all.src_valid_mark = 0
net.ipv4.conf.all.proxy_arp = 0
net.ipv4.conf.all.medium_id = 0
net.ipv4.conf.all.bootp_relay = 0
net.ipv4.conf.all.log_martians = 0
net.ipv4.conf.all.tag = 0
net.ipv4.conf.all.arp_filter = 0
net.ipv4.conf.all.arp_announce = 0
net.ipv4.conf.all.arp_ignore = 0
net.ipv4.conf.all.arp_accept = 0
net.ipv4.conf.all.arp_notify = 0
net.ipv4.conf.all.proxy_arp_pvlan = 0
net.ipv4.conf.all.disable_xfrm = 0
net.ipv4.conf.all.disable_policy = 0
net.ipv4.conf.all.force_igmp_version = 0
net.ipv4.conf.all.promote_secondaries = 0
net.ipv4.conf.default.forwarding = 0
net.ipv4.conf.default.mc_forwarding = 0
net.ipv4.conf.default.accept_redirects = 1
net.ipv4.conf.default.secure_redirects = 1
net.ipv4.conf.default.shared_media = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.send_redirects = 1
net.ipv4.conf.default.accept_source_route = 1
net.ipv4.conf.default.accept_local = 0
net.ipv4.conf.default.src_valid_mark = 0
net.ipv4.conf.default.proxy_arp = 0
net.ipv4.conf.default.medium_id = 0
net.ipv4.conf.default.bootp_relay = 0
net.ipv4.conf.default.log_martians = 0
net.ipv4.conf.default.tag = 0
net.ipv4.conf.default.arp_filter = 0
net.ipv4.conf.default.arp_announce = 0
net.ipv4.conf.default.arp_ignore = 0
net.ipv4.conf.default.arp_accept = 0
net.ipv4.conf.default.arp_notify = 0
net.ipv4.conf.default.proxy_arp_pvlan = 0
net.ipv4.conf.default.disable_xfrm = 0
net.ipv4.conf.default.disable_policy = 0
net.ipv4.conf.default.force_igmp_version = 0
net.ipv4.conf.default.promote_secondaries = 0
net.ipv4.conf.lo.forwarding = 0
net.ipv4.conf.lo.mc_forwarding = 0
net.ipv4.conf.lo.accept_redirects = 1
net.ipv4.conf.lo.secure_redirects = 1
net.ipv4.conf.lo.shared_media = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.lo.send_redirects = 1
net.ipv4.conf.lo.accept_source_route = 1
net.ipv4.conf.lo.accept_local = 0
net.ipv4.conf.lo.src_valid_mark = 0
net.ipv4.conf.lo.proxy_arp = 0
net.ipv4.conf.lo.medium_id = 0
net.ipv4.conf.lo.bootp_relay = 0
net.ipv4.conf.lo.log_martians = 0
net.ipv4.conf.lo.tag = 0
net.ipv4.conf.lo.arp_filter = 0
net.ipv4.conf.lo.arp_announce = 0
net.ipv4.conf.lo.arp_ignore = 0
net.ipv4.conf.lo.arp_accept = 0
net.ipv4.conf.lo.arp_notify = 0
net.ipv4.conf.lo.proxy_arp_pvlan = 0
net.ipv4.conf.lo.disable_xfrm = 1
net.ipv4.conf.lo.disable_policy = 1
net.ipv4.conf.lo.force_igmp_version = 0
net.ipv4.conf.lo.promote_secondaries = 0
net.ipv4.conf.eth0.forwarding = 0
net.ipv4.conf.eth0.mc_forwarding = 0
net.ipv4.conf.eth0.accept_redirects = 1
net.ipv4.conf.eth0.secure_redirects = 1
net.ipv4.conf.eth0.shared_media = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.eth0.send_redirects = 1
net.ipv4.conf.eth0.accept_source_route = 1
net.ipv4.conf.eth0.accept_local = 0
net.ipv4.conf.eth0.src_valid_mark = 0
net.ipv4.conf.eth0.proxy_arp = 0
net.ipv4.conf.eth0.medium_id = 0
net.ipv4.conf.eth0.bootp_relay = 0
net.ipv4.conf.eth0.log_martians = 0
net.ipv4.conf.eth0.tag = 0
net.ipv4.conf.eth0.arp_filter = 0
net.ipv4.conf.eth0.arp_announce = 0
net.ipv4.conf.eth0.arp_ignore = 0
net.ipv4.conf.eth0.arp_accept = 0
net.ipv4.conf.eth0.arp_notify = 0
net.ipv4.conf.eth0.proxy_arp_pvlan = 0
net.ipv4.conf.eth0.disable_xfrm = 0
net.ipv4.conf.eth0.disable_policy = 0
net.ipv4.conf.eth0.force_igmp_version = 0
net.ipv4.conf.eth0.promote_secondaries = 0
net.ipv4.ip_forward = 0
net.ipv4.xfrm4_gc_thresh = 1048576
net.ipv4.ipfrag_high_thresh = 262144
net.ipv4.ipfrag_low_thresh = 196608
net.ipv4.ipfrag_time = 30
net.ipv4.icmp_echo_ignore_all = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ratelimit = 1000
net.ipv4.icmp_ratemask = 6168
net.ipv4.rt_cache_rebuild_count = 4
net.ipv4.ping_group_range = 1   0
net.ipv4.ipfrag_secret_interval = 600
net.ipv4.ipfrag_max_dist = 64

Doing everything twice

Running on Mac OS X 10.7
Memcached server 1.4.13
Latest build of php-memcached from PECL

Take the following code:

$m = new Memcached();
$m->addServer("127.0.0.1", 11211);
$m->set("hi", "hello");

If I run memcached with -vvv I get the following:

<31 new auto-negotiating client connection
31: going from conn_new_cmd to conn_waiting
31: going from conn_waiting to conn_read
31: going from conn_read to conn_parse_cmd
31: Client using the ascii protocol
<31 set hi 0 0 5
31: going from conn_parse_cmd to conn_nread
> NOT FOUND hi
>31 STORED
31: going from conn_nread to conn_write
31: going from conn_write to conn_new_cmd
31: going from conn_new_cmd to conn_waiting
31: going from conn_waiting to conn_read
31: going from conn_read to conn_parse_cmd
<31 quit
31: going from conn_parse_cmd to conn_closing
<31 connection closed.
<31 new auto-negotiating client connection
31: going from conn_new_cmd to conn_waiting
31: going from conn_waiting to conn_read
31: going from conn_read to conn_parse_cmd
31: Client using the ascii protocol
<31 set hi 0 0 5
31: going from conn_parse_cmd to conn_nread
> FOUND KEY hi
>31 STORED
31: going from conn_nread to conn_write
31: going from conn_write to conn_new_cmd
31: going from conn_new_cmd to conn_waiting
31: going from conn_waiting to conn_read
31: going from conn_read to conn_parse_cmd
<31 quit
31: going from conn_parse_cmd to conn_closing
<31 connection closed.

It seems to be doing everything twice?

I'm fairly sure this is a bug and that I haven't done anything wrong.

Thanks

PHP will not stop when there is a blank char in the key

As blank char is not allowed in the key of Memcache, so it's must be checked in store, delete and get method, but not only check the length of the key. I have made a patch which is based 2.0.1.

I hope this problem will be fixed in the next version. Thanks very much.

diff -ur memcached-2.0.1/php_memcached.c memcached-2.0.1-patch/php_memcached.c
--- memcached-2.0.1/php_memcached.c     2012-03-03 22:58:13.000000000 +0800
+++ memcached-2.0.1-patch/php_memcached.c       2012-09-21 15:56:15.000000000 +0800
@@ -532,7 +532,8 @@
        MEMC_METHOD_FETCH_OBJECT;
        i_obj->rescode = MEMCACHED_SUCCESS;

-       if (key_len == 0) {
+       char* blank_pos = strchr(key, ' ');
+       if (key_len == 0 || blank_pos != NULL) {
                i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
                RETURN_FROM_GET;
        }
@@ -1381,7 +1382,8 @@
        MEMC_METHOD_FETCH_OBJECT;
        i_obj->rescode = MEMCACHED_SUCCESS;

-       if (key_len == 0) {
+       char* blank_pos = strchr(key, ' ');
+       if (key_len == 0 || blank_pos != NULL) {
                i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
                RETURN_FALSE;
        }
@@ -1519,7 +1521,8 @@
        MEMC_METHOD_FETCH_OBJECT;
        i_obj->rescode = MEMCACHED_SUCCESS;

-       if (key_len == 0) {
+       char* blank_pos = strchr(key, ' ');
+       if (key_len == 0 || blank_pos != NULL) {
                i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
                RETURN_FALSE;
        }
@@ -1626,7 +1629,8 @@
        MEMC_METHOD_FETCH_OBJECT;
        i_obj->rescode = MEMCACHED_SUCCESS;

-       if (key_len == 0) {
+       char* blank_pos = strchr(key, ' ');
+       if (key_len == 0 || blank_pos != NULL) {
                i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
                RETURN_FALSE;
        }
@@ -1726,7 +1730,8 @@
        MEMC_METHOD_FETCH_OBJECT;
        i_obj->rescode = MEMCACHED_SUCCESS;

-       if (key_len == 0) {
+       char* blank_pos = strchr(key, ' ');
+       if (key_len == 0 || blank_pos != NULL) {
                i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
                RETURN_FALSE;
        }

Buffer writes not working as expected

Memcached::OPT_BUFFER_WRITES
Enables or disables buffered I/O. Enabling buffered I/O causes storage commands to "buffer" instead of being sent. Any action that retrieves data causes this buffer to be sent to the remote connection. Quitting the connection or closing down the connection will also cause the buffered data to be pushed to the remote connection.

Type: boolean, default: FALSE.

@ http://php.net/manual/en/memcached.constants.php

$ php -a
Interactive shell

php > $m = new \Memcached(); $m->addServer('....', 11211);
php > $m->set('test1', 10);
php > var_dump($m->get('test1'));
int(10)
php > $m->setOption(\Memcached::OPT_BUFFER_WRITES, true);
php > $m->set('test2', 20);
php > var_dump($m->get('test2'));
bool(false)
php > var_dump($m->getResultMessage());
string(9) "NOT FOUND"

I don't understand why there isn't a method like flush buffers, is already implemented at libmemcached:

http://docs.libmemcached.org/memcached_flush_buffers.html

PHP crash in get() when using persistence

I am getting intermittent problems when doing a get() - every few hundred requests PHP is crashing. I've narrowed it down to to a libmemcached/io.cc: No such file or directory error - but I only get this when PHP crashes. About 1% of my requests result in the crash (which caues HTTP 502).

My environment:
Ubuntu 12.04 64bit: Linux ryan 3.2.0-35-generic #55-Ubuntu SMP Wed Dec 5 17:42:16 UTC 2012 x86_64
nginx 1.2.4
php5-fpm:

/usr/sbin/php5-fpm -v
PHP 5.3.10-1ubuntu3.4 (fpm-fcgi) (built: Sep 12 2012 19:03:32)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with Suhosin v0.9.33, Copyright (c) 2007-2012, by SektionEins GmbH

PECL memcached 2.1.0:

memcached

memcached support => enabled
Version => 2.1.0
libmemcached version => 1.0.15
Session support => yes
igbinary support => yes
json support => no

Directive => Local Value => Master Value
memcached.compression_factor => 1.3 => 1.3
memcached.compression_threshold => 2000 => 2000
memcached.compression_type => fastlz => fastlz
memcached.serializer => igbinary => igbinary
memcached.sess_binary => 0 => 0
memcached.sess_lock_wait => 150000 => 150000
memcached.sess_locking => 1 => 1
memcached.sess_prefix => memc.sess.key. => memc.sess.key.

Lots of memory:

free -m
             total       used       free     shared    buffers     cached
Mem:         15982      15712        270          0        462       9171
-/+ buffers/cache:       6078       9903
Swap:         3813          0       3813

Here is test script to reproduce (test.php):

<?php

$m = new Memcached('mc');
$m->addServer('localhost', 11211);

$d = $m->get('foo');
if(empty($d)){
    $m->set('foo', 100);
}
var_export($d);
echo $m->getResultMessage(),"\n";

Here is my GDB: https://gist.github.com/4b966fa47cd0515ddf25
Here is the core dump: https://dl.dropbox.com/u/1374786/core-php5-fpm.19325.bz2

then simply run ab -n 1000 -c 20 http://localhost/test.php

Any idea what is going on? Is this really a bug in libmemcached?

get with cas token fails to fetch all results

Description:

When performing a get with a cas token requested a multi-get is performed
internally. After doing so
only the first result is fetched, leaving the final RES_END result on the
stack.
As per the
libmemcached documentation memcached_fetch_result should be called until it

returns NULL following a
multi-get.

In some circumstances this is not noticeable as libmemcached takes care of

flushing the receive buffers
accordingly, however certain subsequent operations will incorrectly return
the
left-over RES_END result.
I have seen this behaviour exhibited when performing a get with cas token
request followed by an add
operation though there may be other examples.

I have tested this with memcached extension version 2.0.0b2 using
libmemcached
0.53 and 1.0.2, though I
believe the issue also exists with earlier versions.

Please find attached a patch against 2.0.0b2 to address this issue which
both
resolves the primary issue
and also simplifies the call in the case that a cas token is not required
by
calling
memcached_get_by_key.

Deprecated option messages from libmemcached not shown

Messages about deprecated options aren't passed from libmemcached to php-memcached

Running this:

echo '$m = new Memcached();$m->setOption(Memcached::OPT_CACHE_LOOKUPS, true);' | php -a

Generates a warning but with no information:

Warning: Memcached::setOption(): error setting memcached option in php shell code on line 1

This option has been deprecated for a while: http://docs.libmemcached.org/memcached_behavior.html?highlight=cache_lookups#MEMCACHED_BEHAVIOR_CACHE_LOOKUPS

And libmemcached gives an explanation in the error message but unfortunately that's lost in PHP:
http://bazaar.launchpad.net/~tangent-org/libmemcached/trunk/view/head:/libmemcached/behavior.cc

memcached 2.1.0 requires libmemcached 1.0.10

Latest version use memcached_server_*_version which are not available in libmemcached < 1.0.10 (tested with 1.0.8)

This only cast warning during build.
.../php_memcached.c:2646:5: warning: implicit declaration of function 'memcached_server_major_version' [-Wimplicit-function-declaration]
.../php_memcached.c:2647:5: warning: implicit declaration of function 'memcached_server_minor_version' [-Wimplicit-function-declaration]
.../php_memcached.c:2648:5: warning: implicit declaration of function 'memcached_server_micro_version' [-Wimplicit-function-declaration]

So build succeed, but created extension is unusable.
PHP Warning: PHP Startup: Unable to load dynamic library 'modules/memcached.so' - modules/memcached.so: undefined symbol: memcached_server_micro_version in Unknown on line 0

1/ I think this should be documented

2/ it will be great to detect this at configure time

Per example, adding in config.m4, after AC_MSG_RESULT([$PHP_LIBMEMCACHED_DIR])

O_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -L$PHP_LIBMEMCACHED_DIR/$PHP_LIBDIR"
AC_CHECK_LIB(memcached, memcached_server_major_version, , AC_MSG_ERROR([memcached support requires libmemcached >= 1.0.10]))
LDFLAGS=$O_LDFLAGS

increment function working incorrectly (with binary protocol)

5.4.3 64 bit

increment / decrement operations failing with binary protocol in the following
scenario.

add operation returns incorrect result (true instead of false)

there is no bug without binary protocol

test script (you can run it as php script also)

!/bin/env spartan-test

// spartan-test unit test: https://github.com/parf/spartan-test
// PHP memcached extension BUGS

// you can run this test
// it shows just found bug in memcached php extension for php

$mc = new Memcached();

={"class":"Memcached","0":{}}

; $mc->addServer("localhost", 11211);

// this IS a bug option - binary protocol messes things up
; $mc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);

$mc->getVersion();

={"localhost:11211":"1.4.13"}

// #={"p:11211":"1.4.10"} << test on another server also have same issue

phpversion();

="5.4.1"

// rpm -qa | grep php-pecl-memcached : php-pecl-memcached-2.0.1-6.el6.remi.x86_64

; $key="key-for-testing";

// OK CASE
$mc->set($key, 0);

=true

$mc->increment($key);

=1

$mc->increment($key);

=2

$mc->increment($key);

=3

// BUG CASE
// extra get after set messes subsequent increments
$mc->set($key, 0);

=true

$mc->get($key);

=0

// OMG - BUG !!!
$mc->increment($key);

=-1

$mc->increment($key);

=1

$mc->increment($key);

=2

// ANOTHER BUG
; $mc->delete($key);

$mc->add($key, "abc");

=true

$mc->get($key);

="abc"

// BUG - should return false !!!
$mc->add($key, "def");

=true

$mc->get($key);

="abc"

2.1.0: Corrupted return value from getServerByKey

Memcached 2.1.0
libmemcached 1.0.15
OS X 10.8.3
PHP 5.4.11

After adding several servers with addServer(), I execute a getServerByKey() with the simple key "test".

I get back:

array(
    [host] => some garbled text, looks like double encoded utf8
    [port] => some random number < 65353
    [weight] => 1
)

On my production servers running 1.0.2, I get the expected data back. This version of memcached was compiled from "brew". The install formula is: https://github.com/josegonzalez/homebrew-php/blob/master/Formula/php54-memcached.rb

This formula just downloads and installs the tarball from http://pecl.php.net/get/memcached-2.1.0.tgz though.

Slow cache misses using binary protocol

Hello,

I was experimenting with php-memcached binary mode, and I noticed that my PHP script became very, very slow when I enabled the binary protocol. The server load went to near zero, indicating that something is just sitting and waiting while doing nothing at all. I managed to isolate the problem into a simple test case (see below). It turned out that an attempt to get() a non-existing key requires about 30 ms to complete. As soon as the binary protocol is turned off, response times are back to normal.

I'm on Ubuntu Server 12.04 (64-bit). The PHP script and the memcached server run on two seperate servers. Package versions are:

php5-memcached-1.0.2-2
libmemcached 0.44-1.1build1
memcached 1.4.13-0ubuntu2

I also tried to compile the latest memcached PECL from source, which did not make any difference.

A PHP script which reproduces the problem is shown below. Can anyone else reproduce this?

setOption(Memcached::OPT_BINARY_PROTOCOL, True); $Cache -> addServers(array ( array ("172.16.0.20","11211","0") )); $Counter = 0; $Start = time(); print("Getting 1000 Keys..."); while ($Counter < 1000) { $Cache -> get("test"); $Counter++; } $End = time(); $Speed = 1000.0 / ($End - $Start); print("Done, $Speed per second.\n");

I can't compiled memcached-2.1.0 on CentOS 6.4 with libmemcached 1.0.17.

I tried to compile memcached-2.1.0 on CentOS 6.4. I executed following commands on console for compile it.

pecl install memcached

but compilation was faiured, because of following erros.

/var/tmp/memcached/php_memcached.c:318: error: expected declaration specifiers or ‘...’ before ‘memcached_server_instance_st’
/var/tmp/memcached/php_memcached.c:319: error: expected declaration specifiers or ‘...’ before ‘memcached_server_instance_st’
/var/tmp/memcached/php_memcached.c:320: error: expected declaration specifiers or ‘...’ before ‘memcached_server_instance_st’
/var/tmp/memcached/php_memcached.c: In function ‘php_memc_get_impl’:
/var/tmp/memcached/php_memcached.c:599: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c: In function ‘php_memc_getMulti_impl’:
/var/tmp/memcached/php_memcached.c:797: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c:800: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c: In function ‘zim_Memcached_fetch’:
/var/tmp/memcached/php_memcached.c:1014: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c:1017: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c: In function ‘zim_Memcached_fetchAll’:
/var/tmp/memcached/php_memcached.c:1068: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c:1071: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c: In function ‘zim_Memcached_getServerList’:
/var/tmp/memcached/php_memcached.c:1948: warning: assignment from incompatible pointer type
/var/tmp/memcached/php_memcached.c: In function ‘zim_Memcached_getServerByKey’:
/var/tmp/memcached/php_memcached.c:1977: warning: assignment from incompatible pointer type
/var/tmp/memcached/php_memcached.c: In function ‘zim_Memcached_getStats’:
/var/tmp/memcached/php_memcached.c:2056: warning: assignment from incompatible pointer type
/var/tmp/memcached/php_memcached.c: In function ‘zim_Memcached_getVersion’:
/var/tmp/memcached/php_memcached.c:2089: warning: assignment from incompatible pointer type
/var/tmp/memcached/php_memcached.c: At top level:
/var/tmp/memcached/php_memcached.c:2576: error: expected declaration specifiers or ‘...’ before ‘memcached_server_instance_st’
/var/tmp/memcached/php_memcached.c: In function ‘php_memc_do_serverlist_callback’:
/var/tmp/memcached/php_memcached.c:2583: error: ‘instance’ undeclared (first use in this function)
/var/tmp/memcached/php_memcached.c:2583: error: (Each undeclared identifier is reported only once
/var/tmp/memcached/php_memcached.c:2583: error: for each function it appears in.)
/var/tmp/memcached/php_memcached.c: At top level:
/var/tmp/memcached/php_memcached.c:2593: error: expected declaration specifiers or ‘...’ before ‘memcached_server_instance_st’
/var/tmp/memcached/php_memcached.c: In function ‘php_memc_do_stats_callback’:
/var/tmp/memcached/php_memcached.c:2599: error: ‘instance’ undeclared (first use in this function)
/var/tmp/memcached/php_memcached.c: At top level:
/var/tmp/memcached/php_memcached.c:2637: error: expected declaration specifiers or ‘...’ before ‘memcached_server_instance_st’
/var/tmp/memcached/php_memcached.c: In function ‘php_memc_do_version_callback’:
/var/tmp/memcached/php_memcached.c:2644: error: ‘instance’ undeclared (first use in this function)
/var/tmp/memcached/php_memcached.c: In function ‘php_memc_do_result_callback’:
/var/tmp/memcached/php_memcached.c:3191: warning: assignment discards qualifiers from pointer target type
/var/tmp/memcached/php_memcached.c:3194: warning: assignment discards qualifiers from pointer target type
make: *** [php_memcached.lo] Error 1
ERROR: `make' failed

Close unused persistent memcached connections after specified timeout.

Persistent connections to memcached appear to be only closed when apache/php-fpm
is restarted.

Our persistent identifier is based on the application version, so old data for
some caches is automagically expired. However, the old persistent connections
won't be closed and keeps lots of unused tcp connections open.

Test script:

SASL support for session handler

Hi,

There is (a rather undocumented) support for SASL in the client, but not in the session handler.

I think it will be useful to add SASL support for session handler. This way cloud based Memcached services which require SASL (like Northscale, Memcachier...) can be used as session storages.

Pecl won't build on Suse

When I run:

$ pecl install memcached

The operation terminates with this error:

...
checking for session includes... /usr/include/php5
checking for memcached session support... enabled
checking for memcached igbinary support... disabled
checking for libmemcached location... configure: error: memcached support requires libmemcached 1.0.x. Use --with-libmemcached-dir=<DIR> to specify the prefix where libmemcached headers and library are located
ERROR: `/tmp/pear/temp/memcached/configure' failed

I checked to see if I had the relevant libraries installed:

$ zypper search memcached
S | Name               | Summary                                               | Type   
--+--------------------+-------------------------------------------------------+--------
i | libmemcached       | Libmemcached is a C and C++ client library to the m-> | package
  | libmemcached-devel | Libmemcached is a C and C++ client library to the m-> | package
i | libmemcached2      | Libmemcached is a C and C++ client library to the m-> | package
  | libmemcachedutil0  | Libmemcached is a C and C++ client library to the m-> | package
i | memcached          | A high-performance, distributed memory object cachi-> | package

Am I missing something here or is it a bug? Any help appreciated.

getResult* return failure status after successful retry

After a failed operation (get/set etc.) followed by a successful retry getResultCode and getResultMessage return the status from the initial failure not the expected success code/message.

This is because in this scenario i_obj->rescode is not reset to MEMCACHED_SUCCESS after the retry goto. As far as I can see the best place to do this would be in php_memc_handle_error though I may have missed a reason for this not already being the case.

Casting cas_token to double fails for large cas values

Given a key with a cas_token value of 9941891035036819 the cas operation will fail as casting the cas_token to double will round it up to 9941891035036820.

We tested casting the cas_token to long and was sucesful in casing the value in memcached.

Running php 5.3.24
memcached support => enabled
Version => 1.0.2
libmemcached version => 0.44
Session support => yes

sample code

printf("cas %ld, dbl cas: %f\n", 9941891035036819, (double)9941891035036819);

PHP compilation failure due to missing stdc++ library dependency declaration

stdc++ dependency is missing in config.m4 file

Adding those lines fixed the problem for me:

PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++, 1, MEMCACHED_SHARED_LIBADD)

I was compiling extension as built-in in php executable and was hit by linker error.
stdc++ dependency was introduced by memcached extension - no problem without it.

Related PHP docs:
http://devzone.zend.com/1435/wrapping-c-classes-in-a-php-extension/

Thanks,
Jacek

Memcached::touch gives Memcached::RES_END in binary mode, later calls fail

using php 5.3.2, libmemcached 1.0.5, memcached 1.4.13, php-memcached 2.0.1

After using the "touch"-command, I cannot retrieve any further keys. Simple test script:

<?php
$mem = new Memcached();
$mem->setOption(Memcached::OPT_BINARY_PROTOCOL,true);
$mem->addServer('localhost', 11211) or die ("Could not connect");

var_dump( $mem->get( 'test' ) );
$mem->set( 'test', 1 );
var_dump( $mem->getResultcode() );
var_dump( $mem->get('test') );
$mem->touch( 'test' );
var_dump( $mem->getResultcode() );
var_dump( $mem->get('test') );
var_dump( $mem->getResultcode() );
?>

first run gives:

bool(false)
int(21)
int(1)
int(21)
bool(false)
int(7)

so after "touch", it cannot retrieve the key "test" anymore? second run of script gives:

int(1)
int(21)
int(1)
int(21)
bool(false)
int(7)

so the value actually was stored in the cache (it did not get lost), but after "touch" it cannot be retrieved. I cannot retrieve any other key either (not only the touched one).

multiple server use for php session handler

it will be nice to enhance php-memcached session handler to support multiple servers and make use of MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS and MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ stuff

get() returns empty string when connection refused to memcached.

PHP 5.3.3

My code looks similar to this:

class MemoryCache extends Memcached {
  public function get($key, $callback = null, &$cas_token = null) {
    $results = parent::get($key, $callback, $cas_token);
    if ($results === false) {
      error_log("Cache miss on {$key}");
    }
    return $results;
  }
}

$results = $MemoryCache->get("Key");
if ($results === false) {
  $results = get_the_real_data();
}
do_stuff($results);

According to the documentation, either the result or FALSE should be returned. However, if the memcached server is down, or connection otherwise refused, $results comes out as a blank string "" (according to var_dump). This causes the calling code to get "" and do stuff with it instead of looking up the real data, due to the ===.

7deb03e perhaps related?

I've worked around this by checking getResultCode() and acting accordingly if not Memcached::RES_SUCCESS or Memcached::RES_NOTFOUND

This also seems to be reported here, although as a NULL return value.

Apologies if this is already fixed, or bogus. If it's bogus, the documentation should get updated on php.net :)

Missing DISTRIBUTION flags

While trying to achieve a failover/HA scenario, I noticed not all libmemcached 1.0.4 distribution options are supported right now.

Most notably what is missing is "MEMCACHED_DISTRIBUTION_RANDOM" in combination with EJECT options, but there are several other distribution algorithms available in libmemcached.

(just as a current workaround, had to use the KETAMA distribution to achieve some sort of failover for now).

Connection timeout for session handling

Hi,

At the moment it's not possible to set the connection timeout when using memcached as session handler.
So if the memcached server is down the request hangs for ages waiting for the connection.

Could you please add this?
It probably needs to be a parameter in the ini file, something like:
memcached.sess_connect_timeout = xxx

In my opinion the timeout should be around 3 seconds by default.

Thanks!

increment and decrement: can't specify $initial_value or $expiry

pecl memcached 2.1.0, libmemcache 1.0.15, ubuntu 12.04 64bit

When specifying any more than 2 parameters to increment/decrement I always get:

message: INVALID ARGUMENTS code: 38

Here is code to reproduce:

<?php
$m = new Memcached();
$newServers = array(
                  array('localhost', 11211, 100),
              );            
$m->setOption(Memcached::OPT_BINARY_PROTOCOL, false);

$m->addServers($newServers);

$d = $m->get('foo');

$m->set('counter', 5);
$n = $m->increment('counter',1,0,0);

Changelog for 2.0.0b1 says get method returns NULL instead of false

But this is plain wrong! Please change remove that line from the changelog, I modified hundred of lines of code just to find out that wasn't true: when I tested my changes nothing Memcached still returned false. Also, I has to check the C code of the extension to find out what's going on since I couldn't believe the changelog was writing something plain wrong that could potentially break hundreds of projects.

This is what it says:
Change the return value for non-existing keys to be NULL rather than 'false', affects simple get only

Double free during shutdown

I've come across a low-level error in the shutdown sequence when testing fault-tolerance. I'm using Ubuntu 12.10, PHP 5.3.10, memcached extension 1.0.2-2, all PHP packages are installed via. APT.

Script to reproduce error:

<?php

/**
 * Dev machine setup
 *   4 memcache instances running on the same VM running over a local bridge
 *   SSH key-less access set up using ssh-copy-id
 */


// Replace these with your cluster.
$servers = array(array('vm2.local', '11211'),
                 array('vm2.local', '11212'),
                 array('vm2.local', '11213'),
                 array('vm2.local', '11214'));

$mc = new Memcached;
foreach ($servers as $s) {
    $mc->addServer($s[0], $s[1]);
}


// This key must map to the server you remove in the next step
$key = 'NMgJg2Bz1Z2hfmrM0a6Zl4FVUq6vq774';

// Stop one of the servers
exec("ssh [email protected] sudo /etc/init.d/memcached stop a", $out, $ret);
if ($ret != 0) {
    throw new \RuntimeException("Failed to stop memcache server:\n" . implode("\n", $out), 2376);
}

$mc->set($key, "This is a test!");

$mc->getServerByKey($key);

echo "Test is complete\n";

Crashes with the following error:

*** glibc detected *** /usr/bin/php: double free or corruption (fasttop): 0x00000000010c2e10

Here's a gdb backtrace:

(gdb) bt
#0  0x00007ffff5b83445 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff5b86bab in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff5bc0e2e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007ffff5bcb626 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x00007ffff5c1ab58 in freeaddrinfo () from /lib/x86_64-linux-gnu/libc.so.6
#5  0x00007fffec74b9ab in memcached_server_list_free () from /usr/lib/libmemcached.so.6
#6  0x00007fffec749e49 in memcached_free () from /usr/lib/libmemcached.so.6
#7  0x00007fffec95b782 in ?? () from /usr/lib/php5/20090626/memcached.so
#8  0x00000000006bf5ff in zend_objects_store_del_ref_by_handle_ex (handle=17323080, handlers=0x4467) at /build/buildd/php5-5.3.10/Zend/zend_objects_API.c:220
#9  0x00000000006bf623 in zend_objects_store_del_ref (zobject=0x109d4c8) at /build/buildd/php5-5.3.10/Zend/zend_objects_API.c:172
#10 0x000000000068bb21 in _zval_ptr_dtor (zval_ptr=0x4467) at /build/buildd/php5-5.3.10/Zend/zend_variables.h:35
#11 0x00000000006a672e in zend_hash_apply_deleter () at /build/buildd/php5-5.3.10/Zend/zend_hash.c:813
#12 0x00000000006a82e1 in zend_hash_reverse_apply (ht=0xdd40a8, apply_func=0x68b9e0 <zval_call_destructor>) at /build/buildd/php5-5.3.10/Zend/zend_hash.c:964
#13 0x000000000068bed1 in shutdown_destructors () at /build/buildd/php5-5.3.10/Zend/zend_execute_API.c:226
#14 0x000000000069a167 in zend_call_destructors () at /build/buildd/php5-5.3.10/Zend/zend.c:947
#15 0x00000000006470bd in php_request_shutdown (dummy=0x4467) at /build/buildd/php5-5.3.10/main/main.c:1618
#16 0x000000000042b8d5 in main (argc=32767, argv=0x7fffffffe3e4) at /build/buildd/php5-5.3.10/sapi/cli/php_cli.c:1367

Note that the error is in the PHP shutdown sequence, the PHP script completes before it crashes

Binary protocol is broken

I've been having trouble using binary protocol in very simple scenarios. For instance:

<?php
$mc = new \Memcached();
$mc->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$mc->addServer("127.0.0.1", 11211);

$mc->touch("key", time() + 600);
$touchResult = $mc->getResultCode();
$mc->set("key", 1, time() + 600);
$setResult = $mc->getResultCode();

echo "<pre>";
echo "Touch result: $touchResult\n";
echo "Set result: $setResult\n";
echo "</pre>";

The first run outputs:

Touch result: 16 [RES_NOTFOUND]
Set result: 0 [RES_SUCCESS]

And the second run forth will output:

Touch result: 0 [RES_SUCCESS]
Set result: 5 [RES_WRITE_FAILURE]

Here are my system's configurations:

  • Ubuntu 12.04 64bit
  • PHP 5.3.14
  • memcached 2.1.0 (PECL module)
  • libmemcached 1.0.8
  • Memcached sever 1.4.13

Can't compile on Debian 6

root@x:/php-memcached# make
/bin/bash /php-memcached/libtool --mode=compile cc -I/usr/include/php5 -I. -I/php-memcached -DPHP_ATOM_INC -I/php-memcached/include -I/php-memcached/main -I/php-memcached -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -I/usr/local/include -DHAVE_CONFIG_H -g -O2 -c /php-memcached/php_memcached.c -o php_memcached.lo
libtool: compile: cc -I/usr/include/php5 -I. -I/php-memcached -DPHP_ATOM_INC -I/php-memcached/include -I/php-memcached/main -I/php-memcached -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -I/usr/local/include -DHAVE_CONFIG_H -g -O2 -c /php-memcached/php_memcached.c -fPIC -DPIC -o .libs/php_memcached.o
/php-memcached/php_memcached.c:324: error: expected declaration specifiers or '...' before 'memcached_server_instance_st'
/php-memcached/php_memcached.c:325: error: expected declaration specifiers or '...' before 'memcached_server_instance_st'
/php-memcached/php_memcached.c:326: error: expected declaration specifiers or '...' before 'memcached_server_instance_st'
/php-memcached/php_memcached.c: In function 'php_memc_get_impl':
/php-memcached/php_memcached.c:605: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c: In function 'php_memc_getMulti_impl':
/php-memcached/php_memcached.c:803: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c:806: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c: In function 'zim_Memcached_fetch':
/php-memcached/php_memcached.c:1020: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c:1023: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c: In function 'zim_Memcached_fetchAll':
/php-memcached/php_memcached.c:1074: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c:1077: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c: In function 'zim_Memcached_getServerList':
/php-memcached/php_memcached.c:1955: warning: assignment from incompatible pointer type
/php-memcached/php_memcached.c: In function 'zim_Memcached_getServerByKey':
/php-memcached/php_memcached.c:1968: error: 'memcached_server_instance_st' undeclared (first use in this function)
/php-memcached/php_memcached.c:1968: error: (Each undeclared identifier is reported only once
/php-memcached/php_memcached.c:1968: error: for each function it appears in.)
/php-memcached/php_memcached.c:1968: error: 'server_instance' undeclared (first use in this function)
/php-memcached/php_memcached.c: In function 'zim_Memcached_getLastDisconnectedServer':
/php-memcached/php_memcached.c:2086: error: 'memcached_server_instance_st' undeclared (first use in this function)
/php-memcached/php_memcached.c:2086: error: 'server_instance' undeclared (first use in this function)
/php-memcached/php_memcached.c: In function 'zim_Memcached_getStats':
/php-memcached/php_memcached.c:2138: warning: assignment from incompatible pointer type
/php-memcached/php_memcached.c: In function 'zim_Memcached_getVersion':
/php-memcached/php_memcached.c:2171: warning: assignment from incompatible pointer type
/php-memcached/php_memcached.c: At top level:
/php-memcached/php_memcached.c:2663: error: expected declaration specifiers or '...' before 'memcached_server_instance_st'
/php-memcached/php_memcached.c: In function 'php_memc_do_serverlist_callback':
/php-memcached/php_memcached.c:2670: error: 'instance' undeclared (first use in this function)
/php-memcached/php_memcached.c: At top level:
/php-memcached/php_memcached.c:2681: error: expected declaration specifiers or '...' before 'memcached_server_instance_st'
/php-memcached/php_memcached.c: In function 'php_memc_do_stats_callback':
/php-memcached/php_memcached.c:2687: error: 'instance' undeclared (first use in this function)
/php-memcached/php_memcached.c: At top level:
/php-memcached/php_memcached.c:2725: error: expected declaration specifiers or '...' before 'memcached_server_instance_st'
/php-memcached/php_memcached.c: In function 'php_memc_do_version_callback':
/php-memcached/php_memcached.c:2732: error: 'instance' undeclared (first use in this function)
/php-memcached/php_memcached.c: In function 'php_memc_do_result_callback':
/php-memcached/php_memcached.c:3291: warning: assignment discards qualifiers from pointer target type
/php-memcached/php_memcached.c:3294: warning: assignment discards qualifiers from pointer target type
make: *** [php_memcached.lo] Error 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.