2012-05-03 16 views
2

lengthの結果がmysqli_fetch_fields()の場合、不正確な結果になります。mysqli_fetch_fields()はなぜ私に不正確な結果を与えていますか?

のMySQL>DESCRIBE Notices;

Field  Type    Null  Key  Default  Extra 
Id  int(10) unsigned NO  PRI  (NULL)  auto_increment 
UserId int(10) unsigned NO  MUL  (NULL) 
Title  char(255)   NO    (NULL) 
Name  char(255)   NO    (NULL) 
Summary text    NO    (NULL) 

しかし、

class Db { 
    public function exec($sql) { 
     if (!$this->link) { 
      $this->open(); 
     } 
     if (($this->result = mysqli_query($this->link, $sql)) === false) { 
      throw new Exception('<b>' . __METHOD__ . '</b>: ' . $sql . ': ' . mysqli_error($this->link)); 
     } 
     return true; 
    } 
    public function field_info($table) { 
     $sql = 'SELECT * FROM `' . $table . '` LIMIT 1'; 
     $this->exec($sql); 
     return $this->field_info = $this->result->fetch_fields(); 
    } 
} 

$a = $db->field_info('Notices'); 
print_r($a); 

は、次の出力を生成します。

// Note: "max_length" is the maximum existing length in the result set, 
// while "length" is the set maximum length in the table definition. 

Array 
(
    [0] => stdClass Object 
     (
      [name] => Id 
      [orgname] => Id 
      [table] => Notices 
      [orgtable] => Notices 
      [def] => 
      [max_length] => 1 
      [length] => 10 
      [charsetnr] => 63 
      [flags] => 49699 
      [type] => 3 
      [decimals] => 0 
     ) 

    [1] => stdClass Object 
     (
      [name] => UserId 
      [orgname] => UserId 
      [table] => Notices 
      [orgtable] => Notices 
      [def] => 
      [max_length] => 1 
      [length] => 10 
      [charsetnr] => 63 
      [flags] => 53289 
      [type] => 3 
      [decimals] => 0 
     ) 

    [2] => stdClass Object 
     (
      [name] => Title 
      [orgname] => Title 
      [table] => Notices 
      [orgtable] => Notices 
      [def] => 
      [max_length] => 27 
      [length] => 765 
      [charsetnr] => 33 
      [flags] => 4097 
      [type] => 254 
      [decimals] => 0 
     ) 

    [3] => stdClass Object 
     (
      [name] => Name 
      [orgname] => Name 
      [table] => Notices 
      [orgtable] => Notices 
      [def] => 
      [max_length] => 25 
      [length] => 765 
      [charsetnr] => 33 
      [flags] => 4097 
      [type] => 254 
      [decimals] => 0 
     ) 

    [4] => stdClass Object 
     (
      [name] => Summary 
      [orgname] => Summary 
      [table] => Notices 
      [orgtable] => Notices 
      [def] => 
      [max_length] => 26 
      [length] => 196605 
      [charsetnr] => 33 
      [flags] => 4113 
      [type] => 252 
      [decimals] => 0 
     ) 
) 

あなたが見れば、あなたはCHARの報告の長さが表示されますフィールドが一致しません。 DESCRIBEは私に255を与え、fetch_fields()は私に765を与えている。どうして?

(アイデアは、あなたが迷っている場合には、<input>タグのmaxlength属性を生成することである。)

答えて

1

あなたのフィールドの長さは255 文字ですが、報告された長さがバイトです。

MySQLは3 bytes per characterをUTF-8照合に使用しているため、結果として255 * 3 = 765となります。

+0

ここで、長さはバイト単位で表されていますか? [mysqli_fetch_fields'(http://php.net/manual/en/mysqli-result.fetch-fields.php#refsect1-mysqli-result.fetch-fields-returnvalues)のドキュメントには、「フィールドを指定してください。 "また、Windows上で間違った結果しか得られません。 Linuxで同じスクリプトを実行すると、期待される結果、つまり '255'が得られます。 –

+0

@SebastianZartnerいいえ。私は、PHPとMySQLの両方がLinux上で動作していたのを見ていました。 (Ubuntu上でもCentOS上でも) – TRiG

+0

右のコメントは、昨日の私の認識です。下の私の答えで見ることができますが、実際にはOSとは無関係ですが、むしろデフォルトのクライアントキャラクタセットによって定義されています。 –

-1

私は同じ問題があり、あなたが使用する必要があることを知りました: $ val-> length;

not max_length、max_lengthは、テーブルのdefではなく、その特定の列の値の最大長です。

テーブル定義を使用する場合は、「長さ」を使用します。

$q = $mysqli->query("select * from table"); 

$finfo = $q->fetch_fields(); 

foreach ($finfo as $val) { 

    echo $val->length; 

} 

は、参考文献:

+0

はい。私の質問のコードのコメントを参照してください。これはすでにその点です。 – TRiG

+0

ああ、水平スクロールbalkのために気づかなかった... – stevesrs

1

明らかで定義されたデフォルトの文字セットに依存lengthなどmysqli_result::fetch_fields()/mysqli_fetch_fields()出力でcharsetnr値クライアント。

など。 a charsetnr33はUTF-8を表します。正確には、実際には文字セット 'utf8'の照合 'utf8_general_ci'を表します。その情報は、このクエリを実行することで取得できます

SELECT * FROM information_schema.collations; 

利用できる文字セットとその文字の長さのリストは、このクエリを介して検索することができます。

SELECT * FROM information_schema.character_sets; 

デフォルトのクライアントの文字セットがPHPで変更することができますmysqli::set_charset()/mysqli_set_charset()と呼んでください。

例:

$dbHandle->set_charset('latin1'); 

mysqli_fetch_fields()のためのPHPのドキュメントは、現在、その情報が含まれていないので、私はbug 68573にそれを追加するように要求。

defined within the server configurationのデフォルトの文字セットは、described in another threadとすることもできます。

fetch_fields()のこの動作はかなり混乱していますので、bug 68574に変更するように要求しました。

関連する問題