Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Mbstring.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 19.30 KiB


001  <?php
002   
003  /*
004   * Copyright (C) 2016 Nicolas Grekas - p@tchwork.com
005   *
006   * This library is free software; you can redistribute it and/or modify it
007   * under the terms of the (at your option):
008   * Apache License v2.0 (http://apache.org/licenses/LICENSE-2.0.txt), or
009   * GNU General Public License v2.0 (http://gnu.org/licenses/gpl-2.0.txt).
010   */
011   
012  namespace Patchwork\PHP\Shim;
013   
014  /**
015   * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
016   *
017   * Implemented:
018   * - mb_convert_encoding     - Convert character encoding
019   * - mb_convert_variables    - Convert character code in variable(s)
020   * - mb_decode_mimeheader    - Decode string in MIME header field
021   * - mb_encode_mimeheader    - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
022   * - mb_convert_case         - Perform case folding on a string
023   * - mb_get_info             - Get internal settings of mbstring
024   * - mb_http_input           - Detect HTTP input character encoding
025   * - mb_http_output          - Set/Get HTTP output character encoding
026   * - mb_internal_encoding    - Set/Get internal character encoding
027   * - mb_list_encodings       - Returns an array of all supported encodings
028   * - mb_output_handler       - Callback function converts character encoding in output buffer
029   * - mb_strlen               - Get string length
030   * - mb_strpos               - Find position of first occurrence of string in a string
031   * - mb_strrpos              - Find position of last occurrence of a string in a string
032   * - mb_strtolower           - Make a string lowercase
033   * - mb_strtoupper           - Make a string uppercase
034   * - mb_substitute_character - Set/Get substitution character
035   * - mb_substr               - Get part of string
036   * - mb_stripos              - Finds position of first occurrence of a string within another, case insensitive
037   * - mb_stristr              - Finds first occurrence of a string within another, case insensitive
038   * - mb_strrchr              - Finds the last occurrence of a character in a string within another
039   * - mb_strrichr             - Finds the last occurrence of a character in a string within another, case insensitive
040   * - mb_strripos             - Finds position of last occurrence of a string within another, case insensitive
041   * - mb_strstr               - Finds first occurrence of a string within anothers
042   * - mb_strwidth             - Return width of string
043   * - mb_substr_count         - Count the number of substring occurrences
044   *
045   * Not implemented:
046   * - mb_convert_kana         - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
047   * - mb_decode_numericentity - Decode HTML numeric string reference to character
048   * - mb_encode_numericentity - Encode character to HTML numeric string reference
049   * - mb_ereg_*               - Regular expression with multibyte support
050   * - mb_parse_str            - Parse GET/POST/COOKIE data and set global variable
051   * - mb_preferred_mime_name  - Get MIME charset string
052   * - mb_regex_encoding       - Returns current encoding for multibyte regex as string
053   * - mb_regex_set_options    - Set/Get the default options for mbregex functions
054   * - mb_send_mail            - Send encoded mail
055   * - mb_split                - Split multibyte string using regular expression
056   * - mb_strcut               - Get part of string
057   * - mb_strimwidth           - Get truncated string with specified width
058   *
059   * @internal
060   */
061  class Mbstring
062  {
063      const MB_CASE_FOLD = PHP_INT_MAX;
064   
065      private static $encodingList = array('ASCII', 'UTF-8');
066      private static $language = 'neutral';
067      private static $internalEncoding = 'UTF-8';
068      private static $caseFold = array(
069          array('µ','ſ',"\xCD\x85",'ς',"\xCF\x90","\xCF\x91","\xCF\x95","\xCF\x96","\xCF\xB0","\xCF\xB1","\xCF\xB5","\xE1\xBA\x9B","\xE1\xBE\xBE"),
070          array('μ','s','ι',       'σ','β',       'θ',       'φ',       'π',       'κ',       'ρ',       'ε',       "\xE1\xB9\xA1",'ι'),
071      );
072   
073      public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
074      {
075          if (is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
076              $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
077          } else {
078              $fromEncoding = self::getEncoding($fromEncoding);
079          }
080   
081          $toEncoding = self::getEncoding($toEncoding);
082   
083          if ('BASE64' === $fromEncoding) {
084              $s = base64_decode($s);
085              $fromEncoding = $toEncoding;
086          }
087   
088          if ('BASE64' === $toEncoding) {
089              return base64_encode($s);
090          }
091   
092          if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
093              if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
094                  $fromEncoding = 'Windows-1252';
095              }
096              if ('UTF-8' !== $fromEncoding) {
097                  $s = iconv($fromEncoding, 'UTF-8', $s);
098              }
099   
100              return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
101          }
102   
103          if ('HTML-ENTITIES' === $fromEncoding) {
104              $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
105              $fromEncoding = 'UTF-8';
106          }
107   
108          return iconv($fromEncoding, $toEncoding, $s);
109      }
110   
111      public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
112      {
113          $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
114   
115          $ok = true;
116          array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
117              if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
118                  $ok = false;
119              }
120          });
121   
122          return $ok ? $fromEncoding : false;
123      }
124   
125      public static function mb_decode_mimeheader($s)
126      {
127          return iconv_mime_decode($s, 2, self::$internalEncoding);
128      }
129   
130      public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
131      {
132          trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
133      }
134   
135      public static function mb_convert_case($s, $mode, $encoding = null)
136      {
137          if ('' === $s .= '') {
138              return '';
139          }
140   
141          $encoding = self::getEncoding($encoding);
142   
143          if ('UTF-8' === $encoding) {
144              $encoding = null;
145          } else {
146              $s = iconv($encoding, 'UTF-8', $s);
147          }
148   
149          if (MB_CASE_TITLE == $mode) {
150              $s = preg_replace_callback('/\b\p{Ll}/u', array(__CLASS__, 'title_case_upper'), $s);
151              $s = preg_replace_callback('/\B[\p{Lu}\p{Lt}]+/u', array(__CLASS__, 'title_case_lower'), $s);
152          } else {
153              if (MB_CASE_UPPER == $mode) {
154                  static $upper = null;
155                  if (null === $upper) {
156                      $upper = self::getData('upperCase');
157                  }
158                  $map = $upper;
159              } else {
160                  if (self::MB_CASE_FOLD === $mode) {
161                      $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
162                  }
163   
164                  static $lower = null;
165                  if (null === $lower) {
166                      $lower = self::getData('lowerCase');
167                  }
168                  $map = $lower;
169              }
170   
171              static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
172   
173              $i = 0;
174              $len = strlen($s);
175   
176              while ($i < $len) {
177                  $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
178                  $uchr = substr($s, $i, $ulen);
179                  $i += $ulen;
180   
181                  if (isset($map[$uchr])) {
182                      $uchr = $map[$uchr];
183                      $nlen = strlen($uchr);
184   
185                      if ($nlen == $ulen) {
186                          $nlen = $i;
187                          do {
188                              $s[--$nlen] = $uchr[--$ulen];
189                          } while ($ulen);
190                      } else {
191                          $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
192                          $len += $nlen - $ulen;
193                          $i   += $nlen - $ulen;
194                      }
195                  }
196              }
197          }
198   
199          if (null === $encoding) {
200              return $s;
201          }
202   
203          return iconv('UTF-8', $encoding, $s);
204      }
205   
206      public static function mb_internal_encoding($encoding = null)
207      {
208          if (null === $encoding) {
209              return self::$internalEncoding;
210          }
211   
212          $encoding = self::getEncoding($encoding);
213   
214          if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
215              self::$internalEncoding = $encoding;
216   
217              return true;
218          }
219   
220          return false;
221      }
222   
223      public static function mb_language($lang = null)
224      {
225          if (null === $lang) {
226              return self::$language;
227          }
228   
229          switch ($lang = strtolower($lang)) {
230              case 'uni':
231              case 'neutral':
232                  self::$language = $lang;
233   
234                  return true;
235          }
236   
237          return false;
238      }
239   
240      public static function mb_list_encodings()
241      {
242          return array('UTF-8');
243      }
244   
245      public static function mb_encoding_aliases($encoding)
246      {
247          switch (strtoupper($encoding)) {
248              case 'UTF8':
249              case 'UTF-8':
250                  return array('utf8');
251          }
252   
253          return false;
254      }
255   
256      public static function mb_check_encoding($var = null, $encoding = null)
257      {
258          if (null === $encoding) {
259              if (null === $var) {
260                  return false;
261              }
262              $encoding = self::$internalEncoding;
263          }
264   
265          return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
266      }
267   
268      public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
269      {
270          if (null === $encodingList) {
271              $encodingList = self::$encodingList;
272          } else {
273              if (!is_array($encodingList)) {
274                  $encodingList = array_map('trim', explode(',', $encodingList));
275              }
276              $encodingList = array_map('strtoupper', $encodingList);
277          }
278   
279          foreach ($encodingList as $enc) {
280              switch ($enc) {
281                  case 'ASCII':
282                      if (!preg_match('/[\x80-\xFF]/', $str)) {
283                          return $enc;
284                      }
285                      break;
286   
287                  case 'UTF8':
288                  case 'UTF-8':
289                      if (preg_match('//u', $str)) {
290                          return 'UTF-8';
291                      }
292                      break;
293   
294                  default:
295                      if (0 === strncmp($enc, 'ISO-8859-', 9)) {
296                          return $enc;
297                      }
298              }
299          }
300   
301          return false;
302      }
303   
304      public static function mb_detect_order($encodingList = null)
305      {
306          if (null === $encodingList) {
307              return self::$encodingList;
308          }
309   
310          if (!is_array($encodingList)) {
311              $encodingList = array_map('trim', explode(',', $encodingList));
312          }
313          $encodingList = array_map('strtoupper', $encodingList);
314   
315          foreach ($encodingList as $enc) {
316              switch ($enc) {
317                  default:
318                      if (strncmp($enc, 'ISO-8859-', 9)) {
319                          return false;
320                      }
321                  case 'ASCII':
322                  case 'UTF8':
323                  case 'UTF-8':
324              }
325          }
326   
327          self::$encodingList = $encodingList;
328   
329          return true;
330      }
331   
332      public static function mb_strlen($s, $encoding = null)
333      {
334          $encoding = self::getEncoding($encoding);
335   
336          return iconv_strlen($s, $encoding);
337      }
338   
339      public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
340      {
341          $encoding = self::getEncoding($encoding);
342   
343          if ('' === $needle .= '') {
344              trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
345   
346              return false;
347          }
348   
349          return iconv_strpos($haystack, $needle, $offset, $encoding);
350      }
351   
352      public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
353      {
354          $encoding = self::getEncoding($encoding);
355   
356          if ($offset != (int) $offset) {
357              $offset = 0;
358          } elseif ($offset = (int) $offset) {
359              if ($offset < 0) {
360                  $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
361                  $offset = 0;
362              } else {
363                  $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
364              }
365          }
366   
367          $pos = iconv_strrpos($haystack, $needle, $encoding);
368   
369          return false !== $pos ? $offset + $pos : false;
370      }
371   
372      public static function mb_strtolower($s, $encoding = null)
373      {
374          return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
375      }
376   
377      public static function mb_strtoupper($s, $encoding = null)
378      {
379          return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
380      }
381   
382      public static function mb_substitute_character($c = null)
383      {
384          if (0 === strcasecmp($c, 'none')) {
385              return true;
386          }
387   
388          return null !== $c ? false : 'none';
389      }
390   
391      public static function mb_substr($s, $start, $length = null, $encoding = null)
392      {
393          $encoding = self::getEncoding($encoding);
394   
395          if ($start < 0) {
396              $start = iconv_strlen($s, $encoding) + $start;
397              if ($start < 0) {
398                  $start = 0;
399              }
400          }
401   
402          if (null === $length) {
403              $length = 2147483647;
404          } elseif ($length < 0) {
405              $length = iconv_strlen($s, $encoding) + $length - $start;
406              if ($length < 0) {
407                  return '';
408              }
409          }
410   
411          return iconv_substr($s, $start, $length, $encoding).'';
412      }
413   
414      public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
415      {
416          $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
417          $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
418   
419          return self::mb_strpos($haystack, $needle, $offset, $encoding);
420      }
421   
422      public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
423      {
424          $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
425   
426          return self::getSubpart($pos, $part, $haystack, $encoding);
427      }
428   
429      public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
430      {
431          $encoding = self::getEncoding($encoding);
432          $needle = self::mb_substr($needle, 0, 1, $encoding);
433          $pos = iconv_strrpos($haystack, $needle, $encoding);
434   
435          return self::getSubpart($pos, $part, $haystack, $encoding);
436      }
437   
438      public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
439      {
440          $needle = self::mb_substr($needle, 0, 1, $encoding);
441          $pos = self::mb_strripos($haystack, $needle, $encoding);
442   
443          return self::getSubpart($pos, $part, $haystack, $encoding);
444      }
445   
446      public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
447      {
448          $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
449          $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
450   
451          return self::mb_strrpos($haystack, $needle, $offset, $encoding);
452      }
453   
454      public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
455      {
456          $pos = strpos($haystack, $needle);
457          if (false === $pos) {
458              return false;
459          }
460          if ($part) {
461              return substr($haystack, 0, $pos);
462          }
463   
464          return substr($haystack, $pos);
465      }
466   
467      public static function mb_get_info($type = 'all')
468      {
469          $info = array(
470              'internal_encoding' => self::$internalEncoding,
471              'http_output' => 'pass',
472              'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
473              'func_overload' => 0,
474              'func_overload_list' => 'no overload',
475              'mail_charset' => 'UTF-8',
476              'mail_header_encoding' => 'BASE64',
477              'mail_body_encoding' => 'BASE64',
478              'illegal_chars' => 0,
479              'encoding_translation' => 'Off',
480              'language' => self::$language,
481              'detect_order' => self::$encodingList,
482              'substitute_character' => 'none',
483              'strict_detection' => 'Off',
484          );
485   
486          if ('all' === $type) {
487              return $info;
488          }
489          if (isset($info[$type])) {
490              return $info[$type];
491          }
492   
493          return false;
494      }
495   
496      public static function mb_http_input($type = '')
497      {
498          return false;
499      }
500   
501      public static function mb_http_output($encoding = null)
502      {
503          return null !== $encoding ? 'pass' === $encoding : 'pass';
504      }
505   
506      public static function mb_strwidth($s, $encoding = null)
507      {
508          $encoding = self::getEncoding($encoding);
509   
510          if ('UTF-8' !== $encoding) {
511              $s = iconv($encoding, 'UTF-8', $s);
512          }
513   
514          $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
515   
516          return ($wide << 1) + iconv_strlen($s, 'UTF-8');
517      }
518   
519      public static function mb_substr_count($haystack, $needle, $encoding = null)
520      {
521          return substr_count($haystack, $needle);
522      }
523   
524      public static function mb_output_handler($contents, $status)
525      {
526          return $contents;
527      }
528   
529      private static function getSubpart($pos, $part, $haystack, $encoding)
530      {
531          if (false === $pos) {
532              return false;
533          }
534          if ($part) {
535              return self::mb_substr($haystack, 0, $pos, $encoding);
536          }
537   
538          return self::mb_substr($haystack, $pos, null, $encoding);
539      }
540   
541      private static function html_encoding_callback($m)
542      {
543          $i = 1;
544          $entities = '';
545          $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
546   
547          while (isset($m[$i])) {
548              if (0x80 > $m[$i]) {
549                  $entities .= chr($m[$i++]);
550                  continue;
551              }
552              if (0xF0 <= $m[$i]) {
553                  $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
554              } elseif (0xE0 <= $m[$i]) {
555                  $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
556              } else {
557                  $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
558              }
559   
560              $entities .= '&#'.$c.';';
561          }
562   
563          return $entities;
564      }
565   
566      private static function title_case_lower($s)
567      {
568          return self::mb_convert_case($s[0], MB_CASE_LOWER, 'UTF-8');
569      }
570   
571      private static function title_case_upper($s)
572      {
573          return self::mb_convert_case($s[0], MB_CASE_UPPER, 'UTF-8');
574      }
575   
576      private static function getData($file)
577      {
578          if (file_exists($file = __DIR__.'/unidata/'.$file.'.ser')) {
579              return unserialize(file_get_contents($file));
580          }
581   
582          return false;
583      }
584   
585      private static function getEncoding($encoding)
586      {
587          if (null === $encoding) {
588              return self::$internalEncoding;
589          }
590   
591          $encoding = strtoupper($encoding);
592   
593          if ('8BIT' === $encoding || 'BINARY' === $encoding) {
594              return 'CP850';
595          }
596          if ('UTF8' === $encoding) {
597              return 'UTF-8';
598          }
599   
600          return $encoding;
601      }
602  }
603