Rumah pangkalan data tutorial mysql 深入理解mysql SET NAMES和mysql(i)_set_charset的区别

深入理解mysql SET NAMES和mysql(i)_set_charset的区别

Jun 07, 2016 pm 06:05 PM
set

最近公司组织了个PHP安全编程的培训, 其中涉及到一部分关于Mysql的 SET NAMES 和mysql_set_charset (mysqli_set_charset)的内容

说到, 尽量使用mysqli_set_charset(mysqli:set_charset)而不是”SET NAMES”, 当然, 这个内容在PHP手册中也有叙及, 但是却没有解释为什么.
  最近有好几个朋友问我这个问题, 到底为什么?
  问的人多了, 我也就觉得可以写篇blog, 专门介绍下这部分的内容了.
  首先, 很多人都不知道”SET NAMES”到底是做了什么,
  我之前的文章深入MySQL字符集设置中, 曾经介绍过character_set_client/character_set_connection/character_set_results这三个MySQL的”环境变量”, 这里再简单介绍下,
  这三个变量, 分别告诉MySQL服务器, 客户端的编码集, 在传输给MySQL服务器的时候的编码集, 以及期望MySQL返回的结果的编码集.
  比如, 通过使用”SET NAMES utf8″, 就告诉服务器, 我用的是utf-8编码, 我希望你也给我返回utf-8编码的查询结果.
  一般情况下, 使用”SET NAMES”就足够了, 也是可以保证正确的. 那么为什么手册又要说推荐使用mysqli_set_charset(PHP>=5.0.5)呢?
  首先, 我们看看mysqli_set_charset到底做了什么(注意星号注释处, mysql_set_charset类似):
代码如下:
  //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)) {
  //** 调用libmysql的对应函数
  RETURN_FALSE;
  }
  RETURN_TRUE;
  }

  那mysql_set_character_set又做了什么呢?
代码如下:
  //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)   (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)   return 0;
  sprintf(buff, "SET NAMES %s", cs_name);
  if (!mysql_real_query(mysql, buff, strlen(buff)))
  {
  mysql->charset= cs;
  }
  }
  //以下省略

  我们可以看到, mysqli_set_charset除了做了”SET NAMES”以外, 还多做了一步:
代码如下:
  sprintf(buff, "SET NAMES %s", cs_name);
  if (!mysql_real_query(mysql, buff, strlen(buff)))
  {
  mysql->charset= cs;
  }

  而对于mysql这个核心结构的成员charset又有什么作用呢?
  这就要说说mysql_real_escape_string()了, 这个函数和mysql_escape_string的区别就是, 它会考虑”当前”字符集. 那么这个当前字符集从哪里来呢?
  对了, 你猜的没错, 就是mysql->charset.
  mysql_real_string在判断宽字符集的字符的时候, 就根据这个成员变量来分别采用不同的策略, 比如如果是utf-8, 那么就会采用libmysql/ctype-utf8.c.
  看个实例, 默认mysql连接字符集是latin-1, (经典的5c问题):
代码如下:
    $db = mysql_connect('localhost:3737', 'root' ,'123456');
  mysql_select_db("test");
  $a = "\x91\x5c";//"慭"的gbk编码, 低字节为5c, 也就是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));
  ?>

  因为, “慭”的gbk编码低字节为5c, 也就是ascii中的”\”, 而因为除了mysql(i)_set_charset影响mysql->charset以外, 其他时刻mysql->charset都为默认值, 所以, 结果就是:
代码如下:
  $ php -f 5c.php
  string(3) "慭\"
  string(3) "慭\"
  string(3) "慭\"
  string(2) "慭"

  大家现在很清楚了吧?
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Penjelasan terperinci tentang fungsi Set tag dalam teg SQL dinamik MyBatis Penjelasan terperinci tentang fungsi Set tag dalam teg SQL dinamik MyBatis Feb 26, 2024 pm 07:48 PM

Tafsiran teg SQL dinamik MyBatis: Penjelasan terperinci tentang penggunaan teg Set MyBatis ialah rangka kerja lapisan kegigihan yang sangat baik Ia menyediakan banyak teg SQL dinamik dan boleh membina pernyataan operasi pangkalan data secara fleksibel. Antaranya, tag Set ialah tag yang digunakan untuk menjana klausa SET dalam kenyataan UPDATE, yang sangat biasa digunakan dalam operasi kemas kini. Artikel ini akan menerangkan secara terperinci penggunaan teg Set dalam MyBatis dan menunjukkan kefungsiannya melalui contoh kod tertentu. Apakah itu Set tag Set tag digunakan dalam MyBati

Bagaimana untuk memadam elemen dari set dalam javascript Bagaimana untuk memadam elemen dari set dalam javascript Jan 12, 2022 am 10:56 AM

Kaedah untuk memadam elemen: 1. Gunakan delete() untuk memadam elemen yang ditentukan daripada objek Set, sintaks "setObj.delete(value);" 2. Gunakan clear() untuk memadam semua elemen dalam objek Set, sintaks "setObj.clear();".

Inventori penggunaan biasa dict dan set dalam pengaturcaraan Python Inventori penggunaan biasa dict dan set dalam pengaturcaraan Python Jul 25, 2023 pm 04:52 PM

