Aktueller Standort: Startseite> Neueste Artikel> Praktische Tipps zur Verwendung von Convert_Cyr_String -Funktion, um URL -Parameter zu codieren und zu konvertieren, um verstümmelte Codeprobleme zu vermeiden

Praktische Tipps zur Verwendung von Convert_Cyr_String -Funktion, um URL -Parameter zu codieren und zu konvertieren, um verstümmelte Codeprobleme zu vermeiden

gitbox 2025-09-17

1. Überblick über Problemszenarien und Ideen

Ein typischer Prozess ist: Der Browser- oder Client -URL codiert die Parameter und sendet sie (z. B. ? Name =%E4%F0%E0%E2%E5%F2 ), und der Server erhält eine Byte -Sequenz, die durch das prozentuale Zeichen entkommen ist. Um den richtigen UTF-8-Text wiederherzustellen, sind normalerweise zwei Schritte erforderlich:

  1. Dekodieren Sie die URL -Codierung ( Rawurldecode / Urldecode ), um die ursprüngliche Byte -Sequenz zu erhalten. php.net +1

  2. Konvertieren Sie diese Byte-Sequenz von der korrekten Einzel-Byte-Codierung (z. B. Windows-1251, KOI8-R, CP866 usw.) in UTF-8. Für gemeinsame kyrillische Encodings kann Convert_Cyr_String die Conversions von Zeichensatz vervollständigen, wenn sie von der Server -PHP -Version unterstützt werden. php.net

Hinweis: Convert_cyr_String ist veraltet, da Php 7.4 in PHP 8.0 entfernt wird. MB_CONVERT_ENCODING / ICONV oder UTF-8-Bibliotheken von Drittanbietern sollten zuerst in neuen Umgebungen verwendet werden. Kompatibilität und alternative Lösungen sind unten angegeben. php.net


2. Der von convert_cyr_string (präzise) unterstützte Codierungscode, der unterstützt wird

convert_cyr_string (String $ str, String $ von, String $ bis) verwendet einen Einzelcharakter-Identifikationscode, und die gemeinsame Identifizierung lautet wie folgt:

  • K -KOI8-R

  • W -Windows-1251

  • I -ISO-8859-5

  • A / D -X-CP866 (DOS CP866)

  • M -X-MAC-Cyrillic. php.net


3. Praktische Codevorlage (basierend auf convert_cyr_string )

