Kalle_B: Schon wieder Probleme mit Umlauten (UTF-8)

Hallöle,

bin dabei, Einträge in der Datenbank nach Suchworten auszuwerten:

http://was-vermietet-wer.de/index.php?zp=p121

Kein Problem, wenn ich als Suchwort ein e eingebe. Aber bei einem ü zickt PHP rum mit Fehlermeldungen:

Warning: mb_strpos() [function.mb-strpos]: Unknown encoding or conversion error. in /homepages/45/d283598515/htdocs/100/p121.php on line 309

Line 309:

      $start_pos = mb_strpos ( 'x'.mb_strtolower($row['firma1']), mb_strtolower($arr_in['suchworte']), 0, 'UTF-8' );  

In $arr_in['suchworte'] steckt das ü.

Die Seite mit dem einzugebenden Suchwort hat den header
header('content-type: text/html; charset=utf-8');
und zusätzlich
<form accept-charset="utf-8" name=form_p100_suche action='/index.php' method='post'>

Was will PHP denn noch?

LG Kalle

  1. Hallo,

    var_dump(mb_strpos ( "abcü","ü",0,"latin1"));

    geht.

    var_dump(mb_strpos ( "abcü","ü",0,"utf-8"));

    nicht.

    var_dump(mb_strpos ( "abcü","ü",0,"iso-8859"));

    auch nicht.

    Also stimmt vielleicht das, was php sagt: "unbekanntes encoding". Wozu überhaupt das encoding festlegen? PHP bringt doch utf-8 von Hause aus mit, oder? Was du nachher dem HTML-Dokument sagst, spielt dabei wohl kaum eine Rolle.

    Gruß

    jobo

    1. habe nicht verstanden, was du sagen willst.

      1. Hallo,

        habe nicht verstanden, was du sagen willst.

        Naja, evtl. stimmt der Parameter an der Stelle 4 nicht. "latin1" geht ja, "utf-8" aber nicht, "iso-8859-1" aber auch. Meiner Einschätzung nach machst Du vier Sachen gleichzeitig. Ich hatte jetzt nur die Funktion mb_strpos() isoliert.

        Gruß

        jobo

  2. Moin!

    Warning: mb_strpos() [function.mb-strpos]: Unknown encoding or conversion error. in /homepages/45/d283598515/htdocs/100/p121.php on line 309

    Line 309:

    $start_pos = mb_strpos ( 'x'.mb_strtolower($row['firma1']), mb_strtolower($arr_in['suchworte']), 0, 'UTF-8' );

    
    >   
    > In $arr\_in['suchworte'] steckt das ü.  
      
    Alle mb-Funktionen haben einen Parameter, der das anzunehmende Encoding angibt. Wenn man den nicht jedesmal explizit angibt, wäre mindestens das [mb_internal_encoding](http://de.php.net/manual/de/function.mb-internal-encoding.php) zu definieren. Ansonsten bauen deine mb\_strtolower() aus dem "ü" nämlich ein kleingemachtes ISO-8859-1-Ersatzzeichen, weil ISO-8859-1 evtl. Standardencoding ist.  
      
     - Sven Rautenberg
    
    1. Hallo, Sven,

      Alle mb-Funktionen haben einen Parameter, der das anzunehmende Encoding angibt. Wenn man den nicht jedesmal explizit angibt, wäre mindestens das mb_internal_encoding zu definieren.

      Okay, habe ich eingebaut:

      @mysql_query( "SET NAMES 'utf8'", $conn_id );  
      header('content-type: text/html; charset=utf-8');  
      mb_internal_encoding("UTF-8");  
      
      

      Ansonsten bauen deine mb_strtolower() aus dem "ü" nämlich ein kleingemachtes ISO-8859-1-Ersatzzeichen, weil ISO-8859-1 evtl. Standardencoding ist.

      Nun gibt es zwar keine Fehlermeldung mehr, aber es werden Treffer gedunden, die gar kei ü beinhalten.

      Kalle

      1. Nun gibt es zwar keine Fehlermeldung mehr, aber es werden Treffer gefunden, die gar kein ü beinhalten.

        Dazu das SQL:

        SELECT  
         SQL_CALC_FOUND_ROWS  
         adr1.*  
        FROM      bia_adressen adr1  
        WHERE     adr1.owner_id  = 1  
        AND       adr1.loe_kz    = 0  
        AND       adr1.intern_kz = 0  
        AND     (  adr1.hauptbranche LIKE '%ü%'  
                OR adr1.firma1 LIKE '%ü%'  
                OR adr1.firma2 LIKE '%ü%'  
                OR adr1.suchworte LIKE '%ü%'  
                )
        

        Wieso gibt's da unerklärliche Treffer?

        Kalle

        1. Moin!

          Nun gibt es zwar keine Fehlermeldung mehr, aber es werden Treffer gefunden, die gar kein ü beinhalten.

          Dazu das SQL:

          SELECT

          SQL_CALC_FOUND_ROWS
          adr1.*
          FROM      bia_adressen adr1
          WHERE     adr1.owner_id  = 1
          AND       adr1.loe_kz    = 0
          AND       adr1.intern_kz = 0
          AND     (  adr1.hauptbranche LIKE '%ü%'
                  OR adr1.firma1 LIKE '%ü%'
                  OR adr1.firma2 LIKE '%ü%'
                  OR adr1.suchworte LIKE '%ü%'
                  )

          
          >   
          > Wieso gibt's da unerklärliche Treffer?  
            
          Die Kollation utf8\_general\_ci bzw. utf8\_unicode\_ci definieren eine Sortier- und Äquivalenzliste der Zeichen, die auch für die deutsche Sprache gilt. Und die definiert u.a.: ä = a, ö = o, ü = u. Findest du also zufällig Einträge, die ein u enthalten?  
            
           - Sven Rautenberg
          
    2. Hallo Sven,

      Alle mb-Funktionen haben einen Parameter, der das anzunehmende Encoding angibt. Wenn man den nicht jedesmal explizit angibt, wäre mindestens das mb_internal_encoding zu definieren. Ansonsten bauen deine mb_strtolower() aus dem "ü" nämlich ein kleingemachtes ISO-8859-1-Ersatzzeichen, weil ISO-8859-1 evtl. Standardencoding ist.

      Ich hatte vor einiger Zeit auch schon mal zu einem ähnlichen Thema gefragt:
      Worauf bezieht sich denn das "Standardencoding"?
      Auf PHP oder auf das Betriebssystem.
      Selbst wenn ich den Apache, PHP und alle meine Header bzw. PHP Seiten in UTF8 ausliefere, bringt mit ein echo mb_internal_encoding() immer ISO-8859-1.

      vielen Dank und viele Grüße
      hawk

      1. Moin!

        Alle mb-Funktionen haben einen Parameter, der das anzunehmende Encoding angibt. Wenn man den nicht jedesmal explizit angibt, wäre mindestens das mb_internal_encoding zu definieren. Ansonsten bauen deine mb_strtolower() aus dem "ü" nämlich ein kleingemachtes ISO-8859-1-Ersatzzeichen, weil ISO-8859-1 evtl. Standardencoding ist.

        Ich hatte vor einiger Zeit auch schon mal zu einem ähnlichen Thema gefragt:
        Worauf bezieht sich denn das "Standardencoding"?
        Auf PHP oder auf das Betriebssystem.

        Auf die PHP.INI.

        Selbst wenn ich den Apache, PHP und alle meine Header bzw. PHP Seiten in UTF8 ausliefere, bringt mit ein echo mb_internal_encoding() immer ISO-8859-1.

        Die PHP.INI erlaubt diverse Settings für das mbstring-Modul. Etliche davon beschäftigen sich mit der automatischen Erkennung des Encodings. Das mag in manchen speziellen Situationen hilfreich sein, aber allgemein sollte man a) alle seine verwendeten Encodings kennen und deshalb b) immer explizit angeben. Im Idealfall also immer explizit UTF-8 verwenden, und nur an bestimmten Schnittstellen zu ISO-8859-1/Win-1252/ISO-8859-15, deren Encoding man nicht ändern kann, direkt eine Konvertierung einbauen.

        - Sven Rautenberg

        1. Hallo Sven,

          Auf die PHP.INI.

          Das hatte ich schon vermutet bzw. schon mal wo so gelesen.
          NUR: ich habe in meiner PHP.ini alles auf UTF8

          [mbstring]
          mbstring.language = utf-8
          mbstring.internal_encoding = utf-8
          mbstring.http_input = utf-8
          mbstring.http_output = utf-8

          Trotzdem kommt bei mit
          ISO-8859-1

          als Ausgabe.
          Daher war ich verunsichert.

          vielen Dank und viele Grüße
          hawk

          1. Moin!

            Auf die PHP.INI.

            Das hatte ich schon vermutet bzw. schon mal wo so gelesen.
            NUR: ich habe in meiner PHP.ini alles auf UTF8

            [mbstring]
            mbstring.language = utf-8
            mbstring.internal_encoding = utf-8
            mbstring.http_input = utf-8
            mbstring.http_output = utf-8

            Trotzdem kommt bei mit
            ISO-8859-1

            als Ausgabe.
            Daher war ich verunsichert.

            Tja, dann ist da irgendwas nicht so, wie a) es sein sollte oder b) ich es vermute. :)

            Server neu gestartet? Was sagt phpinfo()?

            - Sven Rautenberg

            1. Hallo Sven,

              ja den Apache hatte ich bereits neu gestartet.

              PHP info bringt bei mbstring auch UTF8:

              mbstring
              Multibyte Support enabled
              Multibyte string engine libmbfl
              Multibyte (japanese) regex support enabled
              Multibyte regex (oniguruma) version 4.4.4
              Multibyte regex (oniguruma) backtrack check On

              mbstring extension makes use of "streamable kanji code filter and converter", which is distributed under the GNU Lesser General Public License version 2.1.

              Directive Local Value Master Value
              mbstring.detect_order no value no value
              mbstring.encoding_translation Off Off
              mbstring.func_overload 0 0
              mbstring.http_input utf-8 utf-8
              mbstring.http_output utf-8 utf-8
              mbstring.internal_encoding utf-8 utf-8
              mbstring.language neutral neutral
              mbstring.strict_detection Off Off
              mbstring.substitute_character no value no value

              vielen Dank und viele Grüße
              hawk

              1. Moin!

                ja den Apache hatte ich bereits neu gestartet.

                PHP info bringt bei mbstring auch UTF8:

                Tja, hm. Ich bin überfragt. :)

                Allerdings würde ich als grundsätzliche Taktik die gewollten Settings immer explizit in meine Skripte einprogrammieren, und mich nicht auf irgendwelche Einstellungen der php.ini verlassen. Das geht natürlich nur bei den Settings, die man auch im Skript noch manipulieren kann, also nicht z.B. bei magic_quotes_gpc etc. Damit vermeidet man, dass die Lauffähigkeit des Skripts von irgendwelchen Settings abhängig ist, die man eventuell nicht beeinflussen kann, oder die zu verändern man vergessen hat.

                Es ist überhaupt eine recht gute Idee, an den Standardeinstellungen von PHP möglichst wenig zu verändern, dann hat man am wenigsten Kompatibilitätsprobleme.

                Bringt dich das jetzt weiter?

                - Sven Rautenberg

                1. Hallo Sven,

                  Bringt dich das jetzt weiter?

                  ja schon, danke sehr.

                  ich mache es sowieso wie du empfiehlst, nämlich die Code Angaben gleich in der Funktion anzugeben.
                  also etwa, $filename_ges_utf8 = mb_strlen($f, 'utf8');

                  Ich hatte nur im Zuge meiner Umstellung auf UTF8 einiges mit den MB Funktionen ausprobiert und da ist mir halt diese Ausgabe mit ISO-8859-1 etwas seltsam vorgekommen.

                  vielen Dank und viele Grüße
                  hawk