Artikel ini berdasarkan asas Python dan memperkenalkan cara menggunakan dict dan set Dict menggunakan struktur storan nilai kunci sangat berguna dalam Python ialah rentetan.

Perbandingan Peta Java dan rangka kerja koleksi lain: analisis kelebihan dan kekurangan serta panduan senario aplikasi Perbandingan Peta Java dan rangka kerja koleksi lain: analisis kelebihan dan kekurangan serta panduan senario aplikasi Feb 19, 2024 pm 10:24 PM

1. Gambaran Keseluruhan Rangka Kerja Pengumpulan Peta Rangka kerja pengumpulan Peta ialah struktur data pasangan nilai kunci yang membolehkan anda menggunakan kunci untuk mencari dan menyimpan nilai. Setiap kunci dalam Peta adalah unik dan hanya boleh dikaitkan dengan satu nilai. Pelaksanaan biasa dalam rangka kerja pengumpulan Peta termasuk HashMap, TreeMap dan LinkedHashMap. 1.HashMapHashMap ialah pelaksanaan Peta yang paling banyak digunakan dalam Java Ia menyimpan data berdasarkan jadual cincang. HashMap mempunyai prestasi cemerlang, dan kerumitan masa operasi carian dan sisipan ialah O(1), tetapi ia tidak menjamin susunan unsur. Kod demo: Mapmap=newHashMap

Apakah perbezaan antara kaedah yang ditetapkan dan kaedah tambah dalam Senarai dalam java? Apakah perbezaan antara kaedah yang ditetapkan dan kaedah tambah dalam Senarai dalam java? Apr 19, 2023 pm 07:49 PM

Prakata Terdapat dua kaedah yang hampir sama dalam Senarai antara muka koleksi yang biasa digunakan dalam Java: Eset(intindex,Eelement);voidadd(intindex,Eelement); kedua-dua kaedah ini memasukkan elemen tertentu pada kedudukan tertentu dalam koleksi, kemudian Apakah perbezaannya antara dua kaedah ini? Seterusnya, mari kita lihat perbezaan dan persamaan antara kedua-dua kaedah ini melalui ArrayList, pelaksanaan koleksi yang biasa kita gunakan Pertama, mari kita lihat persamaan antara kedua-dua kaedah ini dalam ArrayList koleksi, seperti Contoh berikut: #Masukkan F pada kedudukan ke-2 koleksi #Masukkan Senarai Senarai= melalui kaedah tambah

Bagaimana untuk melaksanakan perintah Set bagi klien Tile bersepadu Springboot Bagaimana untuk melaksanakan perintah Set bagi klien Tile bersepadu Springboot May 19, 2023 pm 01:37 PM

Sintaks arahan yang ditetapkan SETkeyid[FIELDnamevalue...][EXseconds][NX|XX](OBJECTgeojson)|(POINTlatlonz)|(BOUNDSminlatminlonmaxlatmaxlon)|(HASHgeohash)|(STRINGvalue) Perintah yang ditetapkan adalah bersamaan dengan penggunaan perintah cincang dalam redis. Ia juga merupakan gabungan kunci dan id, tetapi perbezaannya ialah perintah set Tile38 juga boleh membawa lebih banyak atribut lain, seperti menyesuaikan medan FIELD, menetapkan tempoh sah EX, dll., maka kita perlu

Apakah prinsip pelaksanaan set koleksi Python? Apakah prinsip pelaksanaan set koleksi Python? Apr 20, 2023 pm 07:37 PM

Pemahaman mendalam tentang mesin maya Python: prinsip pelaksanaan set dan analisis kod sumber struktur data pengenalan typedefstruct{PyObject_HEADPy_ssize_tfill;/*Numberactiveanddummyenries*/Py_ssize_tused;/*Numberactiveenries*//*Thetablecontainsmask+1slots,andthat'swesastorethemaskizeof2maskin.

Struktur Data SPL PHP: Rahsia untuk Meningkatkan Prestasi Aplikasi Struktur Data SPL PHP: Rahsia untuk Meningkatkan Prestasi Aplikasi Feb 19, 2024 pm 11:12 PM

Konsep Struktur Data SPL PHPSPL (Perpustakaan PHP Standard) mengandungi satu set struktur data dan kelas iterator yang direka untuk meningkatkan jenis data asli PHP. Struktur ini dioptimumkan untuk menyimpan dan memanipulasi pelbagai data dengan cekap dan menyediakan antara muka yang konsisten dan mekanisme lelaran yang fleksibel. Struktur Data SPL Teras Pustaka SPL menyediakan pelbagai struktur data, termasuk: LinkedList: senarai terpaut dua kali yang membolehkan pemasukan, pemadaman dan carian pantas. Tindanan: Struktur data masuk dahulu keluar (LIFO) terakhir untuk operasi tindanan. Baris gilir: Struktur data masuk dahulu keluar dahulu (FIFO) untuk operasi baris gilir. Peta: Koleksi pasangan nilai kunci, menyediakan carian kunci dan penyimpanan data yang cekap. Set: pengumpulan nilai unik, menyokong carian dan pengumpulan ahli pantas

See all articles