Hier ist eine praktische PHP-Funktion: Empfangen Sie eine Zeichenfolge, die möglicherweise von URL-codiert sein kann und eine Art kyrillisch codierter Zeichenfolge (aus Abfrage-Zeichenfolge oder Pfadsegment) verwendet, decodiert und konvertiert sie in UTF-8. Hinweis : Bevor Sie die Verwendung verwenden, stellen Sie bitte sicher, dass Ihre PHP -Version immer noch Convert_Cyr_String (Php ≤ 7,3) unterstützt. Wenn Ihre laufende Umgebung Php 8+ ist, gehen Sie bitte zum nächsten Abschnitt, um die Alternative anzuzeigen.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
<span class="hljs-comment">/**
 * Wille URL Parameter(Möglicherweise kodiert für ein Byte -Kyrillisch und entkommen durch prozentuales Zeichen)Standardisiert zu UTF-8 Saite。
 *
 * $rawUrlPart: Original URL Teil(Zum Beispiel $_GET['name'],Oder von PATH_INFO/In der Route erhaltene Fragmente)
 * $sourceCode: Quellcode -Identifizierung,verwenden convert_cyr_string Einzelbuchstabencode('w','k','i','a','d','m')
 *
 * zurückkehren UTF-8 Saite(若无法转换则zurückkehrenOriginal经过 rawurldecode 的Saite)
 */</span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">normalize_cyrillic_url_param</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$rawUrlPart</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$sourceCode</span></span><span> = </span><span><span class="hljs-string">'w'</span></span><span>): </span><span><span class="hljs-title">string</span></span><span> {
    </span><span><span class="hljs-comment">// 先把百分号转义还原fürOriginal字节</span></span><span>
    </span><span><span class="hljs-variable">$decoded</span></span><span> = </span><span><span class="hljs-title function_ invoke__">rawurldecode</span></span><span>(</span><span><span class="hljs-variable">$rawUrlPart</span></span><span>); </span><span><span class="hljs-comment">// Reservierte Bytes,Nicht + Sich dem Raum wenden(Anwendbar auf path segment);Wenn von query Und es gibt +,Verfügbar urldecode()</span></span><span>
    
    </span><span><span class="hljs-comment">// Wenn das System hat convert_cyr_string(Beachten:existieren PHP 8+ ENTFERNT)</span></span><span>
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'convert_cyr_string'</span></span><span>)) {
        </span><span><span class="hljs-comment">// Codieren zuerst ein einzelnes Byte(sourceCode)Konvertieren zu windows-1251('w'),</span></span><span>
        </span><span><span class="hljs-comment">// Dann windows-1251 Wenden Sie sich an UTF-8(verwenden mb_convert_encoding)</span></span><span>
        </span><span><span class="hljs-variable">$asWin1251</span></span><span> = </span><span><span class="hljs-title function_ invoke__">convert_cyr_string</span></span><span>(</span><span><span class="hljs-variable">$decoded</span></span><span>, </span><span><span class="hljs-variable">$sourceCode</span></span><span>, </span><span><span class="hljs-string">'w'</span></span><span>);
        </span><span><span class="hljs-comment">// Wille windows-1251 二进制字节Wenden Sie sich an UTF-8 Saite</span></span><span>
        </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'mb_convert_encoding'</span></span><span>)) {
            </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">mb_convert_encoding</span></span><span>(</span><span><span class="hljs-variable">$asWin1251</span></span><span>, </span><span><span class="hljs-string">'UTF-8'</span></span><span>, </span><span><span class="hljs-string">'Windows-1251'</span></span><span>);
        } </span><span><span class="hljs-keyword">else</span></span><span> {
            </span><span><span class="hljs-comment">// Als Backup,versuchen iconv(wie果Verfügbar)</span></span><span>
            </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'iconv'</span></span><span>)) {
                </span><span><span class="hljs-variable">$utf8</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">iconv</span></span><span>(</span><span><span class="hljs-string">'CP1251'</span></span><span>, </span><span><span class="hljs-string">'UTF-8//IGNORE'</span></span><span>, </span><span><span class="hljs-variable">$asWin1251</span></span><span>);
                </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$utf8</span></span><span> !== </span><span><span class="hljs-literal">false</span></span><span> ? </span><span><span class="hljs-variable">$utf8</span></span><span> : </span><span><span class="hljs-variable">$asWin1251</span></span><span>;
            }
            </span><span><span class="hljs-comment">// 都不Verfügbar时,zurückkehrenOriginal解码Saite</span></span><span>
            </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$asWin1251</span></span><span>;
        }
    }

    </span><span><span class="hljs-comment">// Wenn nicht convert_cyr_string(wie PHP 8+),直接zurückkehrenOriginal解码Saite,让调用方verwenden替代方案</span></span><span>
    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$decoded</span></span><span>;
}
</span></span>

Beispiel Verwendung:

 <span><span><span class="hljs-comment">// Annahmen URL für: /?name=%D0%9C%D0%B8%D1%80</span></span><span>
</span><span><span class="hljs-variable">$raw</span></span><span> = </span><span><span class="hljs-variable">$_GET</span></span><span>[</span><span><span class="hljs-string">'name'</span></span><span>] ?? </span><span><span class="hljs-string">''</span></span><span>;
</span><span><span class="hljs-variable">$name</span></span><span> = </span><span><span class="hljs-title function_ invoke__">normalize_cyrillic_url_param</span></span><span>(</span><span><span class="hljs-variable">$raw</span></span><span>, </span><span><span class="hljs-string">'w'</span></span><span>); </span><span><span class="hljs-comment">// Annahmen客户端以 Windows-1251 schicken</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$name</span></span><span>; </span><span><span class="hljs-comment">// Die Ausgabe ist korrekt UTF-8 Name</span></span><span>
</span></span>

Die Dekodierung von % Eskapen sollte basierend auf Ihrem Parameterquelle RawurLdeCode () (besser für Pfadsegmente geeignet) oder UrldeCode () (wenn + der Speicherplatz in der Abfragezeichenfolge darstellt) ausgewählt werden. Für die Unterschiede und die empfohlene Verwendung der beiden finden Sie in der offiziellen Dokumentation. php.net Guides.codepath.com


4. Php 8+ (oder möchten veraltete Funktionen vermeiden) - Empfohlene Alternativen

