Многобайтовая безопасная функция wordwrap () для UTF-8

Число в типе данных MySQL INT(n) не указывает, сколько места зарезервировано, это ширина дисплея только для форматирования. Таким образом, INT(10) - это то же самое, что и обычный INTEGER, то есть 32-разрядное число со знаком.

Так что это, безусловно, подходящий тип данных для 32-битной метки времени Unix. Но если вам нужны 64-битные метки времени, этого будет недостаточно; вам придется использовать BIGINT.

14
задан philfreo 29 September 2010 в 19:41
поделиться

1 ответ

Пользовательские границы слова

текст Unicode имеют намного более потенциальные границы слова, чем 8-разрядная кодировка, включая 17 разделителей пространства , и полная запятая ширины. Это решение позволяет Вам настраивать список границ слова для Вашего приложения.

Лучшая производительность

Вы когда-либо сравнивали mb_* семейство созданного-ins PHP? Они не масштабируются хорошо вообще. При помощи пользовательского nextCharUtf8(), мы можем сделать то же задание, но порядки величины быстрее, особенно на больших строках.

<?php

function wordWrapUtf8(
  string $phrase,
  int $width = 75,
  string $break = "\n",
  bool $cut = false,
  array $seps = [' ', "\n", "\t", ',']
): string
{
  $chunks = [];
  $chunk = '';
  $len = 0;
  $pointer = 0;
  while (!is_null($char = nextCharUtf8($phrase, $pointer))) {
    $chunk .= $char;
    $len++;
    if (in_array($char, $seps, true) || ($cut && $len === $width)) {
      $chunks[] = [$len, $chunk];
      $len = 0;
      $chunk = '';
    }
  }
  if ($chunk) {
    $chunks[] = [$len, $chunk];
  }
  $line = '';
  $lines = [];
  $lineLen = 0;
  foreach ($chunks as [$len, $chunk]) {
    if ($lineLen + $len > $width) {
      if ($line) {
        $lines[] = $line;
        $lineLen = 0;
        $line = '';
      }
    }
    $line .= $chunk;
    $lineLen += $len;
  }
  if ($line) {
    $lines[] = $line;
  }
  return implode($break, $lines);
}

function nextCharUtf8(&$string, &$pointer)
{
  // EOF
  if (!isset($string[$pointer])) {
    return null;
  }

  // Get the byte value at the pointer
  $char = ord($string[$pointer]);

  // ASCII
  if ($char < 128) {
    return $string[$pointer++];
  }

  // UTF-8
  if ($char < 224) {
    $bytes = 2;
  } elseif ($char < 240) {
    $bytes = 3;
  } elseif ($char < 248) {
    $bytes = 4;
  } elseif ($char == 252) {
    $bytes = 5;
  } else {
    $bytes = 6;
  }

  // Get full multibyte char
  $str = substr($string, $pointer, $bytes);

  // Increment pointer according to length of char
  $pointer += $bytes;

  // Return mb char
  return $str;
}
1
ответ дан 1 December 2019 в 09:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: