wahsaga: mbstring-Funktionen/ UTF-8 in PHP

'nabend,

hat hier jemand erfahrung mit den mbstring-funktionen von PHP?

mich würde folgendes interessieren:

1. zum "Function Overloading Feature", mit dem man einige der nicht multi-byte-fähigen (string-)funktionen von PHP mit deren mbstring-pendants "überlagern" kann, steht im manual:

"It is not recommended to use the function overloading option in the per-directory context, because it's not confirmed yet to be stable enough in a production environment and may lead to undefined behaviour."

ist dem wirklich (noch) so? d.h., fahre ich besser, wenn ich an allen stellen im script wirklich explizit die mbstring_funktionen statt der "normalen" verwende - oder ist diese option inzwischen "stable enough", dass man sie entsprechend setzen und dann im script weiterhin die "normalen" funktionsnamen stehen lassen könnte?

2. was ist mit den string-funktionen, die unter an dieser stelle _nicht_ genannt werden, wie beispielsweise trim() oder auch preg_replace() - sind die "von natur aus" multi-byte-fähig, oder muss/sollte ich hier mit komplikationen rechnen?

wäre nett, wenn mich jemand an seinen erfahrungen diesbezüglich teilhaben lassen könnte.

gruß,
wahsaga

--
"Look, that's why there's rules, understand? So that you _think_ before you break 'em."
  1. 你好 wahsaga,

    [...]
    2. was ist mit den string-funktionen, die unter an dieser stelle
    _nicht_ genannt werden, wie beispielsweise trim() oder auch
    preg_replace() - sind die "von natur aus" multi-byte-fähig, oder
    muss/sollte ich hier mit komplikationen rechnen?

    Von trim() habe ich keine Ahnung, aber die manpage zur libpcre, die auch von
    PHP benutzt wird, sagt in pcrecompat:

    1. PCRE does not have full UTF-8 support. Details of what it does have are
    given in the section on UTF-8 support  in  the  main  pcre page.

    Weiter steht da:

    UTF-8 SUPPORT

    Starting  at  release 3.3, PCRE has had some support for character strings encoded in the UTF-8 format. For release 4.0 this has been
           greatly extended to cover most common requirements.

    In order process UTF-8 strings, you must build PCRE to include UTF-8 support in the code, and, in addition, you must  call  pcre_com-
           pile()  with  the  PCRE_UTF8  option flag. When you do this, both the pattern and any subject strings that are matched against it are
           treated as UTF-8 strings instead of just strings of bytes.

    If you compile PCRE with UTF-8 support, but do not use it at run time, the library will be a bit bigger, but the additional run  time
           overhead is limited to testing the PCRE_UTF8 flag in several places, so should not be very large.

    The following comments apply when PCRE is running in UTF-8 mode:

    1.  When  you  set  the PCRE_UTF8 flag, the strings passed as patterns and subjects are checked for validity on entry to the relevant
           functions. If an invalid UTF-8 string is passed, an error return is given. In some situations, you may already know that your strings
           are valid, and therefore want to skip these checks in order to improve performance. If you set the PCRE_NO_UTF8_CHECK flag at compile
           time or at run time, PCRE assumes that the pattern or subject it is given (respectively) contains only valid  UTF-8  codes.  In  this
           case,  it  does not diagnose an invalid UTF-8 string. If you pass an invalid UTF-8 string to PCRE when PCRE_NO_UTF8_CHECK is set, the
           results are undefined. Your program may crash.

    2. In a pattern, the escape sequence \x{...}, where the contents of the braces is a string of hexadecimal digits, is interpreted as a
           UTF-8  character whose code number is the given hexadecimal number, for example: \x{1234}. If a non-hexadecimal digit appears between
           the braces, the item is not recognized.  This escape sequence can be used either as a literal, or within a character class.

    3. The original hexadecimal escape sequence, \xhh, matches a two-byte UTF-8 character if the value is greater than 127.

    4. Repeat quantifiers apply to complete UTF-8 characters, not to individual bytes, for example: \x{100}{3}.

    5. The dot metacharacter matches one UTF-8 character instead of a single byte.

    6. The escape sequence \C can be used to match a single byte in UTF-8 mode, but its use can lead to some strange effects.

    7. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly test characters of any code value, but the characters that PCRE
           recognizes as digits, spaces, or word characters remain the same set as before, all with values less than 256.

    8.  Case-insensitive  matching  applies only to characters whose values are less than 256. PCRE does not support the notion of "case"
           for higher-valued characters.

    9. PCRE does not support the use of Unicode tables and properties or the Perl escapes \p, \P, and \X.

    Du musst also deine preg_*-Pattern mit dem u-Flag erweitern
    (preg_match('/.../u',$txt)) und die oben genannten Hinweise beachten.

    再见,
     CK

    --
    1 + 1 = 3 für gosse Werte von 1.
    http://wwwtech.de/
  2. 你好 wahsaga,

    1. was ist mit den string-funktionen, die unter an dieser stelle
      _nicht_ genannt werden, wie beispielsweise trim() [...]

    Ich habe mir jetzt mal den Sourcecode von trim() angesehen. Diese Funktion
    ist _nicht_ multibyte-faehig, sie entfernt nur \x20\n\r\t\v\0 links und/oder
    rechts vom String. Es werden keinerlei Unicode-Whitespaces entfernt.
    Inwieweit diese Bytemuster Innerhalb von UTF-32- oder UTF-16-Strings
    auftreten koennen, kann ich dir nicht sagen, in UTF-8 ist das insofern
    nicht von belang, als das keine Zeichen “kaputt” gemacht werden (weil
    saemtliche zeichen, die entfernt werden, unterhalb von 127 liegen -- und
    in diesem Teil ist UTF-8 mit ASCII gleichzusetzen).

    再见,
     CK

    --
    89,7% aller Statistiken sind frei erfunden!
    http://wwwtech.de/
    1. 'nabend Christian,

      danke für deine ausführungen.

      Inwieweit diese Bytemuster Innerhalb von UTF-32- oder UTF-16-Strings
      auftreten koennen, kann ich dir nicht sagen, in UTF-8 ist das insofern
      nicht von belang, als das keine Zeichen “kaputt” gemacht werden (weil
      saemtliche zeichen, die entfernt werden, unterhalb von 127 liegen -- und
      in diesem Teil ist UTF-8 mit ASCII gleichzusetzen).

      d.h., trim() ist "sicher", so lange ich nur utf-8 verwende, OK.
      hatte mir als alternative überlegt, dann stattdessen ebenfalls preg_replace zu nutzen, und whitespace (über \s) am stringanfang/-ende durch leerstring zu ersetzen.

      gruß,
      wahsaga

      --
      "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
      1. 你好 wahsaga,

        Inwieweit diese Bytemuster Innerhalb von UTF-32- oder UTF-16-Strings
        auftreten koennen, kann ich dir nicht sagen, in UTF-8 ist das insofern
        nicht von belang, als das keine Zeichen “kaputt” gemacht werden (weil
        saemtliche zeichen, die entfernt werden, unterhalb von 127 liegen -- und
        in diesem Teil ist UTF-8 mit ASCII gleichzusetzen).

        d.h., trim() ist "sicher", so lange ich nur utf-8 verwende, OK.

        Wenn du keinen Wert darauf legst, dass Unicode-Whitespaces entfernt
        werden: ja.

        hatte mir als alternative überlegt, dann stattdessen ebenfalls
        preg_replace zu nutzen, und whitespace (über \s) am stringanfang/-ende
        durch leerstring zu ersetzen.

        In den Anmerkungen von libpcre steht, dass \s nur auf die Whitespaces <
        256 zutrifft, also auch _nicht_ auf Unicode-Whitespaces.

        再见,
         CK

        --
        Der Mund ist das Portal zum Unglück.
        http://wwwtech.de/
        1. hi,

          Wenn du keinen Wert darauf legst, dass Unicode-Whitespaces entfernt
          werden: ja.
          ...
          In den Anmerkungen von libpcre steht, dass \s nur auf die Whitespaces <
          256 zutrifft, also auch _nicht_ auf Unicode-Whitespaces.

          ähm ... was es in unicode denn noch für whitespaces > 255 gibt, ist mir im moment noch gar nicht bewusst :-)

          gruß,
          wahsaga

          --
          "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
          1. 你好 wahsaga,

            Wenn du keinen Wert darauf legst, dass Unicode-Whitespaces entfernt
            werden: ja.
            ...
            In den Anmerkungen von libpcre steht, dass \s nur auf die Whitespaces <
            256 zutrifft, also auch _nicht_ auf Unicode-Whitespaces.

            ähm ... was es in unicode denn noch für whitespaces > 255 gibt, ist mir
            im moment noch gar nicht bewusst :-)

            Molily hatte netterweise mal eine Liste gemacht und mir zukommen lassen:
            0x20, 0xA0, 0x2000 - 0x200B und 0x2028 - x202F sind Leerzeichen.

            再见,
             CK

            --
            Wenn du gehst, gehe. Wenn du sitzt, sitze. Und vor allem: schwanke nicht!
            http://wwwtech.de/
            1. Hallo,

              ähm ... was es in unicode denn noch für whitespaces > 255 gibt, ist mir im moment noch gar nicht bewusst :-)

              Molily hatte netterweise mal eine Liste gemacht und mir zukommen lassen:
              0x20, 0xA0, 0x2000 - 0x200B und 0x2028 - x202F sind Leerzeichen.

              Strenggenommen sind nur U+2000 bis U+200B Leerzeichen im eigentlichen Sinne, U+2028 bis U+202F sind »Formatting characters«. Wenn man die wegschneidet, sollte man z.B. auch U+200C bis U+200F entfernen. Formatting characters sind (meiner Vermutung nach) nicht notwendigerweise irrelevante Zeichen, wenn sie am Anfang bzw. Ende eines Strings stehen. Vielleicht gibt es Fälle, in denen ein solches Zeichen durchaus seinen Sinn an diesen Stellen hat, dazu kenne ich die vielen von Unicode repräsentierten Schriftsysteme nicht.
              Darüber hinaus gibt es wahrscheinlich unzählige weitere Steuerzeichen, die man für gewöhnlich nicht gerne im String haben will. Hängt letztlich wohl davon ab, welche Aufgabe das trim() erfüllen soll.

              Mathias

  3. Hallo!

    wäre nett, wenn mich jemand an seinen erfahrungen diesbezüglich teilhaben lassen könnte.

    Eigene Erfahrungen habe ich auf deisem Feld leider noch nicht, irgendwie ist mir das ganze Thema noch etwas suspekt.

    Ne kleine Diskussion zur PHP 5.1 Roadmap:
    http://www.zend.com/lists/php-dev/200410/msg00344.html
    (wenn ich mich richtig erinnere wurde verbesserter, evtl. nativer Unicode-Support auf die 5.2 verschoben ;-))

    Evtl. kannst Du auch mit http://de3.php.net/iconv arbeiten?

    Noch eine Diskussion zum Thema mb* Funktionen:
    http://www.zend.com/lists/php-dev/200408/threads.html#00661

    Und noch eine kleine Präsentation:
    http://talks.php.net/show/wereldveroverend-ffm2004/

    Grüße
    Andreas

    --
    SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/