Für neue Projekte oder PHP 8+-Umgebungen wird empfohlen, mb_detect_encoding + mb_convert_encoding / iconv zu verwenden oder Clients zu ermöglichen, UTF-8 gleichmäßig (Best Practices) zu verwenden. Beispiel:

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">normalize_cyrillic_url_param_modern</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$rawUrlPart</span></span><span>, </span><span><span class="hljs-keyword">array</span></span><span> </span><span><span class="hljs-variable">$tryEncodings</span></span><span> = [</span><span><span class="hljs-string">'Windows-1251'</span></span><span>,</span><span><span class="hljs-string">'KOI8-R'</span></span><span>,</span><span><span class="hljs-string">'CP866'</span></span><span>]) : </span><span><span class="hljs-title">string</span></span><span> {
    </span><span><span class="hljs-variable">$decoded</span></span><span> = </span><span><span class="hljs-title function_ invoke__">rawurldecode</span></span><span>(</span><span><span class="hljs-variable">$rawUrlPart</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'mb_detect_encoding'</span></span><span>) &amp;&amp; </span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'mb_convert_encoding'</span></span><span>)) {
        </span><span><span class="hljs-comment">// versuchen检测并转换到 UTF-8</span></span><span>
        </span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$tryEncodings</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$enc</span></span><span>) {
            </span><span><span class="hljs-comment">// 检测字节串是否für此编码(Tests sind möglicherweise nicht zuverlässig,故采用versuchen转换后判断)</span></span><span>
            </span><span><span class="hljs-variable">$maybe</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">mb_convert_encoding</span></span><span>(</span><span><span class="hljs-variable">$decoded</span></span><span>, </span><span><span class="hljs-string">'UTF-8'</span></span><span>, </span><span><span class="hljs-variable">$enc</span></span><span>);
            </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$maybe</span></span><span> !== </span><span><span class="hljs-literal">false</span></span><span>) {
                </span><span><span class="hljs-comment">// Einfache Überprüfung:Ähnelt es der ursprünglichen Bytelänge nach der Umwandlung?(NEIN 100% zuverlässig,Aber praktisch)</span></span><span>
                </span><span><span class="hljs-variable">$back</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">mb_convert_encoding</span></span><span>(</span><span><span class="hljs-variable">$maybe</span></span><span>, </span><span><span class="hljs-variable">$enc</span></span><span>, </span><span><span class="hljs-string">'UTF-8'</span></span><span>);
                </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$back</span></span><span> !== </span><span><span class="hljs-literal">false</span></span><span> &amp;&amp; </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$back</span></span><span>) &gt;= </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$decoded</span></span><span>) - </span><span><span class="hljs-number">2</span></span><span>) {
                    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$maybe</span></span><span>;
                }
            }
        }
    }
    </span><span><span class="hljs-comment">// 最后退回Original解码后的Saite(Wahrscheinlich schon UTF-8)</span></span><span>
    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$decoded</span></span><span>;
}
</span></span>

Darüber hinaus können reife Bibliotheken von Drittanbietern (wie Voku/Portable-UTF8 usw.) auch verwendet werden, um komplexe Codierungs-/Normalisierungsprobleme zu behandeln, insbesondere in Produktionssystemen, die eine hohe Robustheit erfordern. Github


5. Liste der praktischen Vorschläge und wichtigen Punkte

  1. Priorität : Die beste Lösung besteht darin, allen Clients UTF-8 einheitlich zu verwenden (erklärt in HTML <meta charset = "UTF-8"> , HTTP-Header, API-Dokumentation). Dies ist die beste Praxis, um verstümmelten Code grundlegend zu vermeiden.

  2. Auswahl der Decodierungsfunktion : Wenn Sie die URL -Codierung empfangen, wird UrldeCode () , wenn es sich um den Abfrageteil ( ? A = B + C ) handelt, + in einen Raum. Wenn es sich um ein Pfadsegment handelt, wird Rawurldecode () bevorzugt. php.net +1

  3. Serverseitige Konvertierung : Wenn nur historische Daten oder Systeme von Drittanbietern verarbeitet werden können, wird die Byte-Sequenz unter Verwendung der oben gezeigten Konvertierungskette ( Rawurldecodeconvert_cyr_string (falls verfügbar) oder mb_convert_encoding / iconv ) in UTF-8 konvertiert. php.net +1

  4. Erkennung und Fallback : Die automatische Erkennungskodierung ist nicht 100% genau. Es wird empfohlen, "Glaubwürdigkeit" -Rents zu den Schlüsselszenarien (z. B. Überprüfung der Konsistenz nach der Erkennung und dann umgekehrter Konvertierung) und den Aufzeichnungsfehlern für manuelle Eingriffe oder das Hinzufügen spezifischer Regeln hinzuzufügen.

  5. Abwertung Hinweis : convert_cyr_string ist in Php 7.4 veraltet und in PHP 8.0 entfernt; Wenn Ihr Code für lange Zeit in einer modernen PHP-Umgebung ausgeführt werden muss, implementieren Sie bitte eine kompatible Alternative ( MB_CONVERT_ENCODING / ICONV / INTER-PARTY-Bibliothek). php.net


