X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fmemcached-client.php;h=53f0324f7e53387150aaba5a4329676ad5467430;hb=c52cf288d40d1a925f9ec5e7346357f446a14018;hp=0e043147b534da70d2f024315f946fe4a04669d8;hpb=aa7101aabe29deeb722053758547714a2fc621a0;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/memcached-client.php b/includes/memcached-client.php index 0e043147b5..53f0324f7e 100644 --- a/includes/memcached-client.php +++ b/includes/memcached-client.php @@ -1,40 +1,41 @@ | -// | All rights reserved. | -// | | -// | Redistribution and use in source and binary forms, with or without | -// | modification, are 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. | -// | | -// | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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. | -// +---------------------------------------------------------------------------+ -// | Author: Ryan T. Dean | -// | Heavily influenced by the Perl memcached client by Brad Fitzpatrick. | -// | Permission granted by Brad Fitzpatrick for relicense of ported Perl | -// | client logic under 2-clause BSD license. | -// +---------------------------------------------------------------------------+ -// -// $TCAnet$ -// +/** + * +---------------------------------------------------------------------------+ + * | memcached client, PHP | + * +---------------------------------------------------------------------------+ + * | Copyright (c) 2003 Ryan T. Dean | + * | All rights reserved. | + * | | + * | Redistribution and use in source and binary forms, with or without | + * | modification, are 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. | + * | | + * | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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. | + * +---------------------------------------------------------------------------+ + * | Author: Ryan T. Dean | + * | Heavily influenced by the Perl memcached client by Brad Fitzpatrick. | + * | Permission granted by Brad Fitzpatrick for relicense of ported Perl | + * | client logic under 2-clause BSD license. | + * +---------------------------------------------------------------------------+ + * + * @file + * $TCAnet$ + */ /** * This is the PHP client for memcached - a distributed memory cache daemon. @@ -70,10 +71,9 @@ * @author Ryan T. Dean * @ingroup Cache */ -class MWMemcached -{ - // {{{ properties - // {{{ public +class MWMemcached { + // {{{ properties + // {{{ public // {{{ constants // {{{ flags @@ -240,26 +240,25 @@ class MWMemcached /** * Memcache initializer * - * @param array $args Associative array of settings + * @param $args Array Associative array of settings * * @return mixed - * @access public */ - function __construct ($args) - { - $this->set_servers(@$args['servers']); - $this->_debug = @$args['debug']; + public function __construct( $args ) { + global $wgMemCachedTimeout; + $this->set_servers( isset( $args['servers'] ) ? $args['servers'] : array() ); + $this->_debug = isset( $args['debug'] ) ? $args['debug'] : false; $this->stats = array(); - $this->_compress_threshold = @$args['compress_threshold']; - $this->_persistant = array_key_exists('persistant', $args) ? (@$args['persistant']) : false; + $this->_compress_threshold = isset( $args['compress_threshold'] ) ? $args['compress_threshold'] : 0; + $this->_persistant = isset( $args['persistant'] ) ? $args['persistant'] : false; $this->_compress_enable = true; - $this->_have_zlib = function_exists("gzcompress"); + $this->_have_zlib = function_exists( 'gzcompress' ); $this->_cache_sock = array(); $this->_host_dead = array(); $this->_timeout_seconds = 0; - $this->_timeout_microseconds = 50000; + $this->_timeout_microseconds = $wgMemCachedTimeout; $this->_connect_timeout = 0.01; $this->_connect_attempts = 2; @@ -272,33 +271,33 @@ class MWMemcached * Adds a key/value to the memcache server if one isn't already set with * that key * - * @param string $key Key to set with data - * @param mixed $val Value to store - * @param integer $exp (optional) Time to expire data at + * @param $key String: key to set with data + * @param $val Mixed: value to store + * @param $exp Integer: (optional) Expiration time. This can be a number of seconds + * to cache for (up to 30 days inclusive). Any timespans of 30 days + 1 second or + * longer must be the timestamp of the time at which the mapping should expire. It + * is safe to use timestamps in all cases, regardless of exipration + * eg: strtotime("+3 hour") * - * @return boolean - * @access public + * @return Boolean */ - function add ($key, $val, $exp = 0) - { - return $this->_set('add', $key, $val, $exp); + public function add( $key, $val, $exp = 0 ) { + return $this->_set( 'add', $key, $val, $exp ); } // }}} // {{{ decr() /** - * Decriment a value stored on the memcache server + * Decrease a value stored on the memcache server * - * @param string $key Key to decriment - * @param integer $amt (optional) Amount to decriment + * @param $key String: key to decrease + * @param $amt Integer: (optional) amount to decrease * - * @return mixed FALSE on failure, value on success - * @access public + * @return Mixed: FALSE on failure, value on success */ - function decr ($key, $amt=1) - { - return $this->_incrdecr('decr', $key, $amt); + public function decr( $key, $amt = 1 ) { + return $this->_incrdecr( 'decr', $key, $amt ); } // }}} @@ -307,37 +306,42 @@ class MWMemcached /** * Deletes a key from the server, optionally after $time * - * @param string $key Key to delete - * @param integer $time (optional) How long to wait before deleting + * @param $key String: key to delete + * @param $time Integer: (optional) how long to wait before deleting * - * @return boolean TRUE on success, FALSE on failure - * @access public + * @return Boolean: TRUE on success, FALSE on failure */ - function delete ($key, $time = 0) - { - if (!$this->_active) + public function delete( $key, $time = 0 ) { + if ( !$this->_active ) { return false; + } - $sock = $this->get_sock($key); - if (!is_resource($sock)) + $sock = $this->get_sock( $key ); + if ( !is_resource( $sock ) ) { return false; + } - $key = is_array($key) ? $key[1] : $key; + $key = is_array( $key ) ? $key[1] : $key; - @$this->stats['delete']++; + if ( isset( $this->stats['delete'] ) ) { + $this->stats['delete']++; + } else { + $this->stats['delete'] = 1; + } $cmd = "delete $key $time\r\n"; - if(!$this->_safe_fwrite($sock, $cmd, strlen($cmd))) - { - $this->_dead_sock($sock); + if( !$this->_safe_fwrite( $sock, $cmd, strlen( $cmd ) ) ) { + $this->_dead_sock( $sock ); return false; } - $res = trim(fgets($sock)); + $res = trim( fgets( $sock ) ); - if ($this->_debug) - $this->_debugprint(sprintf("MemCache: delete %s (%s)\n", $key, $res)); + if ( $this->_debug ) { + $this->_debugprint( sprintf( "MemCache: delete %s (%s)\n", $key, $res ) ); + } - if ($res == "DELETED") + if ( $res == "DELETED" ) { return true; + } return false; } @@ -346,13 +350,11 @@ class MWMemcached /** * Disconnects all connected sockets - * - * @access public */ - function disconnect_all () - { - foreach ($this->_cache_sock as $sock) - fclose($sock); + public function disconnect_all() { + foreach ( $this->_cache_sock as $sock ) { + fclose( $sock ); + } $this->_cache_sock = array(); } @@ -363,12 +365,9 @@ class MWMemcached /** * Enable / Disable compression * - * @param boolean $enable TRUE to enable, FALSE to disable - * - * @access public + * @param $enable Boolean: TRUE to enable, FALSE to disable */ - function enable_compress ($enable) - { + public function enable_compress( $enable ) { $this->_compress_enable = $enable; } @@ -377,11 +376,8 @@ class MWMemcached /** * Forget about all of the dead hosts - * - * @access public */ - function forget_dead_hosts () - { + public function forget_dead_hosts() { $this->_host_dead = array(); } @@ -391,50 +387,52 @@ class MWMemcached /** * Retrieves the value associated with the key from the memcache server * - * @param string $key Key to retrieve + * @param $key Mixed: key to retrieve * - * @return mixed - * @access public + * @return Mixed */ - function get ($key) - { - $fname = 'memcached::get'; - wfProfileIn( $fname ); + public function get( $key ) { + wfProfileIn( __METHOD__ ); if ( $this->_debug ) { $this->_debugprint( "get($key)\n" ); } - if (!$this->_active) { - wfProfileOut( $fname ); + if ( !$this->_active ) { + wfProfileOut( __METHOD__ ); return false; } - $sock = $this->get_sock($key); + $sock = $this->get_sock( $key ); - if (!is_resource($sock)) { - wfProfileOut( $fname ); + if ( !is_resource( $sock ) ) { + wfProfileOut( __METHOD__ ); return false; } - @$this->stats['get']++; + if ( isset( $this->stats['get'] ) ) { + $this->stats['get']++; + } else { + $this->stats['get'] = 1; + } $cmd = "get $key\r\n"; - if (!$this->_safe_fwrite($sock, $cmd, strlen($cmd))) - { - $this->_dead_sock($sock); - wfProfileOut( $fname ); + if ( !$this->_safe_fwrite( $sock, $cmd, strlen( $cmd ) ) ) { + $this->_dead_sock( $sock ); + wfProfileOut( __METHOD__ ); return false; } $val = array(); - $this->_load_items($sock, $val); + $this->_load_items( $sock, $val ); - if ($this->_debug) - foreach ($val as $k => $v) - $this->_debugprint(sprintf("MemCache: sock %s got %s\n", serialize($sock), $k)); + if ( $this->_debug ) { + foreach ( $val as $k => $v ) { + $this->_debugprint( sprintf( "MemCache: sock %s got %s\n", serialize( $sock ), $k ) ); + } + } - wfProfileOut( $fname ); + wfProfileOut( __METHOD__ ); return @$val[$key]; } @@ -444,26 +442,29 @@ class MWMemcached /** * Get multiple keys from the server(s) * - * @param array $keys Keys to retrieve + * @param $keys Array: keys to retrieve * - * @return array - * @access public + * @return Array */ - function get_multi ($keys) - { - if (!$this->_active) + public function get_multi( $keys ) { + if ( !$this->_active ) { return false; + } - @$this->stats['get_multi']++; + if ( isset( $this->stats['get_multi'] ) ) { + $this->stats['get_multi']++; + } else { + $this->stats['get_multi'] = 1; + } $sock_keys = array(); - foreach ($keys as $key) - { - $sock = $this->get_sock($key); - if (!is_resource($sock)) continue; - $key = is_array($key) ? $key[1] : $key; - if (!isset($sock_keys[$sock])) - { + foreach ( $keys as $key ) { + $sock = $this->get_sock( $key ); + if ( !is_resource( $sock ) ) { + continue; + } + $key = is_array( $key ) ? $key[1] : $key; + if ( !isset( $sock_keys[$sock] ) ) { $sock_keys[$sock] = array(); $socks[] = $sock; } @@ -471,34 +472,31 @@ class MWMemcached } // Send out the requests - foreach ($socks as $sock) - { - $cmd = "get"; - foreach ($sock_keys[$sock] as $key) - { - $cmd .= " ". $key; + foreach ( $socks as $sock ) { + $cmd = 'get'; + foreach ( $sock_keys[$sock] as $key ) { + $cmd .= ' ' . $key; } $cmd .= "\r\n"; - if ($this->_safe_fwrite($sock, $cmd, strlen($cmd))) - { + if ( $this->_safe_fwrite( $sock, $cmd, strlen( $cmd ) ) ) { $gather[] = $sock; - } else - { - $this->_dead_sock($sock); + } else { + $this->_dead_sock( $sock ); } } // Parse responses $val = array(); - foreach ($gather as $sock) - { - $this->_load_items($sock, $val); + foreach ( $gather as $sock ) { + $this->_load_items( $sock, $val ); } - if ($this->_debug) - foreach ($val as $k => $v) - $this->_debugprint(sprintf("MemCache: got %s\n", $k)); + if ( $this->_debug ) { + foreach ( $val as $k => $v ) { + $this->_debugprint( sprintf( "MemCache: got %s\n", $k ) ); + } + } return $val; } @@ -509,15 +507,15 @@ class MWMemcached /** * Increments $key (optionally) by $amt * - * @param string $key Key to increment - * @param integer $amt (optional) amount to increment + * @param $key String: key to increment + * @param $amt Integer: (optional) amount to increment * - * @return integer New key value? - * @access public + * @return Integer: null if the key does not exist yet (this does NOT + * create new mappings if the key does not exist). If the key does + * exist, this returns the new value for that key. */ - function incr ($key, $amt=1) - { - return $this->_incrdecr('incr', $key, $amt); + public function incr( $key, $amt = 1 ) { + return $this->_incrdecr( 'incr', $key, $amt ); } // }}} @@ -526,16 +524,18 @@ class MWMemcached /** * Overwrites an existing value for key; only works if key is already set * - * @param string $key Key to set value as - * @param mixed $value Value to store - * @param integer $exp (optional) Experiation time + * @param $key String: key to set value as + * @param $value Mixed: value to store + * @param $exp Integer: (optional) Expiration time. This can be a number of seconds + * to cache for (up to 30 days inclusive). Any timespans of 30 days + 1 second or + * longer must be the timestamp of the time at which the mapping should expire. It + * is safe to use timestamps in all cases, regardless of exipration + * eg: strtotime("+3 hour") * - * @return boolean - * @access public + * @return Boolean */ - function replace ($key, $value, $exp=0) - { - return $this->_set('replace', $key, $value, $exp); + public function replace( $key, $value, $exp = 0 ) { + return $this->_set( 'replace', $key, $value, $exp ); } // }}} @@ -551,28 +551,29 @@ class MWMemcached * with a \n. This is with the PHP flag auto_detect_line_endings set * to falase (the default). * - * @param resource $sock Socket to send command on - * @param string $cmd Command to run + * @param $sock Ressource: socket to send command on + * @param $cmd String: command to run * - * @return array Output array - * @access public + * @return Array: output array */ - function run_command ($sock, $cmd) - { - if (!is_resource($sock)) + public function run_command( $sock, $cmd ) { + if ( !is_resource( $sock ) ) { return array(); + } - if (!$this->_safe_fwrite($sock, $cmd, strlen($cmd))) + if ( !$this->_safe_fwrite( $sock, $cmd, strlen( $cmd ) ) ) { return array(); + } - while (true) - { - $res = fgets($sock); + while ( true ) { + $res = fgets( $sock ); $ret[] = $res; - if (preg_match('/^END/', $res)) + if ( preg_match( '/^END/', $res ) ) { break; - if (strlen($res) == 0) + } + if ( strlen( $res ) == 0 ) { break; + } } return $ret; } @@ -584,16 +585,18 @@ class MWMemcached * Unconditionally sets a key to a given value in the memcache. Returns true * if set successfully. * - * @param string $key Key to set value as - * @param mixed $value Value to set - * @param integer $exp (optional) Experiation time + * @param $key String: key to set value as + * @param $value Mixed: value to set + * @param $exp Integer: (optional) Expiration time. This can be a number of seconds + * to cache for (up to 30 days inclusive). Any timespans of 30 days + 1 second or + * longer must be the timestamp of the time at which the mapping should expire. It + * is safe to use timestamps in all cases, regardless of exipration + * eg: strtotime("+3 hour") * - * @return boolean TRUE on success - * @access public + * @return Boolean: TRUE on success */ - function set ($key, $value, $exp=0) - { - return $this->_set('set', $key, $value, $exp); + public function set( $key, $value, $exp = 0 ) { + return $this->_set( 'set', $key, $value, $exp ); } // }}} @@ -602,12 +605,9 @@ class MWMemcached /** * Sets the compression threshold * - * @param integer $thresh Threshold to compress if larger than - * - * @access public + * @param $thresh Integer: threshold to compress if larger than */ - function set_compress_threshold ($thresh) - { + public function set_compress_threshold( $thresh ) { $this->_compress_threshold = $thresh; } @@ -617,14 +617,11 @@ class MWMemcached /** * Sets the debug flag * - * @param boolean $dbg TRUE for debugging, FALSE otherwise - * - * @access public + * @param $dbg Boolean: TRUE for debugging, FALSE otherwise * - * @see memcahced::memcached + * @see MWMemcached::__construct */ - function set_debug ($dbg) - { + public function set_debug( $dbg ) { $this->_debug = $dbg; } @@ -634,34 +631,29 @@ class MWMemcached /** * Sets the server list to distribute key gets and puts between * - * @param array $list Array of servers to connect to - * - * @access public + * @param $list Array of servers to connect to * - * @see memcached::memcached() + * @see MWMemcached::__construct() */ - function set_servers ($list) - { + public function set_servers( $list ) { $this->_servers = $list; - $this->_active = count($list); + $this->_active = count( $list ); $this->_buckets = null; $this->_bucketcount = 0; $this->_single_sock = null; - if ($this->_active == 1) + if ( $this->_active == 1 ) { $this->_single_sock = $this->_servers[0]; + } } /** * Sets the timeout for new connections * - * @param integer $seconds Number of seconds - * @param integer $microseconds Number of microseconds - * - * @access public + * @param $seconds Integer: number of seconds + * @param $microseconds Integer: number of microseconds */ - function set_timeout ($seconds, $microseconds) - { + public function set_timeout( $seconds, $microseconds ) { $this->_timeout_seconds = $seconds; $this->_timeout_microseconds = $microseconds; } @@ -674,15 +666,14 @@ class MWMemcached /** * Close the specified socket * - * @param string $sock Socket to close + * @param $sock String: socket to close * * @access private */ - function _close_sock ($sock) - { - $host = array_search($sock, $this->_cache_sock); - fclose($this->_cache_sock[$host]); - unset($this->_cache_sock[$host]); + function _close_sock( $sock ) { + $host = array_search( $sock, $this->_cache_sock ); + fclose( $this->_cache_sock[$host] ); + unset( $this->_cache_sock[$host] ); } // }}} @@ -691,35 +682,35 @@ class MWMemcached /** * Connects $sock to $host, timing out after $timeout * - * @param integer $sock Socket to connect - * @param string $host Host:IP to connect to + * @param $sock Integer: socket to connect + * @param $host String: Host:IP to connect to * * @return boolean * @access private */ - function _connect_sock (&$sock, $host) - { - list ($ip, $port) = explode(":", $host); + function _connect_sock( &$sock, $host ) { + list( $ip, $port ) = explode( ':', $host ); $sock = false; $timeout = $this->_connect_timeout; $errno = $errstr = null; - for ($i = 0; !$sock && $i < $this->_connect_attempts; $i++) { - if ($this->_persistant == 1) - { - $sock = @pfsockopen($ip, $port, $errno, $errstr, $timeout); - } else - { - $sock = @fsockopen($ip, $port, $errno, $errstr, $timeout); + for( $i = 0; !$sock && $i < $this->_connect_attempts; $i++ ) { + wfSuppressWarnings(); + if ( $this->_persistant == 1 ) { + $sock = pfsockopen( $ip, $port, $errno, $errstr, $timeout ); + } else { + $sock = fsockopen( $ip, $port, $errno, $errstr, $timeout ); } + wfRestoreWarnings(); } - if (!$sock) { - if ($this->_debug) + if ( !$sock ) { + if ( $this->_debug ) { $this->_debugprint( "Error connecting to $host: $errstr\n" ); + } return false; } // Initialise timeout - stream_set_timeout($sock, $this->_timeout_seconds, $this->_timeout_microseconds); + stream_set_timeout( $sock, $this->_timeout_seconds, $this->_timeout_microseconds ); return true; } @@ -730,22 +721,21 @@ class MWMemcached /** * Marks a host as dead until 30-40 seconds in the future * - * @param string $sock Socket to mark as dead + * @param $sock String: socket to mark as dead * * @access private */ - function _dead_sock ($sock) - { - $host = array_search($sock, $this->_cache_sock); - $this->_dead_host($host); + function _dead_sock( $sock ) { + $host = array_search( $sock, $this->_cache_sock ); + $this->_dead_host( $host ); } - function _dead_host ($host) - { - @list ($ip, /* $port */) = explode(":", $host); - $this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10)); + function _dead_host( $host ) { + $parts = explode( ':', $host ); + $ip = $parts[0]; + $this->_host_dead[$ip] = time() + 30 + intval( rand( 0, 10 ) ); $this->_host_dead[$host] = $this->_host_dead[$ip]; - unset($this->_cache_sock[$host]); + unset( $this->_cache_sock[$host] ); } // }}} @@ -754,49 +744,45 @@ class MWMemcached /** * get_sock * - * @param string $key Key to retrieve value for; + * @param $key String: key to retrieve value for; * - * @return mixed resource on success, false on failure - * @access private + * @return Mixed: resource on success, false on failure + * @access private */ - function get_sock ($key) - { - if (!$this->_active) + function get_sock( $key ) { + if ( !$this->_active ) { return false; + } - if ($this->_single_sock !== null) { - $this->_flush_read_buffer($this->_single_sock); - return $this->sock_to_host($this->_single_sock); + if ( $this->_single_sock !== null ) { + $this->_flush_read_buffer( $this->_single_sock ); + return $this->sock_to_host( $this->_single_sock ); } - $hv = is_array($key) ? intval($key[0]) : $this->_hashfunc($key); + $hv = is_array( $key ) ? intval( $key[0] ) : $this->_hashfunc( $key ); - if ($this->_buckets === null) - { - foreach ($this->_servers as $v) - { - if (is_array($v)) - { - for ($i=0; $i<$v[1]; $i++) + if ( $this->_buckets === null ) { + foreach ( $this->_servers as $v ) { + if ( is_array( $v ) ) { + for( $i = 0; $i < $v[1]; $i++ ) { $bu[] = $v[0]; - } else - { + } + } else { $bu[] = $v; } } $this->_buckets = $bu; - $this->_bucketcount = count($bu); + $this->_bucketcount = count( $bu ); } - $realkey = is_array($key) ? $key[1] : $key; - for ($tries = 0; $tries<20; $tries++) - { + $realkey = is_array( $key ) ? $key[1] : $key; + for( $tries = 0; $tries < 20; $tries++ ) { $host = $this->_buckets[$hv % $this->_bucketcount]; - $sock = $this->sock_to_host($host); - if (is_resource($sock)) { - $this->_flush_read_buffer($sock); + $sock = $this->sock_to_host( $host ); + if ( is_resource( $sock ) ) { + $this->_flush_read_buffer( $sock ); return $sock; - } + } $hv = $this->_hashfunc( $hv . $realkey ); } @@ -807,19 +793,18 @@ class MWMemcached // {{{ _hashfunc() /** - * Creates a hash integer based on the $key + * Creates a hash integer based on the $key * - * @param string $key Key to hash + * @param $key String: key to hash * - * @return integer Hash value - * @access private + * @return Integer: hash value + * @access private */ - function _hashfunc ($key) - { + function _hashfunc( $key ) { # Hash function must on [0,0x7ffffff] # We take the first 31 bits of the MD5 hash, which unlike the hash # function used in a previous version of this client, works - return hexdec(substr(md5($key),0,8)) & 0x7fffffff; + return hexdec( substr( md5( $key ), 0, 8 ) ) & 0x7fffffff; } // }}} @@ -828,31 +813,38 @@ class MWMemcached /** * Perform increment/decriment on $key * - * @param string $cmd Command to perform - * @param string $key Key to perform it on - * @param integer $amt Amount to adjust + * @param $cmd String: command to perform + * @param $key String: key to perform it on + * @param $amt Integer: amount to adjust * - * @return integer New value of $key - * @access private + * @return Integer: new value of $key + * @access private */ - function _incrdecr ($cmd, $key, $amt=1) - { - if (!$this->_active) + function _incrdecr( $cmd, $key, $amt = 1 ) { + if ( !$this->_active ) { return null; + } - $sock = $this->get_sock($key); - if (!is_resource($sock)) + $sock = $this->get_sock( $key ); + if ( !is_resource( $sock ) ) { return null; + } - $key = is_array($key) ? $key[1] : $key; - @$this->stats[$cmd]++; - if (!$this->_safe_fwrite($sock, "$cmd $key $amt\r\n")) - return $this->_dead_sock($sock); + $key = is_array( $key ) ? $key[1] : $key; + if ( isset( $this->stats[$cmd] ) ) { + $this->stats[$cmd]++; + } else { + $this->stats[$cmd] = 1; + } + if ( !$this->_safe_fwrite( $sock, "$cmd $key $amt\r\n" ) ) { + return $this->_dead_sock( $sock ); + } - $line = fgets($sock); + $line = fgets( $sock ); $match = array(); - if (!preg_match('/^(\d+)/', $line, $match)) + if ( !preg_match( '/^(\d+)/', $line, $match ) ) { return null; + } return $match[1]; } @@ -862,58 +854,59 @@ class MWMemcached /** * Load items into $ret from $sock * - * @param resource $sock Socket to read from - * @param array $ret Returned values + * @param $sock Ressource: socket to read from + * @param $ret Array: returned values * - * @access private + * @access private */ - function _load_items ($sock, &$ret) - { - while (1) - { - $decl = fgets($sock); - if ($decl == "END\r\n") - { + function _load_items( $sock, &$ret ) { + while ( 1 ) { + $decl = fgets( $sock ); + if ( $decl == "END\r\n" ) { return true; - } elseif (preg_match('/^VALUE (\S+) (\d+) (\d+)\r\n$/', $decl, $match)) - { - list($rkey, $flags, $len) = array($match[1], $match[2], $match[3]); - $bneed = $len+2; + } elseif ( preg_match( '/^VALUE (\S+) (\d+) (\d+)\r\n$/', $decl, $match ) ) { + list( $rkey, $flags, $len ) = array( $match[1], $match[2], $match[3] ); + $bneed = $len + 2; $offset = 0; - while ($bneed > 0) - { - $data = fread($sock, $bneed); - $n = strlen($data); - if ($n == 0) + while ( $bneed > 0 ) { + $data = fread( $sock, $bneed ); + $n = strlen( $data ); + if ( $n == 0 ) { break; + } $offset += $n; $bneed -= $n; - @$ret[$rkey] .= $data; + if ( isset( $ret[$rkey] ) ) { + $ret[$rkey] .= $data; + } else { + $ret[$rkey] = $data; + } } - if ($offset != $len+2) - { + if ( $offset != $len + 2 ) { // Something is borked! - if ($this->_debug) - $this->_debugprint(sprintf("Something is borked! key %s expecting %d got %d length\n", $rkey, $len+2, $offset)); + if ( $this->_debug ) { + $this->_debugprint( sprintf( "Something is borked! key %s expecting %d got %d length\n", $rkey, $len + 2, $offset ) ); + } - unset($ret[$rkey]); - $this->_close_sock($sock); + unset( $ret[$rkey] ); + $this->_close_sock( $sock ); return false; } - if ($this->_have_zlib && $flags & memcached::COMPRESSED) - $ret[$rkey] = gzuncompress($ret[$rkey]); + if ( $this->_have_zlib && $flags & self::COMPRESSED ) { + $ret[$rkey] = gzuncompress( $ret[$rkey] ); + } - $ret[$rkey] = rtrim($ret[$rkey]); + $ret[$rkey] = rtrim( $ret[$rkey] ); - if ($flags & memcached::SERIALIZED) - $ret[$rkey] = unserialize($ret[$rkey]); + if ( $flags & self::SERIALIZED ) { + $ret[$rkey] = unserialize( $ret[$rkey] ); + } - } else - { - $this->_debugprint("Error parsing memcached response\n"); + } else { + $this->_debugprint( "Error parsing memcached response\n" ); return 0; } } @@ -925,63 +918,73 @@ class MWMemcached /** * Performs the requested storage operation to the memcache server * - * @param string $cmd Command to perform - * @param string $key Key to act on - * @param mixed $val What we need to store - * @param integer $exp When it should expire - * - * @return boolean - * @access private + * @param $cmd String: command to perform + * @param $key String: key to act on + * @param $val Mixed: what we need to store + * @param $exp Integer: (optional) Expiration time. This can be a number of seconds + * to cache for (up to 30 days inclusive). Any timespans of 30 days + 1 second or + * longer must be the timestamp of the time at which the mapping should expire. It + * is safe to use timestamps in all cases, regardless of exipration + * eg: strtotime("+3 hour") + * + * @return Boolean + * @access private */ - function _set ($cmd, $key, $val, $exp) - { - if (!$this->_active) + function _set( $cmd, $key, $val, $exp ) { + if ( !$this->_active ) { return false; + } - $sock = $this->get_sock($key); - if (!is_resource($sock)) + $sock = $this->get_sock( $key ); + if ( !is_resource( $sock ) ) { return false; + } - @$this->stats[$cmd]++; + if ( isset( $this->stats[$cmd] ) ) { + $this->stats[$cmd]++; + } else { + $this->stats[$cmd] = 1; + } $flags = 0; - if (!is_scalar($val)) - { - $val = serialize($val); - $flags |= memcached::SERIALIZED; - if ($this->_debug) - $this->_debugprint(sprintf("client: serializing data as it is not scalar\n")); + if ( !is_scalar( $val ) ) { + $val = serialize( $val ); + $flags |= self::SERIALIZED; + if ( $this->_debug ) { + $this->_debugprint( sprintf( "client: serializing data as it is not scalar\n" ) ); + } } - $len = strlen($val); + $len = strlen( $val ); - if ($this->_have_zlib && $this->_compress_enable && - $this->_compress_threshold && $len >= $this->_compress_threshold) + if ( $this->_have_zlib && $this->_compress_enable && + $this->_compress_threshold && $len >= $this->_compress_threshold ) { - $c_val = gzcompress($val, 9); - $c_len = strlen($c_val); + $c_val = gzcompress( $val, 9 ); + $c_len = strlen( $c_val ); - if ($c_len < $len*(1 - memcached::COMPRESSION_SAVINGS)) - { - if ($this->_debug) - $this->_debugprint(sprintf("client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len)); + if ( $c_len < $len * ( 1 - self::COMPRESSION_SAVINGS ) ) { + if ( $this->_debug ) { + $this->_debugprint( sprintf( "client: compressing data; was %d bytes is now %d bytes\n", $len, $c_len ) ); + } $val = $c_val; $len = $c_len; - $flags |= memcached::COMPRESSED; + $flags |= self::COMPRESSED; } } - if (!$this->_safe_fwrite($sock, "$cmd $key $flags $exp $len\r\n$val\r\n")) - return $this->_dead_sock($sock); + if ( !$this->_safe_fwrite( $sock, "$cmd $key $flags $exp $len\r\n$val\r\n" ) ) { + return $this->_dead_sock( $sock ); + } - $line = trim(fgets($sock)); + $line = trim( fgets( $sock ) ); - if ($this->_debug) - { - $this->_debugprint(sprintf("%s %s (%s)\n", $cmd, $key, $line)); + if ( $this->_debug ) { + $this->_debugprint( sprintf( "%s %s (%s)\n", $cmd, $key, $line ) ); } - if ($line == "STORED") + if ( $line == "STORED" ) { return true; + } return false; } @@ -991,59 +994,62 @@ class MWMemcached /** * Returns the socket for the host * - * @param string $host Host:IP to get socket for + * @param $host String: Host:IP to get socket for * - * @return mixed IO Stream or false - * @access private + * @return Mixed: IO Stream or false + * @access private */ - function sock_to_host ($host) - { - if (isset($this->_cache_sock[$host])) + function sock_to_host( $host ) { + if ( isset( $this->_cache_sock[$host] ) ) { return $this->_cache_sock[$host]; + } $sock = null; $now = time(); - list ($ip, /* $port */) = explode (":", $host); - if (isset($this->_host_dead[$host]) && $this->_host_dead[$host] > $now || - isset($this->_host_dead[$ip]) && $this->_host_dead[$ip] > $now) + list( $ip, /* $port */) = explode( ':', $host ); + if ( isset( $this->_host_dead[$host] ) && $this->_host_dead[$host] > $now || + isset( $this->_host_dead[$ip] ) && $this->_host_dead[$ip] > $now + ) { return null; + } - if (!$this->_connect_sock($sock, $host)) - return $this->_dead_host($host); + if ( !$this->_connect_sock( $sock, $host ) ) { + return $this->_dead_host( $host ); + } // Do not buffer writes - stream_set_write_buffer($sock, 0); + stream_set_write_buffer( $sock, 0 ); $this->_cache_sock[$host] = $sock; return $this->_cache_sock[$host]; } - function _debugprint($str){ - print($str); + function _debugprint( $str ) { + print( $str ); } /** * Write to a stream, timing out after the correct amount of time * - * @return bool false on failure, true on success + * @return Boolean: false on failure, true on success */ /* - function _safe_fwrite($f, $buf, $len = false) { - stream_set_blocking($f, 0); + function _safe_fwrite( $f, $buf, $len = false ) { + stream_set_blocking( $f, 0 ); - if ($len === false) { - wfDebug("Writing " . strlen( $buf ) . " bytes\n"); - $bytesWritten = fwrite($f, $buf); + if ( $len === false ) { + wfDebug( "Writing " . strlen( $buf ) . " bytes\n" ); + $bytesWritten = fwrite( $f, $buf ); } else { - wfDebug("Writing $len bytes\n"); - $bytesWritten = fwrite($f, $buf, $len); + wfDebug( "Writing $len bytes\n" ); + $bytesWritten = fwrite( $f, $buf, $len ); } - $n = stream_select($r=NULL, $w = array($f), $e = NULL, 10, 0); - # $this->_timeout_seconds, $this->_timeout_microseconds); + $n = stream_select( $r = null, $w = array( $f ), $e = null, 10, 0 ); + # $this->_timeout_seconds, $this->_timeout_microseconds ); - wfDebug("stream_select returned $n\n"); - stream_set_blocking($f, 1); + wfDebug( "stream_select returned $n\n" ); + stream_set_blocking( $f, 1 ); return $n == 1; return $bytesWritten; }*/ @@ -1051,11 +1057,11 @@ class MWMemcached /** * Original behaviour */ - function _safe_fwrite($f, $buf, $len = false) { - if ($len === false) { - $bytesWritten = fwrite($f, $buf); + function _safe_fwrite( $f, $buf, $len = false ) { + if ( $len === false ) { + $bytesWritten = fwrite( $f, $buf ); } else { - $bytesWritten = fwrite($f, $buf, $len); + $bytesWritten = fwrite( $f, $buf, $len ); } return $bytesWritten; } @@ -1063,14 +1069,14 @@ class MWMemcached /** * Flush the read buffer of a stream */ - function _flush_read_buffer($f) { - if (!is_resource($f)) { + function _flush_read_buffer( $f ) { + if ( !is_resource( $f ) ) { return; } - $n = stream_select($r=array($f), $w = NULL, $e = NULL, 0, 0); - while ($n == 1 && !feof($f)) { - fread($f, 1024); - $n = stream_select($r=array($f), $w = NULL, $e = NULL, 0, 0); + $n = stream_select( $r = array( $f ), $w = null, $e = null, 0, 0 ); + while ( $n == 1 && !feof( $f ) ) { + fread( $f, 1024 ); + $n = stream_select( $r = array( $f ), $w = null, $e = null, 0, 0 ); } }