MediaWiki  1.27.2
MemcachedClient.php
Go to the documentation of this file.
1 <?php
2 // @codingStandardsIgnoreFile It's an external lib and it isn't. Let's not bother.
71 
72 // {{{ class MemcachedClient
80  // {{{ properties
81  // {{{ public
82 
83  // {{{ constants
84  // {{{ flags
85 
89  const SERIALIZED = 1;
90 
94  const COMPRESSED = 2;
95 
99  const INTVAL = 4;
100 
101  // }}}
102 
106  const COMPRESSION_SAVINGS = 0.20;
107 
108  // }}}
109 
116  public $stats;
117 
118  // }}}
119  // {{{ private
120 
127  public $_cache_sock;
128 
135  public $_debug;
136 
143  public $_host_dead;
144 
151  public $_have_zlib;
152 
160 
168 
175  public $_persistent;
176 
184 
191  public $_servers;
192 
199  public $_buckets;
200 
208 
215  public $_active;
216 
224 
232 
237 
242 
246  private $_logger;
247 
248  // }}}
249  // }}}
250  // {{{ methods
251  // {{{ public functions
252  // {{{ memcached()
253 
261  public function __construct( $args ) {
262  $this->set_servers( isset( $args['servers'] ) ? $args['servers'] : array() );
263  $this->_debug = isset( $args['debug'] ) ? $args['debug'] : false;
264  $this->stats = array();
265  $this->_compress_threshold = isset( $args['compress_threshold'] ) ? $args['compress_threshold'] : 0;
266  $this->_persistent = isset( $args['persistent'] ) ? $args['persistent'] : false;
267  $this->_compress_enable = true;
268  $this->_have_zlib = function_exists( 'gzcompress' );
269 
270  $this->_cache_sock = array();
271  $this->_host_dead = array();
272 
273  $this->_timeout_seconds = 0;
274  $this->_timeout_microseconds = isset( $args['timeout'] ) ? $args['timeout'] : 500000;
275 
276  $this->_connect_timeout = isset( $args['connect_timeout'] ) ? $args['connect_timeout'] : 0.1;
277  $this->_connect_attempts = 2;
278 
279  $this->_logger = isset( $args['logger'] ) ? $args['logger'] : new NullLogger();
280  }
281 
282  // }}}
283  // {{{ add()
284 
299  public function add( $key, $val, $exp = 0 ) {
300  return $this->_set( 'add', $key, $val, $exp );
301  }
302 
303  // }}}
304  // {{{ decr()
305 
314  public function decr( $key, $amt = 1 ) {
315  return $this->_incrdecr( 'decr', $key, $amt );
316  }
317 
318  // }}}
319  // {{{ delete()
320 
329  public function delete( $key, $time = 0 ) {
330  if ( !$this->_active ) {
331  return false;
332  }
333 
334  $sock = $this->get_sock( $key );
335  if ( !is_resource( $sock ) ) {
336  return false;
337  }
338 
339  $key = is_array( $key ) ? $key[1] : $key;
340 
341  if ( isset( $this->stats['delete'] ) ) {
342  $this->stats['delete']++;
343  } else {
344  $this->stats['delete'] = 1;
345  }
346  $cmd = "delete $key $time\r\n";
347  if ( !$this->_fwrite( $sock, $cmd ) ) {
348  return false;
349  }
350  $res = $this->_fgets( $sock );
351 
352  if ( $this->_debug ) {
353  $this->_debugprint( sprintf( "MemCache: delete %s (%s)", $key, $res ) );
354  }
355 
356  if ( $res == "DELETED" || $res == "NOT_FOUND" ) {
357  return true;
358  }
359 
360  return false;
361  }
362 
368  public function lock( $key, $timeout = 0 ) {
369  /* stub */
370  return true;
371  }
372 
377  public function unlock( $key ) {
378  /* stub */
379  return true;
380  }
381 
382  // }}}
383  // {{{ disconnect_all()
384 
388  public function disconnect_all() {
389  foreach ( $this->_cache_sock as $sock ) {
390  fclose( $sock );
391  }
392 
393  $this->_cache_sock = array();
394  }
395 
396  // }}}
397  // {{{ enable_compress()
398 
404  public function enable_compress( $enable ) {
405  $this->_compress_enable = $enable;
406  }
407 
408  // }}}
409  // {{{ forget_dead_hosts()
410 
414  public function forget_dead_hosts() {
415  $this->_host_dead = array();
416  }
417 
418  // }}}
419  // {{{ get()
420 
429  public function get( $key, &$casToken = null ) {
430 
431  if ( $this->_debug ) {
432  $this->_debugprint( "get($key)" );
433  }
434 
435  if ( !is_array( $key ) && strval( $key ) === '' ) {
436  $this->_debugprint( "Skipping key which equals to an empty string" );
437  return false;
438  }
439 
440  if ( !$this->_active ) {
441  return false;
442  }
443 
444  $sock = $this->get_sock( $key );
445 
446  if ( !is_resource( $sock ) ) {
447  return false;
448  }
449 
450  $key = is_array( $key ) ? $key[1] : $key;
451  if ( isset( $this->stats['get'] ) ) {
452  $this->stats['get']++;
453  } else {
454  $this->stats['get'] = 1;
455  }
456 
457  $cmd = "gets $key\r\n";
458  if ( !$this->_fwrite( $sock, $cmd ) ) {
459  return false;
460  }
461 
462  $val = array();
463  $this->_load_items( $sock, $val, $casToken );
464 
465  if ( $this->_debug ) {
466  foreach ( $val as $k => $v ) {
467  $this->_debugprint( sprintf( "MemCache: sock %s got %s", serialize( $sock ), $k ) );
468  }
469  }
470 
471  $value = false;
472  if ( isset( $val[$key] ) ) {
473  $value = $val[$key];
474  }
475  return $value;
476  }
477 
478  // }}}
479  // {{{ get_multi()
480 
488  public function get_multi( $keys ) {
489  if ( !$this->_active ) {
490  return false;
491  }
492 
493  if ( isset( $this->stats['get_multi'] ) ) {
494  $this->stats['get_multi']++;
495  } else {
496  $this->stats['get_multi'] = 1;
497  }
498  $sock_keys = array();
499  $socks = array();
500  foreach ( $keys as $key ) {
501  $sock = $this->get_sock( $key );
502  if ( !is_resource( $sock ) ) {
503  continue;
504  }
505  $key = is_array( $key ) ? $key[1] : $key;
506  if ( !isset( $sock_keys[$sock] ) ) {
507  $sock_keys[intval( $sock )] = array();
508  $socks[] = $sock;
509  }
510  $sock_keys[intval( $sock )][] = $key;
511  }
512 
513  $gather = array();
514  // Send out the requests
515  foreach ( $socks as $sock ) {
516  $cmd = 'gets';
517  foreach ( $sock_keys[intval( $sock )] as $key ) {
518  $cmd .= ' ' . $key;
519  }
520  $cmd .= "\r\n";
521 
522  if ( $this->_fwrite( $sock, $cmd ) ) {
523  $gather[] = $sock;
524  }
525  }
526 
527  // Parse responses
528  $val = array();
529  foreach ( $gather as $sock ) {
530  $this->_load_items( $sock, $val, $casToken );
531  }
532 
533  if ( $this->_debug ) {
534  foreach ( $val as $k => $v ) {
535  $this->_debugprint( sprintf( "MemCache: got %s", $k ) );
536  }
537  }
538 
539  return $val;
540  }
541 
542  // }}}
543  // {{{ incr()
544 
555  public function incr( $key, $amt = 1 ) {
556  return $this->_incrdecr( 'incr', $key, $amt );
557  }
558 
559  // }}}
560  // {{{ replace()
561 
575  public function replace( $key, $value, $exp = 0 ) {
576  return $this->_set( 'replace', $key, $value, $exp );
577  }
578 
579  // }}}
580  // {{{ run_command()
581 
591  public function run_command( $sock, $cmd ) {
592  if ( !is_resource( $sock ) ) {
593  return array();
594  }
595 
596  if ( !$this->_fwrite( $sock, $cmd ) ) {
597  return array();
598  }
599 
600  $ret = array();
601  while ( true ) {
602  $res = $this->_fgets( $sock );
603  $ret[] = $res;
604  if ( preg_match( '/^END/', $res ) ) {
605  break;
606  }
607  if ( strlen( $res ) == 0 ) {
608  break;
609  }
610  }
611  return $ret;
612  }
613 
614  // }}}
615  // {{{ set()
616 
631  public function set( $key, $value, $exp = 0 ) {
632  return $this->_set( 'set', $key, $value, $exp );
633  }
634 
635  // }}}
636  // {{{ cas()
637 
653  public function cas( $casToken, $key, $value, $exp = 0 ) {
654  return $this->_set( 'cas', $key, $value, $exp, $casToken );
655  }
656 
657  // }}}
658  // {{{ set_compress_threshold()
659 
665  public function set_compress_threshold( $thresh ) {
666  $this->_compress_threshold = $thresh;
667  }
668 
669  // }}}
670  // {{{ set_debug()
671 
678  public function set_debug( $dbg ) {
679  $this->_debug = $dbg;
680  }
681 
682  // }}}
683  // {{{ set_servers()
684 
691  public function set_servers( $list ) {
692  $this->_servers = $list;
693  $this->_active = count( $list );
694  $this->_buckets = null;
695  $this->_bucketcount = 0;
696 
697  $this->_single_sock = null;
698  if ( $this->_active == 1 ) {
699  $this->_single_sock = $this->_servers[0];
700  }
701  }
702 
709  public function set_timeout( $seconds, $microseconds ) {
710  $this->_timeout_seconds = $seconds;
711  $this->_timeout_microseconds = $microseconds;
712  }
713 
714  // }}}
715  // }}}
716  // {{{ private methods
717  // {{{ _close_sock()
718 
726  function _close_sock( $sock ) {
727  $host = array_search( $sock, $this->_cache_sock );
728  fclose( $this->_cache_sock[$host] );
729  unset( $this->_cache_sock[$host] );
730  }
731 
732  // }}}
733  // {{{ _connect_sock()
734 
744  function _connect_sock( &$sock, $host ) {
745  list( $ip, $port ) = preg_split( '/:(?=\d)/', $host );
746  $sock = false;
747  $timeout = $this->_connect_timeout;
748  $errno = $errstr = null;
749  for ( $i = 0; !$sock && $i < $this->_connect_attempts; $i++ ) {
750  MediaWiki\suppressWarnings();
751  if ( $this->_persistent == 1 ) {
752  $sock = pfsockopen( $ip, $port, $errno, $errstr, $timeout );
753  } else {
754  $sock = fsockopen( $ip, $port, $errno, $errstr, $timeout );
755  }
756  MediaWiki\restoreWarnings();
757  }
758  if ( !$sock ) {
759  $this->_error_log( "Error connecting to $host: $errstr" );
760  $this->_dead_host( $host );
761  return false;
762  }
763 
764  // Initialise timeout
765  stream_set_timeout( $sock, $this->_timeout_seconds, $this->_timeout_microseconds );
766 
767  // If the connection was persistent, flush the read buffer in case there
768  // was a previous incomplete request on this connection
769  if ( $this->_persistent ) {
770  $this->_flush_read_buffer( $sock );
771  }
772  return true;
773  }
774 
775  // }}}
776  // {{{ _dead_sock()
777 
785  function _dead_sock( $sock ) {
786  $host = array_search( $sock, $this->_cache_sock );
787  $this->_dead_host( $host );
788  }
789 
793  function _dead_host( $host ) {
794  $ip = explode( ':', $host )[0];
795  $this->_host_dead[$ip] = time() + 30 + intval( rand( 0, 10 ) );
796  $this->_host_dead[$host] = $this->_host_dead[$ip];
797  unset( $this->_cache_sock[$host] );
798  }
799 
800  // }}}
801  // {{{ get_sock()
802 
811  function get_sock( $key ) {
812  if ( !$this->_active ) {
813  return false;
814  }
815 
816  if ( $this->_single_sock !== null ) {
817  return $this->sock_to_host( $this->_single_sock );
818  }
819 
820  $hv = is_array( $key ) ? intval( $key[0] ) : $this->_hashfunc( $key );
821  if ( $this->_buckets === null ) {
822  $bu = array();
823  foreach ( $this->_servers as $v ) {
824  if ( is_array( $v ) ) {
825  for ( $i = 0; $i < $v[1]; $i++ ) {
826  $bu[] = $v[0];
827  }
828  } else {
829  $bu[] = $v;
830  }
831  }
832  $this->_buckets = $bu;
833  $this->_bucketcount = count( $bu );
834  }
835 
836  $realkey = is_array( $key ) ? $key[1] : $key;
837  for ( $tries = 0; $tries < 20; $tries++ ) {
838  $host = $this->_buckets[$hv % $this->_bucketcount];
839  $sock = $this->sock_to_host( $host );
840  if ( is_resource( $sock ) ) {
841  return $sock;
842  }
843  $hv = $this->_hashfunc( $hv . $realkey );
844  }
845 
846  return false;
847  }
848 
849  // }}}
850  // {{{ _hashfunc()
851 
860  function _hashfunc( $key ) {
861  # Hash function must be in [0,0x7ffffff]
862  # We take the first 31 bits of the MD5 hash, which unlike the hash
863  # function used in a previous version of this client, works
864  return hexdec( substr( md5( $key ), 0, 8 ) ) & 0x7fffffff;
865  }
866 
867  // }}}
868  // {{{ _incrdecr()
869 
880  function _incrdecr( $cmd, $key, $amt = 1 ) {
881  if ( !$this->_active ) {
882  return null;
883  }
884 
885  $sock = $this->get_sock( $key );
886  if ( !is_resource( $sock ) ) {
887  return null;
888  }
889 
890  $key = is_array( $key ) ? $key[1] : $key;
891  if ( isset( $this->stats[$cmd] ) ) {
892  $this->stats[$cmd]++;
893  } else {
894  $this->stats[$cmd] = 1;
895  }
896  if ( !$this->_fwrite( $sock, "$cmd $key $amt\r\n" ) ) {
897  return null;
898  }
899 
900  $line = $this->_fgets( $sock );
901  $match = array();
902  if ( !preg_match( '/^(\d+)/', $line, $match ) ) {
903  return null;
904  }
905  return $match[1];
906  }
907 
908  // }}}
909  // {{{ _load_items()
910 
921  function _load_items( $sock, &$ret, &$casToken = null ) {
922  $results = array();
923 
924  while ( 1 ) {
925  $decl = $this->_fgets( $sock );
926 
927  if ( $decl === false ) {
928  /*
929  * If nothing can be read, something is wrong because we know exactly when
930  * to stop reading (right after "END") and we return right after that.
931  */
932  return false;
933  } elseif ( preg_match( '/^VALUE (\S+) (\d+) (\d+) (\d+)$/', $decl, $match ) ) {
934  /*
935  * Read all data returned. This can be either one or multiple values.
936  * Save all that data (in an array) to be processed later: we'll first
937  * want to continue reading until "END" before doing anything else,
938  * to make sure that we don't leave our client in a state where it's
939  * output is not yet fully read.
940  */
941  $results[] = array(
942  $match[1], // rkey
943  $match[2], // flags
944  $match[3], // len
945  $match[4], // casToken
946  $this->_fread( $sock, $match[3] + 2 ), // data
947  );
948  } elseif ( $decl == "END" ) {
949  if ( count( $results ) == 0 ) {
950  return false;
951  }
952 
957  foreach ( $results as $vars ) {
958  list( $rkey, $flags, $len, $casToken, $data ) = $vars;
959 
960  if ( $data === false || substr( $data, -2 ) !== "\r\n" ) {
961  $this->_handle_error( $sock,
962  'line ending missing from data block from $1' );
963  return false;
964  }
965  $data = substr( $data, 0, -2 );
966  $ret[$rkey] = $data;
967 
968  if ( $this->_have_zlib && $flags & self::COMPRESSED ) {
969  $ret[$rkey] = gzuncompress( $ret[$rkey] );
970  }
971 
972  /*
973  * This unserialize is the exact reason that we only want to
974  * process data after having read until "END" (instead of doing
975  * this right away): "unserialize" can trigger outside code:
976  * in the event that $ret[$rkey] is a serialized object,
977  * unserializing it will trigger __wakeup() if present. If that
978  * function attempted to read from memcached (while we did not
979  * yet read "END"), these 2 calls would collide.
980  */
981  if ( $flags & self::SERIALIZED ) {
982  $ret[$rkey] = unserialize( $ret[$rkey] );
983  } elseif ( $flags & self::INTVAL ) {
984  $ret[$rkey] = intval( $ret[$rkey] );
985  }
986  }
987 
988  return true;
989  } else {
990  $this->_handle_error( $sock, 'Error parsing response from $1' );
991  return false;
992  }
993  }
994  }
995 
996  // }}}
997  // {{{ _set()
998 
1015  function _set( $cmd, $key, $val, $exp, $casToken = null ) {
1016  if ( !$this->_active ) {
1017  return false;
1018  }
1019 
1020  $sock = $this->get_sock( $key );
1021  if ( !is_resource( $sock ) ) {
1022  return false;
1023  }
1024 
1025  if ( isset( $this->stats[$cmd] ) ) {
1026  $this->stats[$cmd]++;
1027  } else {
1028  $this->stats[$cmd] = 1;
1029  }
1030 
1031  $flags = 0;
1032 
1033  if ( is_int( $val ) ) {
1034  $flags |= self::INTVAL;
1035  } elseif ( !is_scalar( $val ) ) {
1036  $val = serialize( $val );
1037  $flags |= self::SERIALIZED;
1038  if ( $this->_debug ) {
1039  $this->_debugprint( sprintf( "client: serializing data as it is not scalar" ) );
1040  }
1041  }
1042 
1043  $len = strlen( $val );
1044 
1045  if ( $this->_have_zlib && $this->_compress_enable
1046  && $this->_compress_threshold && $len >= $this->_compress_threshold
1047  ) {
1048  $c_val = gzcompress( $val, 9 );
1049  $c_len = strlen( $c_val );
1050 
1051  if ( $c_len < $len * ( 1 - self::COMPRESSION_SAVINGS ) ) {
1052  if ( $this->_debug ) {
1053  $this->_debugprint( sprintf( "client: compressing data; was %d bytes is now %d bytes", $len, $c_len ) );
1054  }
1055  $val = $c_val;
1056  $len = $c_len;
1057  $flags |= self::COMPRESSED;
1058  }
1059  }
1060 
1061  $command = "$cmd $key $flags $exp $len";
1062  if ( $casToken ) {
1063  $command .= " $casToken";
1064  }
1065 
1066  if ( !$this->_fwrite( $sock, "$command\r\n$val\r\n" ) ) {
1067  return false;
1068  }
1069 
1070  $line = $this->_fgets( $sock );
1071 
1072  if ( $this->_debug ) {
1073  $this->_debugprint( sprintf( "%s %s (%s)", $cmd, $key, $line ) );
1074  }
1075  if ( $line == "STORED" ) {
1076  return true;
1077  }
1078  return false;
1079  }
1080 
1081  // }}}
1082  // {{{ sock_to_host()
1083 
1092  function sock_to_host( $host ) {
1093  if ( isset( $this->_cache_sock[$host] ) ) {
1094  return $this->_cache_sock[$host];
1095  }
1096 
1097  $sock = null;
1098  $now = time();
1099  list( $ip, /* $port */) = explode( ':', $host );
1100  if ( isset( $this->_host_dead[$host] ) && $this->_host_dead[$host] > $now ||
1101  isset( $this->_host_dead[$ip] ) && $this->_host_dead[$ip] > $now
1102  ) {
1103  return null;
1104  }
1105 
1106  if ( !$this->_connect_sock( $sock, $host ) ) {
1107  return null;
1108  }
1109 
1110  // Do not buffer writes
1111  stream_set_write_buffer( $sock, 0 );
1112 
1113  $this->_cache_sock[$host] = $sock;
1114 
1115  return $this->_cache_sock[$host];
1116  }
1117 
1121  function _debugprint( $text ) {
1122  $this->_logger->debug( $text );
1123  }
1124 
1128  function _error_log( $text ) {
1129  $this->_logger->error( "Memcached error: $text" );
1130  }
1131 
1139  function _fwrite( $sock, $buf ) {
1140  $bytesWritten = 0;
1141  $bufSize = strlen( $buf );
1142  while ( $bytesWritten < $bufSize ) {
1143  $result = fwrite( $sock, $buf );
1144  $data = stream_get_meta_data( $sock );
1145  if ( $data['timed_out'] ) {
1146  $this->_handle_error( $sock, 'timeout writing to $1' );
1147  return false;
1148  }
1149  // Contrary to the documentation, fwrite() returns zero on error in PHP 5.3.
1150  if ( $result === false || $result === 0 ) {
1151  $this->_handle_error( $sock, 'error writing to $1' );
1152  return false;
1153  }
1154  $bytesWritten += $result;
1155  }
1156 
1157  return true;
1158  }
1159 
1166  function _handle_error( $sock, $msg ) {
1167  $peer = stream_socket_get_name( $sock, true );
1168  if ( strval( $peer ) === '' ) {
1169  $peer = array_search( $sock, $this->_cache_sock );
1170  if ( $peer === false ) {
1171  $peer = '[unknown host]';
1172  }
1173  }
1174  $msg = str_replace( '$1', $peer, $msg );
1175  $this->_error_log( "$msg" );
1176  $this->_dead_sock( $sock );
1177  }
1178 
1187  function _fread( $sock, $len ) {
1188  $buf = '';
1189  while ( $len > 0 ) {
1190  $result = fread( $sock, $len );
1191  $data = stream_get_meta_data( $sock );
1192  if ( $data['timed_out'] ) {
1193  $this->_handle_error( $sock, 'timeout reading from $1' );
1194  return false;
1195  }
1196  if ( $result === false ) {
1197  $this->_handle_error( $sock, 'error reading buffer from $1' );
1198  return false;
1199  }
1200  if ( $result === '' ) {
1201  // This will happen if the remote end of the socket is shut down
1202  $this->_handle_error( $sock, 'unexpected end of file reading from $1' );
1203  return false;
1204  }
1205  $len -= strlen( $result );
1206  $buf .= $result;
1207  }
1208  return $buf;
1209  }
1210 
1218  function _fgets( $sock ) {
1219  $result = fgets( $sock );
1220  // fgets() may return a partial line if there is a select timeout after
1221  // a successful recv(), so we have to check for a timeout even if we
1222  // got a string response.
1223  $data = stream_get_meta_data( $sock );
1224  if ( $data['timed_out'] ) {
1225  $this->_handle_error( $sock, 'timeout reading line from $1' );
1226  return false;
1227  }
1228  if ( $result === false ) {
1229  $this->_handle_error( $sock, 'error reading line from $1' );
1230  return false;
1231  }
1232  if ( substr( $result, -2 ) === "\r\n" ) {
1233  $result = substr( $result, 0, -2 );
1234  } elseif ( substr( $result, -1 ) === "\n" ) {
1235  $result = substr( $result, 0, -1 );
1236  } else {
1237  $this->_handle_error( $sock, 'line ending missing in response from $1' );
1238  return false;
1239  }
1240  return $result;
1241  }
1242 
1247  function _flush_read_buffer( $f ) {
1248  if ( !is_resource( $f ) ) {
1249  return;
1250  }
1251  $r = array( $f );
1252  $w = null;
1253  $e = null;
1254  $n = stream_select( $r, $w, $e, 0, 0 );
1255  while ( $n == 1 && !feof( $f ) ) {
1256  fread( $f, 1024 );
1257  $r = array( $f );
1258  $w = null;
1259  $e = null;
1260  $n = stream_select( $r, $w, $e, 0, 0 );
1261  }
1262  }
1263 
1264  // }}}
1265  // }}}
1266  // }}}
1267 }
1268 
1269 // }}}
set_servers($list)
Set the server list to distribute key gets and puts between.
set_timeout($seconds, $microseconds)
Sets the timeout for new connections.
_fwrite($sock, $buf)
Write to a stream.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
lock($key, $timeout=0)
the array() calling protocol came about after MediaWiki 1.4rc1.
_handle_error($sock, $msg)
Handle an I/O error.
magic word the default is to use $key to get the and $key value or $key value text $key value html to format the value $key
Definition: hooks.txt:2321
array $stats
Command statistics.
get_sock($key)
get_sock
memcached client class implemented using (p)fsockopen()
get_multi($keys)
Get multiple keys from the server(s)
array $_host_dead
Dead hosts, assoc array, 'host'=>'unixtime when ok to check again'.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException'returning false will NOT prevent logging $e
Definition: hooks.txt:1932
$command
Definition: cdb.php:65
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
Definition: hooks.txt:1798
const INTVAL
Flag: indicates data is an integer.
$value
incr($key, $amt=1)
Increments $key (optionally) by $amt.
_load_items($sock, &$ret, &$casToken=null)
Load items into $ret from $sock.
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition: hooks.txt:2548
forget_dead_hosts()
Forget about all of the dead hosts.
$_connect_timeout
Connect timeout in seconds.
_dead_sock($sock)
Marks a host as dead until 30-40 seconds in the future.
disconnect_all()
Disconnects all connected sockets.
int $_timeout_microseconds
Stream timeout in microseconds.
see documentation in includes Linker php for Linker::makeImageLink & $time
Definition: hooks.txt:1612
_fread($sock, $len)
Read the specified number of bytes from a stream.
bool $_have_zlib
Is compression available?
_connect_sock(&$sock, $host)
Connects $sock to $host, timing out after $timeout.
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message.Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item.Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page.Return false to stop further processing of the tag $reader:XMLReader object &$pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision.Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag.Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload.Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports.&$fullInterwikiPrefix:Interwiki prefix, may contain colons.&$pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable.Can be used to lazy-load the import sources list.&$importSources:The value of $wgImportSources.Modify as necessary.See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page.$context:IContextSource object &$pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect.&$title:Title object for the current page &$request:WebRequest &$ignoreRedirect:boolean to skip redirect check &$target:Title/string of redirect target &$article:Article object 'InternalParseBeforeLinks':during Parser's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InternalParseBeforeSanitize':during Parser's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings.Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not.Return true without providing an interwiki to continue interwiki search.$prefix:interwiki prefix we are looking for.&$iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user's email has been invalidated successfully.$user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification.Callee may modify $url and $query, URL will be constructed as $url.$query &$url:URL to index.php &$query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) &$article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() &$ip:IP being check &$result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from &$allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn't match your organization.$addr:The e-mail address entered by the user &$result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user &$result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we're looking for a messages file for &$file:The messages file path, you can override this to change the location. 'LanguageGetMagic':DEPRECATED!Use $magicWords in a file listed in $wgExtensionMessagesFiles instead.Use this to define synonyms of magic words depending of the language &$magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces.Do not use this hook to add namespaces.Use CanonicalNamespaces for that.&$namespaces:Array of namespaces indexed by their numbers 'LanguageGetSpecialPageAliases':DEPRECATED!Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead.Use to define aliases of special pages names depending of the language &$specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names.&$names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page's language links.This is called in various places to allow extensions to define the effective language links for a page.$title:The page's Title.&$links:Associative array mapping language codes to prefixed links of the form"language:title".&$linkFlags:Associative array mapping prefixed links to arrays of flags.Currently unused, but planned to provide support for marking individual language links in the UI, e.g.for featured articles. 'LanguageSelector':Hook to change the language selector available on a page.$out:The output page.$cssClassName:CSS class name of the language selector. 'LinkBegin':Used when generating internal and interwiki links in Linker::link(), before processing starts.Return false to skip default processing and return $ret.See documentation for Linker::link() for details on the expected meanings of parameters.$skin:the Skin object $target:the Title that the link is pointing to &$html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1796
if($line===false) $args
Definition: cdb.php:64
int $_timeout_seconds
Stream timeout in seconds.
_fgets($sock)
Read a line from a stream.
set($key, $value, $exp=0)
Unconditionally sets a key to a given value in the memcache.
int $_compress_threshold
At how many bytes should we compress?
bool $_persistent
Are we using persistent links?
unserialize($serialized)
Definition: ApiMessage.php:102
$res
Definition: database.txt:21
const SERIALIZED
Flag: indicates data is serialized.
enable_compress($enable)
Enable / Disable compression.
set_compress_threshold($thresh)
Set the compression threshold.
add($key, $val, $exp=0)
Adds a key/value to the memcache server if one isn't already set with that key.
cas($casToken, $key, $value, $exp=0)
Sets a key to a given value in the memcache if the current value still corresponds to a known...
array $_servers
Array containing ip:port or array(ip:port, weight)
set_debug($dbg)
Set the debug flag.
bool $_debug
Current debug status; 0 - none to 9 - profiling.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
__construct($args)
Memcache initializer.
array $_buckets
Our bit buckets.
string $_single_sock
If only using one server; contains ip:port to connect to.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
_flush_read_buffer($f)
Flush the read buffer of a stream.
int $_active
of total servers we have
_set($cmd, $key, $val, $exp, $casToken=null)
Performs the requested storage operation to the memcache server.
bool $_compress_enable
Do we want to use compression?
$line
Definition: cdb.php:59
_close_sock($sock)
Close the specified socket.
replace($key, $value, $exp=0)
Overwrites an existing value for key; only works if key is already set.
array $_cache_sock
Cached Sockets that are connected.
const COMPRESSED
Flag: indicates data is compressed.
run_command($sock, $cmd)
Passes through $cmd to the memcache server connected by $sock; returns output as an array (null array...
_hashfunc($key)
Creates a hash integer based on the $key.
serialize()
Definition: ApiMessage.php:94
const COMPRESSION_SAVINGS
Minimum savings to store data compressed.
sock_to_host($host)
Returns the socket for the host.
int $_bucketcount
Total # of bit buckets we have.
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition: hooks.txt:1996
$_connect_attempts
Number of connection attempts for each server.
decr($key, $amt=1)
Decrease a value stored on the memcache server.
_incrdecr($cmd, $key, $amt=1)
Perform increment/decriment on $key.
LoggerInterface $_logger