6. Schnellvergleichsbeispiel (beide Enden kompatibel)

Szenario A: Der Legacy-Client sendet Parameter (Abfrage) mit KOI8-R, und der Server hofft, UTF-8 zu erhalten:

 <span><span><span class="hljs-variable">$raw</span></span><span> = </span><span><span class="hljs-variable">$_GET</span></span><span>[</span><span><span class="hljs-string">'q'</span></span><span>];                </span><span><span class="hljs-comment">// Original %xx Saite</span></span><span>
</span><span><span class="hljs-variable">$bytes</span></span><span> = </span><span><span class="hljs-title function_ invoke__">rawurldecode</span></span><span>(</span><span><span class="hljs-variable">$raw</span></span><span>);      </span><span><span class="hljs-comment">// Holen Sie sich binäre Bytes</span></span><span>
</span><span><span class="hljs-comment">// 若Verfügbar convert_cyr_string:</span></span><span>
</span><span><span class="hljs-variable">$win</span></span><span> = </span><span><span class="hljs-title function_ invoke__">convert_cyr_string</span></span><span>(</span><span><span class="hljs-variable">$bytes</span></span><span>, </span><span><span class="hljs-string">'k'</span></span><span>, </span><span><span class="hljs-string">'w'</span></span><span>); </span><span><span class="hljs-comment">// koi8-r -&gt; windows-1251</span></span><span>
</span><span><span class="hljs-variable">$utf8</span></span><span> = </span><span><span class="hljs-title function_ invoke__">mb_convert_encoding</span></span><span>(</span><span><span class="hljs-variable">$win</span></span><span>, </span><span><span class="hljs-string">'UTF-8'</span></span><span>, </span><span><span class="hljs-string">'Windows-1251'</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$utf8</span></span><span>;
</span></span>

Szenario B: Php 8+ Umgebung, versuchen Sie es mit automatischer Konvertierung mit modernen Methoden:

 <span><span><span class="hljs-variable">$raw</span></span><span> = </span><span><span class="hljs-variable">$_GET</span></span><span>[</span><span><span class="hljs-string">'q'</span></span><span>];
</span><span><span class="hljs-variable">$bytes</span></span><span> = </span><span><span class="hljs-title function_ invoke__">rawurldecode</span></span><span>(</span><span><span class="hljs-variable">$raw</span></span><span>);
</span><span><span class="hljs-variable">$utf8</span></span><span> = </span><span><span class="hljs-title function_ invoke__">normalize_cyrillic_url_param_modern</span></span><span>(</span><span><span class="hljs-variable">$raw</span></span><span>, [</span><span><span class="hljs-string">'Windows-1251'</span></span><span>,</span><span><span class="hljs-string">'KOI8-R'</span></span><span>,</span><span><span class="hljs-string">'CP866'</span></span><span>]);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$utf8</span></span><span>;
</span></span>

7. Schlussfolgerung (Überprüfung der wichtigsten Punkte)

  • convert_cyr_string war einst eine bequeme Funktion, um den Austausch zwischen kyrillischen Single-Byte-Codierungen zu verarbeiten, und die unterstützten Codes umfassen K, W, I, A, D, M. Diese Funktion ist jedoch in PHP 7.4 veraltet und in PHP 8.0 entfernt. Es wird empfohlen, dass neue Projekte stattdessen Bibliotheken von mb_convert_encoding / iconv oder Drittanbietern verwenden. php.net

  • Angesichts des Problems mit verstümmelten URL-Parametern ist der Schlüssel: Zuerst korrekt das prozentuale Zeichen ( Rawurldecode / Urldecode ) und dann die Byte-Sequenz basierend auf der tatsächlichen Quellcodierung in UTF-8 konvertieren. Achten Sie bei der Auswahl von Decodierungsfunktionen für Pfad und Abfrage auf die Unterschiede in den Umgangsräumen ( + ) zwischen beiden. php.net +1

  • Die sicherste langfristige Strategie besteht darin, UTF-8 auf einheitliche Weise zu verwenden und sich eindeutig auf die Codierungsspezifikationen in Schnittstellendokumenten und Client-Implementierungen zu einigen. Wenn historische oder Drittanbieter Daten erforderlich sind, wird die obige Konversionskette übernommen und der Erkennungs- und Fallback-Mechanismus hinzugefügt, um Robustheit zu gewährleisten. Github php.net

  • Verwandte Tags:

    URL