Deep understanding of the difference between MySQL SET names and MySQL (i) _set_charset _mysql

Source: Internet
Author: User
Tags sprintf strlen
When it comes to using Mysqli_set_charset (Mysqli:set_charset) instead of "Set NAMES", of course, this content is also described in the PHP manual, but it doesn't explain why.
Recently several friends have asked me this question, in the end why?
Asked a lot of people, I also think you can write a blog, specifically introduced under this part of the content.
First, a lot of people don't know what "SET NAMES" actually does,
My previous article went deep into the MySQL character set, and once introduced the Character_set_client/character_set_connection/character_set_results three MySQL "Environment variables", Here is a brief introduction,
These three variables, respectively, tell the MySQL server, the client's encoding set, the encoding set at the time of transmission to the MySQL server, and the code set expected to return the MySQL results.
For example, by using the "SET NAMES Utf8″, tell the server that I'm using the Utf-8 code, and I want you to return UTF-8 encoded query results."
In general, the use of "SET NAMES" is sufficient and is guaranteed to be correct. So why does the handbook suggest using Mysqli_set_charset (php>=5.0.5)?
First, let's look at what Mysqli_set_charset has done (note the asterisk annotation, mysql_set_charset similar):
Copy Code code as follows:

PHP-5.2.11-SRC/EXT/MYSQLI/MYSQLI_NONAPI.C Line 342
Php_function (Mysqli_set_charset)
{
My_mysql *mysql;
Zval *mysql_link;
char *cs_name = NULL;
unsigned int len;
if (Zend_parse_method_parameters (Zend_num_args () tsrmls_cc, Getthis ()
, "Os", &mysql_link, Mysqli_link_class_entry, &cs_name, &len) = = failure) {
Return
}
Mysqli_fetch_resource (MySQL, my_mysql*, &mysql_link, "Mysqli_link"
, mysqli_status_valid);
if (Mysql_set_character_set (Mysql->mysql, cs_name)) {
* * Call the corresponding function of Libmysql
Return_false;
}
Return_true;
}

And what did Mysql_set_character_set do?
Copy Code code as follows:

MYSQL-5.1.30-SRC/LIBMYSQL/CLIENT.C, line 3166:
int stdcall mysql_set_character_set (MySQL *mysql, const char *cs_name)
{
struct Charset_info_st *cs;
const char *save_csdir= charsets_dir;
if (Mysql->options.charset_dir)
Charsets_dir= mysql->options.charset_dir;
if (strlen (cs_name) < my_cs_name_size &&
(cs= get_charset_by_csname (Cs_name, My_cs_primary, MYF (0)))
{
Char buff[my_cs_name_size + 10];
Charsets_dir= Save_csdir;
/* Skip Execution of "SET NAMES" for pre-4.1 servers * *
if (mysql_get_server_version (MySQL) < 40100)
return 0;
sprintf (Buff, "SET NAMES%s", cs_name);
if (!mysql_real_query (MySQL, buff, strlen (buff))
{
Mysql->charset= CS;
}
}
The following omitted

As we can see, mysqli_set_charset, in addition to doing the "set NAMES", has one more step:
Copy Code code as follows:

sprintf (Buff, "SET NAMES%s", cs_name);
if (!mysql_real_query (MySQL, buff, strlen (buff))
{
Mysql->charset= CS;
}

And what is the role of CharSet, a member of the core structure of MySQL?
This is going to say mysql_real_escape_string (), and the difference between this function and mysql_escape_string is that it takes into account the "current" character set. So where does this current character set come from?
By the way, you guessed right, that's mysql->charset.
Mysql_real_string in judging the character of wide character set, according to this member variable to use different strategies, such as if it is utf-8, then will use LIBMYSQL/CTYPE-UTF8.C.
To see an instance, the default MySQL connection character set is Latin-1, (Classic 5c problem):
Copy Code code as follows:

<?php
$db = mysql_connect (' localhost:3737 ', ' root ', ' 123456 ');
mysql_select_db ("test");
$a = "\x91\x5c";//"慭" GBK encoding, low byte 5c, that is, "\" in ASCII
Var_dump (Addslashes ($a));
Var_dump (mysql_real_escape_string ($a, $db));
mysql_query ("Set names GBK");
Var_dump (mysql_real_escape_string ($a, $db));
Mysql_set_charset ("GBK");
Var_dump (mysql_real_escape_string ($a, $db));
?>

Because, "慭" GBK encoded low byte 5c, that is, "\" in ASCII, and because in addition to MySQL (i) _set_charset impact Mysql->charset, other times Mysql->charset are the default values, so, The result is:
Copy Code code as follows:

$ php-f 5c.php
String (3) "慭 \"
String (3) "慭 \"
String (3) "慭 \"
String (2) "慭"

Is everybody clear now?
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.