MySQL在特殊字符处截断字符串。
MySQL在特殊字符处截断字符串。
我正在尝试使用PHP将远程POST数据(由iSnare发送的文章)插入MySQL。数据成功地来自远程POST发送方,我可以将其写入纯文本文件没有问题。
但不幸的是,当要将其插入MySQL时,MySQL会在特殊字符处截断字符串(文章)。我尝试了很多方法,但仍然没有成功!
我尝试过:
- 使用`mysql_real_escape_string()`转义字符
- 使用`htmlentities()`和`htmlspecialchars()`(使用每个参数..)
- 在执行其他操作之前向MySQL发送`SET NAMES utf8`查询
- 所有表和列都是UTF-8编码和`utf8_general_ci`(还尝试过`utf8_unicode_ci`和`utf8_bin`作为排序规则)
- 将所有PHP文件保存为UTF-8
但仍然找不到解决方案。如果有人能帮助我解决这个问题,我将非常非常非常感激。
下面是我的表定义和PHP代码:
PHP代码:
function guvenlik_sql($x){ // 清除输入中的SQL注入 return mysql_real_escape_string(htmlentities(stripslashes($x)), ENT_QUOTES); } // 检查数据是否真的来自Isnare.com服务器(地址已隐藏) if ($_SERVER['REMOTE_ADDR'] == $isnareIP || $_SERVER['REMOTE_ADDR'] == "xxx.xxx.xxx.xxx") { $title = guvenlik_sql($_POST["article_title"]); $first_name = guvenlik_sql($_POST["article_author"]); $description = guvenlik_sql($_POST["article_summary"]); $category = guvenlik_sql($_POST["article_category"]); $article = guvenlik_sql($_REQUEST["article_body_text"]); $article_html = guvenlik_sql($_POST["article_body_html"]); $resource_box = guvenlik_sql($_POST["article_bio_text"]); $resource_box_html = guvenlik_sql($_POST["article_bio_html"]); $keywords = guvenlik_sql($_POST["article_keywords"]); $email = guvenlik_sql($_POST["article_email"]); $fp = fopen('test.txt', 'a'); fwrite($fp, $title."\n"); fwrite($fp, $article."\n\n\n\n"); fclose($fp); mysql_query("INSERT INTO articles " . "(" . "first_name, " . "email, " . "title, " . "description, " . "article, " . "article_html, " . "category, " . "resource_box, " . "resource_box_html, " . "keywords, " . "distributor, " . "distributor_host" . ") VALUES (" . "'$first_name', " . "'$email', " . "'$title', " . "'$description', " . "'$article', " . "'$article_html', " . "'$category', " . "'$resource_box', " . "'$resource_box_html', " . "'$keywords', " . "'$isnare', " . "'$_SERVER['REMOTE_ADDR']', " . ")") or die(mysql_error()); } //end if security
表定义:
CREATE TABLE `articles` ( `article_ID` int(11) NOT NULL auto_increment, `first_name` varchar(100) NOT NULL, `last_name` varchar(100) NOT NULL, `email` varchar(100) NOT NULL, `password` varchar(100) NOT NULL, `author_url` varchar(255) NOT NULL, `company_name` varchar(100) NOT NULL, `address1` varchar(100) NOT NULL, `address2` varchar(100) NOT NULL, `state_2digit` varchar(100) NOT NULL, `state` varchar(100) NOT NULL, `zip_code` varchar(100) NOT NULL, `country` varchar(100) NOT NULL, `phone` varchar(100) NOT NULL, `newsletter` varchar(100) NOT NULL, `title` varchar(255) NOT NULL, `description` text NOT NULL, `article` longtext NOT NULL, `article_html` longtext NOT NULL, `category` varchar(100) NOT NULL, `cat` varchar(100) NOT NULL, `resource_box` text NOT NULL, `resource_box_html` longtext NOT NULL, `keywords` varchar(255) NOT NULL, `publish_date` timestamp NOT NULL default CURRENT_TIMESTAMP, `distributor` varchar(255) NOT NULL default '', `distributor_host` varchar(255) NOT NULL, PRIMARY KEY (`article_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC
MySQL截断字符串在特殊字符处的问题的出现的原因是没有正确设置字符集。虽然使用"Set names utf8"可以设置表和列名的字符集,但是对于内容字符集还需要使用"set character set utf8"。
解决方法是在数据库连接部分进行以下操作:
mysql_query("SET NAMES 'utf8'"); mysql_query("SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'"); mysql_query("SET CHARACTER SET utf8"); mysql_query("SET COLLATION_CONNECTION = 'utf8_unicode_ci'");
这样就可以解决MySQL截断字符串在特殊字符处的问题。
MySQL字符串截断特殊字符的问题产生的原因是,即使所有文件、连接和表都使用UTF8编码,特殊字符(如ä、ö、è等)所在的条目仍然被截断。解决方法是使用更多的UTF-8编码,对可能包含特殊字符的条目使用utf8_encode()函数进行编码。
mysql_query("INSERT INTO articles (first_name, email, title, description, article, article_html, category, resource_box, resource_box_html, keywords, distributor, distributor_host) values (
'" . utf8_encode($first_name) . "',
'" . $email . "',
'" . utf8_encode($title) . "',
'" . utf8_encode($description) . "',
// etc
)
需要注意的是,如果对已经进行了UTF-8编码的数据进行UTF-8编码,会产生垃圾数据。这里并不是对数据进行双重编码,而是将数据转换为UTF-8格式,以便存储在UTF-8数据库中。所以你只是修改了数据的形状,使其适应容器。方形无法适应三角形的容器。
MySQL在保存字符时会遇到一个问题,即在某些特殊字符处会截断字符串。这个问题在我们的一个老项目中出现过。原来,MySQL有自己的UTF8实现,无法保存由超过3个字节组成的字符(如表情符号等)。有时会抛出错误(如在这个问题"Incorrect string value" when trying to insert UTF-8 into MySQL via JDBC?中所述),有时则只会截断字符串。
解决方法是将编码从utf8切换为utf8mb4,如上述链接中所述,或者在保存前确保截断所有较长的字符。
虽然这是一个老问题,但随着我们越来越多地使用表情符号,这可能会在一些旧应用程序中发生。希望对某人有所帮助。