Autor Zpráva
matak
Profil
snad je to blbost, ale nějak teď netuším kudy do toho, nápad?

díky
Majkl578
Profil
strlen pocita bajty, ne znaky... (plati pro utf)
matak
Profil
a teď ještě otázka jak to zkrátit, protože substr i mb_substr mi pořád délka nevychází

zkoušel jsem něco jako

mb_substr($omezNa50, 0, 49, "8bit");

ale přesto je délka větší než 50, nechápu to
AM_
Profil
a kolik je přesně délka výsledku? a co v něm stojí? mb_substr může vrátit delší, protože UTF-8 má některé multibyte znaky
Majkl578
Profil
AM_
pokud vim, tak je to naopak, mb_* vraci realny pocet znaku nehlede na multibyte znaky
matak
Profil
kolik je to, to nevím, webová služba co přijímá ty data mi neustále hlásí, že je to delší než 50

mb_ no samozřejmě vrací ale proto jsem tam dal 8bit do encoding, zatím jsem to vyřešil tak, že jsem omezil řetězec na délku 40, takže pro většinu případů se to vejde, ale rozhodně to není dobré řešení
DJ Miky
Profil
mb_substr ti právě vrátí řetězec o 50 znacích, který může být větší než 50 bajtů. Zkrať to normálním substr()em nebo to nech na těch 40, do toho se většina případů vejde.
AM_
Profil
Popř. si můžeš napsat vlastní funkci, která bude multibyte utf8 zkracovat na určitý počet bytů, aniž by ti tam vznikaly nesmyslné znaky (což po rozdělení substr mohou, protože může přetnout multibyte znak).
UTF8 může mít znak 1-5 byty dlouhý. Jak se to pozná? Byty binárně začínající 0 jsou jednobytové znaky(0xxxxxxx). Byty začínající 11 jsou začátkem multi-byte znaku (počet jedniček udává počet bytů) - 1110xxxx je počátek 3byte sekvence, 111110x je počátek 5byte znaků. Každý další byte z multibyte znaku je ve tvaru 10xxxxxx.
Takže nějak takto:
function substr_byte_mb($str, $byte_length){
  $vysledek = ''; // promenna k vraceni hodnoty
  $multibyte = ''; //cache pro multibyte znak
  $i = 0; //iterator
  while (strlen($vysledek)+strlen($multibyte) < $byte_length) {
    if ($str[$i] & 0xc0 == 0xc0){ //11xxxxxx prvnicast multibyte znaku
      $vysledek .= $multibyte; //pripojime pripadny predchazejici mutlibyte znak
      $multibyte = $str[$i]; //ulozime prvni byte do cache
    } elseif ($str[$i] & 0xc0 == 0x80) { //10xxxxxx pokracovani multibyte znaku
       $multibyte .= $str[$i];
    } else { //0xxxxxx jednobyte znak
      $vysledek .= $multibyte.$str[$i]; //pripojime pripadny predchazejici mutlibyte znak a soucasny jednobytovy
      $multibyte = ''; //resetujeme cache
    }
    $i++;
  }
  return $vysledek;
}

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: