MySQL kıvırcık (akıllı) tırnak boğuyor

2 Cevap php

Ben bir formdan bir veritabanına bazı verileri takacağım. I addslashes (ayrıca aynı sonucu ile {[) (1]} denedim) metni kaçmak için kullanıyorum.

Düzenli tırnak kaçtı, ancak diğer bazı tırnak değildir. Örneğin, dize:

Homeros'un kan Moe yeni bira gizli madde olur.

dönüştürülür için:

Homer \ 'ın kan Moe yeni bira gizli madde olur.

Ben kıvırcık alıntı çıkmamış önemli olacağını sanmıyordum, ama sadece bu metin veritabanına eklenir:

Homeros'un kan Moe gizli madde olur

Yani PHP kıvırcık alıntı gayet iyi olduğunu düşünüyor, ancak MySQL dize kaybediyor. MySQL rağmen herhangi bir hata vermiyor.

2 Cevap

Ben veritabanı düzeyinde kullanılan Web arayüzü ve kullanılan karakter kodlaması arasında bir uyumsuzluk olmazdı. Web arayüzü, örneğin, UTF-8 kullanır ve veritabanı varsayılan MySQL kodlamayı kullanarak ise latin1, daha sonra DEFAULT CHARSET=utf8 ile tablo kurmak gerekir.

Bu arada, mysql_real_escape_string() veya mysqli kullanmalısınız. addslashes() SQL enjeksiyon karşı NOT yeterli korunmasıdır.

'Moe adlı bu dize latin1 kodlanmış ancak mysql sunucu utf8 beklediğini halinde geçerli olmaz sizin örnek dize tek karakterdir.

Basit gösteri:

<?php
function foo($s) {
    echo 'len=', strlen($s), ' ';
  for($i=0; $i<strlen($s); $i++) {
    printf('%02X ', ord($s[$i]));
  }
  echo "\n";
}

 // my file is latin1 encoded and so is the string literal
foo('Moe’s');
// now try it with an utf8 encoded string
foo( utf8_encode('Moe’s') );

prints

len=5 4D 6F 65 92 73
len=6 4D 6F 65 C2 92 73

Therefore the question is: Do you feed the mysql server something in a "wrong" encoding?
Each connection has a connection charset and the mysql server expects your client (php script) to send data that is encoded in that character set. You can find out what the connection charset is with

SHOW VARIABLES LIKE '%character%'

gibi

$mysql = mysql_connect('..', '..', '..') or die(mysql_error());
mysql_select_db('..', $mysql) or die(mysql_error());

$query = "SHOW VARIABLES like '%character%'";
$result = mysql_query($query, $mysql) or die(__LINE__.mysql_error());
while( false!==($row=mysql_fetch_array($result, MYSQL_ASSOC)) ) {
  echo join(', ', $row), "\n";
}

Bu gibi bir şeyler yazdırmak gerekir

character_set_client, utf8
character_set_connection, utf8
character_set_database, latin1
character_set_filesystem, binary
character_set_results, utf8
character_set_server, utf8
character_set_system, utf8

ve character_set_connection, utf8 mysql sunucu istemci (php) için utf8 kodlanmış karakterleri beklediğini, yani "benim" bağlantı karakter seti, utf8 olduğunu gösterir. "Sizin" bağlantı charset nedir?

Sonra vardı, yani eğer, senin parametre dize gerçek kodlama bir göz atın

$foo = mysql_real_escape_string($_POST['foo'], $mysql);

tarafından Yenisini

echo '<div>Debug hex($_POST[foo])=';
for($i=0; $i<strlen($s); $i++) {
    printf('%02X ', ord($_POST['foo'][$i]));
}
echo "</div>\n";
$foo = mysql_real_escape_string($_POST['foo'], $mysql);

ve giriş dizesi gerçek kodlama ne olduğunu kontrol edin. Bu 92 yazdırmak veya C2 92 mu?