MediaWiki  1.28.0
IP.php
Go to the documentation of this file.
1 <?php
25 
26 // Some regex definition to "play" with IP address and IP address blocks
27 
28 // An IPv4 address is made of 4 bytes from x00 to xFF which is d0 to d255
29 define( 'RE_IP_BYTE', '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])' );
30 define( 'RE_IP_ADD', RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE . '\.' . RE_IP_BYTE );
31 // An IPv4 block is an IP address and a prefix (d1 to d32)
32 define( 'RE_IP_PREFIX', '(3[0-2]|[12]?\d)' );
33 define( 'RE_IP_BLOCK', RE_IP_ADD . '\/' . RE_IP_PREFIX );
34 
35 // An IPv6 address is made up of 8 words (each x0000 to xFFFF).
36 // However, the "::" abbreviation can be used on consecutive x0000 words.
37 define( 'RE_IPV6_WORD', '([0-9A-Fa-f]{1,4})' );
38 define( 'RE_IPV6_PREFIX', '(12[0-8]|1[01][0-9]|[1-9]?\d)' );
39 define( 'RE_IPV6_ADD',
40  '(?:' . // starts with "::" (including "::")
41  ':(?::|(?::' . RE_IPV6_WORD . '){1,7})' .
42  '|' . // ends with "::" (except "::")
43  RE_IPV6_WORD . '(?::' . RE_IPV6_WORD . '){0,6}::' .
44  '|' . // contains one "::" in the middle (the ^ makes the test fail if none found)
45  RE_IPV6_WORD . '(?::((?(-1)|:))?' . RE_IPV6_WORD . '){1,6}(?(-2)|^)' .
46  '|' . // contains no "::"
47  RE_IPV6_WORD . '(?::' . RE_IPV6_WORD . '){7}' .
48  ')'
49 );
50 // An IPv6 block is an IP address and a prefix (d1 to d128)
51 define( 'RE_IPV6_BLOCK', RE_IPV6_ADD . '\/' . RE_IPV6_PREFIX );
52 // For IPv6 canonicalization (NOT for strict validation; these are quite lax!)
53 define( 'RE_IPV6_GAP', ':(?:0+:)*(?::(?:0+:)*)?' );
54 define( 'RE_IPV6_V4_PREFIX', '0*' . RE_IPV6_GAP . '(?:ffff:)?' );
55 
56 // This might be useful for regexps used elsewhere, matches any IPv4 or IPv6 address or network
57 define( 'IP_ADDRESS_STRING',
58  '(?:' .
59  RE_IP_ADD . '(?:\/' . RE_IP_PREFIX . ')?' . // IPv4
60  '|' .
61  RE_IPV6_ADD . '(?:\/' . RE_IPV6_PREFIX . ')?' . // IPv6
62  ')'
63 );
64 
69 class IP {
71  private static $proxyIpSet = null;
72 
81  public static function isIPAddress( $ip ) {
82  return (bool)preg_match( '/^' . IP_ADDRESS_STRING . '$/', $ip );
83  }
84 
92  public static function isIPv6( $ip ) {
93  return (bool)preg_match( '/^' . RE_IPV6_ADD . '(?:\/' . RE_IPV6_PREFIX . ')?$/', $ip );
94  }
95 
103  public static function isIPv4( $ip ) {
104  return (bool)preg_match( '/^' . RE_IP_ADD . '(?:\/' . RE_IP_PREFIX . ')?$/', $ip );
105  }
106 
115  public static function isValid( $ip ) {
116  return ( preg_match( '/^' . RE_IP_ADD . '$/', $ip )
117  || preg_match( '/^' . RE_IPV6_ADD . '$/', $ip ) );
118  }
119 
128  public static function isValidBlock( $ipblock ) {
129  return ( preg_match( '/^' . RE_IPV6_BLOCK . '$/', $ipblock )
130  || preg_match( '/^' . RE_IP_BLOCK . '$/', $ipblock ) );
131  }
132 
142  public static function sanitizeIP( $ip ) {
143  $ip = trim( $ip );
144  if ( $ip === '' ) {
145  return null;
146  }
147  /* If not an IP, just return trimmed value, since sanitizeIP() is called
148  * in a number of contexts where usernames are supplied as input.
149  */
150  if ( !self::isIPAddress( $ip ) ) {
151  return $ip;
152  }
153  if ( self::isIPv4( $ip ) ) {
154  // Remove leading 0's from octet representation of IPv4 address
155  $ip = preg_replace( '/(?:^|(?<=\.))0+(?=[1-9]|0\.|0$)/', '', $ip );
156  return $ip;
157  }
158  // Remove any whitespaces, convert to upper case
159  $ip = strtoupper( $ip );
160  // Expand zero abbreviations
161  $abbrevPos = strpos( $ip, '::' );
162  if ( $abbrevPos !== false ) {
163  // We know this is valid IPv6. Find the last index of the
164  // address before any CIDR number (e.g. "a:b:c::/24").
165  $CIDRStart = strpos( $ip, "/" );
166  $addressEnd = ( $CIDRStart !== false )
167  ? $CIDRStart - 1
168  : strlen( $ip ) - 1;
169  // If the '::' is at the beginning...
170  if ( $abbrevPos == 0 ) {
171  $repeat = '0:';
172  $extra = ( $ip == '::' ) ? '0' : ''; // for the address '::'
173  $pad = 9; // 7+2 (due to '::')
174  // If the '::' is at the end...
175  } elseif ( $abbrevPos == ( $addressEnd - 1 ) ) {
176  $repeat = ':0';
177  $extra = '';
178  $pad = 9; // 7+2 (due to '::')
179  // If the '::' is in the middle...
180  } else {
181  $repeat = ':0';
182  $extra = ':';
183  $pad = 8; // 6+2 (due to '::')
184  }
185  $ip = str_replace( '::',
186  str_repeat( $repeat, $pad - substr_count( $ip, ':' ) ) . $extra,
187  $ip
188  );
189  }
190  // Remove leading zeros from each bloc as needed
191  $ip = preg_replace( '/(^|:)0+(' . RE_IPV6_WORD . ')/', '$1$2', $ip );
192 
193  return $ip;
194  }
195 
203  public static function prettifyIP( $ip ) {
204  $ip = self::sanitizeIP( $ip ); // normalize (removes '::')
205  if ( self::isIPv6( $ip ) ) {
206  // Split IP into an address and a CIDR
207  if ( strpos( $ip, '/' ) !== false ) {
208  list( $ip, $cidr ) = explode( '/', $ip, 2 );
209  } else {
210  list( $ip, $cidr ) = [ $ip, '' ];
211  }
212  // Get the largest slice of words with multiple zeros
213  $offset = 0;
214  $longest = $longestPos = false;
215  while ( preg_match(
216  '!(?:^|:)0(?::0)+(?:$|:)!', $ip, $m, PREG_OFFSET_CAPTURE, $offset
217  ) ) {
218  list( $match, $pos ) = $m[0]; // full match
219  if ( strlen( $match ) > strlen( $longest ) ) {
220  $longest = $match;
221  $longestPos = $pos;
222  }
223  $offset = ( $pos + strlen( $match ) ); // advance
224  }
225  if ( $longest !== false ) {
226  // Replace this portion of the string with the '::' abbreviation
227  $ip = substr_replace( $ip, '::', $longestPos, strlen( $longest ) );
228  }
229  // Add any CIDR back on
230  if ( $cidr !== '' ) {
231  $ip = "{$ip}/{$cidr}";
232  }
233  // Convert to lower case to make it more readable
234  $ip = strtolower( $ip );
235  }
236 
237  return $ip;
238  }
239 
256  public static function splitHostAndPort( $both ) {
257  if ( substr( $both, 0, 1 ) === '[' ) {
258  if ( preg_match( '/^\[(' . RE_IPV6_ADD . ')\](?::(?P<port>\d+))?$/', $both, $m ) ) {
259  if ( isset( $m['port'] ) ) {
260  return [ $m[1], intval( $m['port'] ) ];
261  } else {
262  return [ $m[1], false ];
263  }
264  } else {
265  // Square bracket found but no IPv6
266  return false;
267  }
268  }
269  $numColons = substr_count( $both, ':' );
270  if ( $numColons >= 2 ) {
271  // Is it a bare IPv6 address?
272  if ( preg_match( '/^' . RE_IPV6_ADD . '$/', $both ) ) {
273  return [ $both, false ];
274  } else {
275  // Not valid IPv6, but too many colons for anything else
276  return false;
277  }
278  }
279  if ( $numColons >= 1 ) {
280  // Host:port?
281  $bits = explode( ':', $both );
282  if ( preg_match( '/^\d+/', $bits[1] ) ) {
283  return [ $bits[0], intval( $bits[1] ) ];
284  } else {
285  // Not a valid port
286  return false;
287  }
288  }
289 
290  // Plain hostname
291  return [ $both, false ];
292  }
293 
305  public static function combineHostAndPort( $host, $port, $defaultPort = false ) {
306  if ( strpos( $host, ':' ) !== false ) {
307  $host = "[$host]";
308  }
309  if ( $defaultPort !== false && $port == $defaultPort ) {
310  return $host;
311  } else {
312  return "$host:$port";
313  }
314  }
315 
322  public static function formatHex( $hex ) {
323  if ( substr( $hex, 0, 3 ) == 'v6-' ) { // IPv6
324  return self::hexToOctet( substr( $hex, 3 ) );
325  } else { // IPv4
326  return self::hexToQuad( $hex );
327  }
328  }
329 
336  public static function hexToOctet( $ip_hex ) {
337  // Pad hex to 32 chars (128 bits)
338  $ip_hex = str_pad( strtoupper( $ip_hex ), 32, '0', STR_PAD_LEFT );
339  // Separate into 8 words
340  $ip_oct = substr( $ip_hex, 0, 4 );
341  for ( $n = 1; $n < 8; $n++ ) {
342  $ip_oct .= ':' . substr( $ip_hex, 4 * $n, 4 );
343  }
344  // NO leading zeroes
345  $ip_oct = preg_replace( '/(^|:)0+(' . RE_IPV6_WORD . ')/', '$1$2', $ip_oct );
346 
347  return $ip_oct;
348  }
349 
356  public static function hexToQuad( $ip_hex ) {
357  // Pad hex to 8 chars (32 bits)
358  $ip_hex = str_pad( strtoupper( $ip_hex ), 8, '0', STR_PAD_LEFT );
359  // Separate into four quads
360  $s = '';
361  for ( $i = 0; $i < 4; $i++ ) {
362  if ( $s !== '' ) {
363  $s .= '.';
364  }
365  $s .= base_convert( substr( $ip_hex, $i * 2, 2 ), 16, 10 );
366  }
367 
368  return $s;
369  }
370 
378  public static function isPublic( $ip ) {
379  static $privateSet = null;
380  if ( !$privateSet ) {
381  $privateSet = new IPSet( [
382  '10.0.0.0/8', # RFC 1918 (private)
383  '172.16.0.0/12', # RFC 1918 (private)
384  '192.168.0.0/16', # RFC 1918 (private)
385  '0.0.0.0/8', # this network
386  '127.0.0.0/8', # loopback
387  'fc00::/7', # RFC 4193 (local)
388  '0:0:0:0:0:0:0:1', # loopback
389  '169.254.0.0/16', # link-local
390  'fe80::/10', # link-local
391  ] );
392  }
393  return !$privateSet->match( $ip );
394  }
395 
407  public static function toHex( $ip ) {
408  if ( self::isIPv6( $ip ) ) {
409  $n = 'v6-' . self::IPv6ToRawHex( $ip );
410  } elseif ( self::isIPv4( $ip ) ) {
411  // T62035/T97897: An IP with leading 0's fails in ip2long sometimes (e.g. *.08),
412  // also double/triple 0 needs to be changed to just a single 0 for ip2long.
413  $ip = self::sanitizeIP( $ip );
414  $n = ip2long( $ip );
415  if ( $n < 0 ) {
416  $n += pow( 2, 32 );
417  # On 32-bit platforms (and on Windows), 2^32 does not fit into an int,
418  # so $n becomes a float. We convert it to string instead.
419  if ( is_float( $n ) ) {
420  $n = (string)$n;
421  }
422  }
423  if ( $n !== false ) {
424  # Floating points can handle the conversion; faster than Wikimedia\base_convert()
425  $n = strtoupper( str_pad( base_convert( $n, 10, 16 ), 8, '0', STR_PAD_LEFT ) );
426  }
427  } else {
428  $n = false;
429  }
430 
431  return $n;
432  }
433 
440  private static function IPv6ToRawHex( $ip ) {
441  $ip = self::sanitizeIP( $ip );
442  if ( !$ip ) {
443  return false;
444  }
445  $r_ip = '';
446  foreach ( explode( ':', $ip ) as $v ) {
447  $r_ip .= str_pad( $v, 4, 0, STR_PAD_LEFT );
448  }
449 
450  return $r_ip;
451  }
452 
460  public static function parseCIDR( $range ) {
461  if ( self::isIPv6( $range ) ) {
462  return self::parseCIDR6( $range );
463  }
464  $parts = explode( '/', $range, 2 );
465  if ( count( $parts ) != 2 ) {
466  return [ false, false ];
467  }
468  list( $network, $bits ) = $parts;
469  $network = ip2long( $network );
470  if ( $network !== false && is_numeric( $bits ) && $bits >= 0 && $bits <= 32 ) {
471  if ( $bits == 0 ) {
472  $network = 0;
473  } else {
474  $network &= ~( ( 1 << ( 32 - $bits ) ) - 1 );
475  }
476  # Convert to unsigned
477  if ( $network < 0 ) {
478  $network += pow( 2, 32 );
479  }
480  } else {
481  $network = false;
482  $bits = false;
483  }
484 
485  return [ $network, $bits ];
486  }
487 
503  public static function parseRange( $range ) {
504  // CIDR notation
505  if ( strpos( $range, '/' ) !== false ) {
506  if ( self::isIPv6( $range ) ) {
507  return self::parseRange6( $range );
508  }
509  list( $network, $bits ) = self::parseCIDR( $range );
510  if ( $network === false ) {
511  $start = $end = false;
512  } else {
513  $start = sprintf( '%08X', $network );
514  $end = sprintf( '%08X', $network + pow( 2, ( 32 - $bits ) ) - 1 );
515  }
516  // Explicit range
517  } elseif ( strpos( $range, '-' ) !== false ) {
518  list( $start, $end ) = array_map( 'trim', explode( '-', $range, 2 ) );
519  if ( self::isIPv6( $start ) && self::isIPv6( $end ) ) {
520  return self::parseRange6( $range );
521  }
522  if ( self::isIPv4( $start ) && self::isIPv4( $end ) ) {
523  $start = self::toHex( $start );
524  $end = self::toHex( $end );
525  if ( $start > $end ) {
526  $start = $end = false;
527  }
528  } else {
529  $start = $end = false;
530  }
531  } else {
532  # Single IP
533  $start = $end = self::toHex( $range );
534  }
535  if ( $start === false || $end === false ) {
536  return [ false, false ];
537  } else {
538  return [ $start, $end ];
539  }
540  }
541 
550  private static function parseCIDR6( $range ) {
551  # Explode into <expanded IP,range>
552  $parts = explode( '/', IP::sanitizeIP( $range ), 2 );
553  if ( count( $parts ) != 2 ) {
554  return [ false, false ];
555  }
556  list( $network, $bits ) = $parts;
557  $network = self::IPv6ToRawHex( $network );
558  if ( $network !== false && is_numeric( $bits ) && $bits >= 0 && $bits <= 128 ) {
559  if ( $bits == 0 ) {
560  $network = "0";
561  } else {
562  # Native 32 bit functions WONT work here!!!
563  # Convert to a padded binary number
564  $network = Wikimedia\base_convert( $network, 16, 2, 128 );
565  # Truncate the last (128-$bits) bits and replace them with zeros
566  $network = str_pad( substr( $network, 0, $bits ), 128, 0, STR_PAD_RIGHT );
567  # Convert back to an integer
568  $network = Wikimedia\base_convert( $network, 2, 10 );
569  }
570  } else {
571  $network = false;
572  $bits = false;
573  }
574 
575  return [ $network, (int)$bits ];
576  }
577 
591  private static function parseRange6( $range ) {
592  # Expand any IPv6 IP
593  $range = IP::sanitizeIP( $range );
594  // CIDR notation...
595  if ( strpos( $range, '/' ) !== false ) {
596  list( $network, $bits ) = self::parseCIDR6( $range );
597  if ( $network === false ) {
598  $start = $end = false;
599  } else {
600  $start = Wikimedia\base_convert( $network, 10, 16, 32, false );
601  # Turn network to binary (again)
602  $end = Wikimedia\base_convert( $network, 10, 2, 128 );
603  # Truncate the last (128-$bits) bits and replace them with ones
604  $end = str_pad( substr( $end, 0, $bits ), 128, 1, STR_PAD_RIGHT );
605  # Convert to hex
606  $end = Wikimedia\base_convert( $end, 2, 16, 32, false );
607  # see toHex() comment
608  $start = "v6-$start";
609  $end = "v6-$end";
610  }
611  // Explicit range notation...
612  } elseif ( strpos( $range, '-' ) !== false ) {
613  list( $start, $end ) = array_map( 'trim', explode( '-', $range, 2 ) );
614  $start = self::toHex( $start );
615  $end = self::toHex( $end );
616  if ( $start > $end ) {
617  $start = $end = false;
618  }
619  } else {
620  # Single IP
621  $start = $end = self::toHex( $range );
622  }
623  if ( $start === false || $end === false ) {
624  return [ false, false ];
625  } else {
626  return [ $start, $end ];
627  }
628  }
629 
640  public static function isInRange( $addr, $range ) {
641  $hexIP = self::toHex( $addr );
642  list( $start, $end ) = self::parseRange( $range );
643 
644  return ( strcmp( $hexIP, $start ) >= 0 &&
645  strcmp( $hexIP, $end ) <= 0 );
646  }
647 
658  public static function isInRanges( $ip, $ranges ) {
659  foreach ( $ranges as $range ) {
660  if ( self::isInRange( $ip, $range ) ) {
661  return true;
662  }
663  }
664  return false;
665  }
666 
677  public static function canonicalize( $addr ) {
678  // remove zone info (bug 35738)
679  $addr = preg_replace( '/\%.*/', '', $addr );
680 
681  if ( self::isValid( $addr ) ) {
682  return $addr;
683  }
684  // Turn mapped addresses from ::ce:ffff:1.2.3.4 to 1.2.3.4
685  if ( strpos( $addr, ':' ) !== false && strpos( $addr, '.' ) !== false ) {
686  $addr = substr( $addr, strrpos( $addr, ':' ) + 1 );
687  if ( self::isIPv4( $addr ) ) {
688  return $addr;
689  }
690  }
691  // IPv6 loopback address
692  $m = [];
693  if ( preg_match( '/^0*' . RE_IPV6_GAP . '1$/', $addr, $m ) ) {
694  return '127.0.0.1';
695  }
696  // IPv4-mapped and IPv4-compatible IPv6 addresses
697  if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . '(' . RE_IP_ADD . ')$/i', $addr, $m ) ) {
698  return $m[1];
699  }
700  if ( preg_match( '/^' . RE_IPV6_V4_PREFIX . RE_IPV6_WORD .
701  ':' . RE_IPV6_WORD . '$/i', $addr, $m )
702  ) {
703  return long2ip( ( hexdec( $m[1] ) << 16 ) + hexdec( $m[2] ) );
704  }
705 
706  return null; // give up
707  }
708 
715  public static function sanitizeRange( $range ) {
716  list( /*...*/, $bits ) = self::parseCIDR( $range );
717  list( $start, /*...*/ ) = self::parseRange( $range );
718  $start = self::formatHex( $start );
719  if ( $bits === false ) {
720  return $start; // wasn't actually a range
721  }
722 
723  return "$start/$bits";
724  }
725 
732  public static function getSubnet( $ip ) {
733  $matches = [];
734  $subnet = false;
735  if ( IP::isIPv6( $ip ) ) {
736  $parts = IP::parseRange( "$ip/64" );
737  $subnet = $parts[0];
738  } elseif ( preg_match( '/^(\d+\.\d+\.\d+)\.\d+$/', $ip, $matches ) ) {
739  // IPv4
740  $subnet = $matches[1];
741  }
742  return $subnet;
743  }
744 }
static hexToOctet($ip_hex)
Converts a hexadecimal number to an IPv6 address in octet notation.
Definition: IP.php:334
static isInRanges($ip, $ranges)
Determines if an IP address is a list of CIDR a.b.c.d/n ranges.
Definition: IP.php:656
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
static sanitizeIP($ip)
Convert an IP into a verbose, uppercase, normalized form.
Definition: IP.php:140
static isInRange($addr, $range)
Determine if a given IPv4/IPv6 address is in a given CIDR network.
Definition: IP.php:638
static parseCIDR6($range)
Convert a network specification in IPv6 CIDR notation to an integer network and a number of bits...
Definition: IP.php:548
static sanitizeRange($range)
Gets rid of unneeded numbers in quad-dotted/octet IP strings For example, 127.111.113.151/24 -> 127.111.113.0/24.
Definition: IP.php:713
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:189
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
const RE_IPV6_WORD
Definition: IP.php:37
const RE_IPV6_BLOCK
Definition: IP.php:50
const RE_IPV6_PREFIX
Definition: IP.php:38
const RE_IPV6_GAP
Definition: IP.php:52
MediaWiki has optional support for a high distributed memory object caching system For general information on but for a larger site with heavy like it should help lighten the load on the database servers by caching data and objects in Ubuntu and probably other Linux distributions If there s no package available for your you can compile it from epoll rt patch for Linux is current Memcached and libevent are under BSD style licenses The server should run on Linux and other Unix like systems you can run multiple servers on one machine or on multiple machines on a network
Definition: memcached.txt:16
static IPv6ToRawHex($ip)
Given an IPv6 address in octet notation, returns a pure hex string.
Definition: IP.php:438
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition: hooks.txt:177
const RE_IP_PREFIX
Definition: IP.php:32
static isIPv6($ip)
Given a string, determine if it as valid IP in IPv6 only.
Definition: IP.php:90
static isIPAddress($ip)
Determine if a string is as valid IP address or network (CIDR prefix).
Definition: IP.php:79
const IP_ADDRESS_STRING
Definition: IP.php:56
static parseRange6($range)
Given a string range in a number of formats, return the start and end of the range in hexadecimal...
Definition: IP.php:589
static isPublic($ip)
Determine if an IP address really is an IP address, and if it is public, i.e.
Definition: IP.php:376
static combineHostAndPort($host, $port, $defaultPort=false)
Given a host name and a port, combine them into host/port string like you might find in a URL...
Definition: IP.php:303
static isValid($ip)
Validate an IP address.
Definition: IP.php:113
static isIPv4($ip)
Given a string, determine if it as valid IP in IPv4 only.
Definition: IP.php:101
static hexToQuad($ip_hex)
Converts a hexadecimal number to an IPv4 address in quad-dotted notation.
Definition: IP.php:354
static toHex($ip)
Return a zero-padded upper case hexadecimal representation of an IP address.
Definition: IP.php:405
static formatHex($hex)
Convert an IPv4 or IPv6 hexadecimal representation back to readable format.
Definition: IP.php:320
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
static canonicalize($addr)
Convert some unusual representations of IPv4 addresses to their canonical dotted quad representation...
Definition: IP.php:675
static splitHostAndPort($both)
Given a host/port string, like one might find in the host part of a URL per RFC 2732, split the hostname part and the port part and return an array with an element for each.
Definition: IP.php:254
A collection of public static functions to play with IP address and IP blocks.
Definition: IP.php:67
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
static parseRange($range)
Given a string range in a number of formats, return the start and end of the range in hexadecimal...
Definition: IP.php:501
const RE_IP_BYTE
Definition: IP.php:29
static parseCIDR($range)
Convert a network specification in CIDR notation to an integer network and a number of bits...
Definition: IP.php:458
static IPSet $proxyIpSet
Definition: IP.php:69
usually copyright or history_copyright This message must be in HTML not wikitext if the section is included from a template to be included in the link
Definition: hooks.txt:2889
const RE_IP_BLOCK
Definition: IP.php:33
const RE_IPV6_ADD
Definition: IP.php:39
static getSubnet($ip)
Returns the subnet of a given IP.
Definition: IP.php:730
const RE_IP_ADD
Definition: IP.php:30
static isValidBlock($ipblock)
Validate an IP Block (valid address WITH a valid prefix).
Definition: IP.php:126
const RE_IPV6_V4_PREFIX
Definition: IP.php:53
static prettifyIP($ip)
Prettify an IP for display to end users.
Definition: IP.php:201
$matches