摘抄:mysql set names和set

Jun 07, 2016 pm 03:40 PM
mysql set 導入 初め

首先介绍下 三个MySQL的”环境变量”设置命令及其作用: character_set_client: MySQL服务器, 客户端的编码集 character_set_connection: 传输给MySQL服务器的时候的编码集 character_set_results: 期望MySQL返回的结果的编码集 比如, 通过使用”SET NAME

      首先介绍下三个MySQL的”环境变量”设置命令及其作用:

  • character_set_client:          MySQL服务器, 客户端的编码集
  • character_set_connection:传输给MySQL服务器的时候的编码集
  • character_set_results:       期望MySQL返回的结果的编码集

  比如, 通过使用”SET NAMES utf8″, 就告诉服务器, 我用的是utf-8编码, 我希望你也给我返回utf-8编码的查询结果. 

      一般情况下, 使用”SET NAMES”就足够了, 也是可以保证正确的. 那么为什么手册又要说推荐使用mysqli_set_charset呢? 

  首先, 我们看看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) 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问题): 

 
  <?php   $db = mysql_connect(&#39;localhost:3737&#39;, &#39;root&#39; ,&#39;123456&#39;); 
  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) "慭" 
ログイン後にコピー

 个中细节有待进一步验证。原文适当修改。文章摘至:深入理解mysql SET NAMES和mysql(i)_set_charset
 

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPのビッグデータ構造処理スキル PHPのビッグデータ構造処理スキル May 08, 2024 am 10:24 AM

PHPのビッグデータ構造処理スキル

PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか? PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか? Jun 03, 2024 pm 08:11 PM

PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか?

PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか? PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか? Jun 03, 2024 pm 12:19 PM

PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか?

データベースにおける Java 列挙型のアプリケーション シナリオは何ですか? データベースにおける Java 列挙型のアプリケーション シナリオは何ですか? May 05, 2024 am 09:06 AM

データベースにおける Java 列挙型のアプリケーション シナリオは何ですか?

PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか? PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか? Jun 02, 2024 pm 02:26 PM

PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか?

MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 Dec 09, 2024 am 11:42 AM

MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法

PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか? PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか? Jun 02, 2024 pm 02:13 PM

PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか?

Samsung S24aiの機能を詳しく紹介 Samsung S24aiの機能を詳しく紹介 Jun 24, 2024 am 11:18 AM

Samsung S24aiの機能を詳しく紹介

See all articles