PHP Conference Japan 2024

mysql_fetch_field

(PHP 4, PHP 5)

mysql_fetch_field從結果取得欄位資訊並以物件傳回

警告

此擴充功能已在 PHP 5.5.0 中被棄用,並在 PHP 7.0.0 中移除。應改用 MySQLiPDO_MySQL 擴充功能。另請參閱 MySQL:選擇 API 指南。此函式的替代方案包括

描述

mysql_fetch_field(resource $result, int $field_offset = 0): object

傳回包含欄位資訊的物件。此函式可用於取得提供的查詢結果中欄位的相關資訊。

參數

result

正在評估的結果 resource。此結果來自對 mysql_query() 的呼叫。

field_offset

欄位的數值偏移量。如果未指定欄位偏移量,則會擷取此函式尚未擷取的下一個欄位。field_offset0 開始。

傳回值

傳回包含欄位資訊的 object。物件的屬性為

  • name - 欄位名稱
  • table - 欄位所屬的表格名稱,如果定義了別名,則為別名
  • max_length - 欄位的最大長度
  • not_null - 如果欄位不能為 null,則為 1
  • primary_key - 如果欄位是主鍵,則為 1
  • unique_key - 如果欄位是唯一鍵,則為 1
  • multiple_key - 如果欄位是非唯一鍵,則為 1
  • numeric - 如果欄位是數值,則為 1
  • blob - 如果欄位是 BLOB,則為 1
  • type - 欄位的類型
  • unsigned - 如果欄位是無符號的,則為 1
  • zerofill - 如果欄位是以零填充,則為 1

範例

範例 #1 mysql_fetch_field() 範例

<?php
$conn
= mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!
$conn) {
die(
'無法連線:' . mysql_error());
}
mysql_select_db('database');
$result = mysql_query('select * from table');
if (!
$result) {
die(
'查詢失敗:' . mysql_error());
}
/* 取得欄位元數據 */
$i = 0;
while (
$i < mysql_num_fields($result)) {
echo
"欄位 $i 的資訊:<br />\n";
$meta = mysql_fetch_field($result, $i);
if (!
$meta) {
echo
"沒有可用資訊<br />\n";
}
echo
"<pre>
blob:
$meta->blob
max_length:
$meta->max_length
multiple_key:
$meta->multiple_key
name:
$meta->name
not_null:
$meta->not_null
numeric:
$meta->numeric
primary_key:
$meta->primary_key
table:
$meta->table
type:
$meta->type
unique_key:
$meta->unique_key
unsigned:
$meta->unsigned
zerofill:
$meta->zerofill
</pre>"
;
$i++;
}
mysql_free_result($result);
?>

註解

注意此函式傳回的欄位名稱是區分大小寫的。

注意:

如果在 SQL 查詢中將欄位或表格名稱設定了別名,則會傳回別名。可以使用例如 mysqli_result::fetch_field() 來檢索原始名稱。

參見

新增註解

使用者貢獻的註解 12 則註解

david at vitam dot be
16 年前
一個小函式,可協助程式設計人員從多重選取查詢中區分表格名稱,其中某些欄位在不同的表格中具有相同的名稱。

<?php
public function sql($sql) {
$T_Return=array();
$result=@mysql_query($sql);

$i=0;
while (
$i < mysql_num_fields($result)) {
$fields[]=mysql_fetch_field($result, $i);
$i++;
}

while (
$row=mysql_fetch_row($result)) {
$new_row=array();
for(
$i=0;$i<count($row); $i++) {
$new_row[ $fields[$i]->table][$fields[$i]->name]=$row[$i];
}
$T_Return[]=$new_row;
}


return
$T_Return;
}
?>
krang at krang dot org dot uk
22 年前
欄位類型回傳的是 PHP 如何分類欄位中的資料,而不是資料在資料庫中的儲存方式;請使用以下範例來檢索關於欄位的 MySQL 資訊....

<?php
$USERNAME
= '';
$PASSWORD = '';

$DATABASE = '';
$TABLE_NAME = '';

mysql_connect('localhost', $USERNAME, $PASSWORD)
or die (
"無法連線");

$result = mysql_query("SHOW FIELDS FROM $DATABASE.$TABLE_NAME");

$i = 0;

while (
$row = mysql_fetch_array($result)) {
echo
$row['Field'] . ' ' . $row['Type'];
}
?>
Nick Baicoianu
19 年前
請務必注意,$max_length 是該欄位在回傳資料集中最長值的長度,而不是該欄位設計來保存的最大資料長度。
lucien at ocia dot nl
12 年前
效能注意事項!

我使用此腳本進行測試,該表格有 26 個欄位。

<?php
$t_start
= microtime(true);
$sql = mysql_query("SELECT * FROM `table` LIMIT 1") or trigger_error(mysql_error(), E_USER_WARNING);
for (
$i = 0; $i < mysql_num_fields($sql); $i++) {
$meta = mysql_fetch_field($sql, $i);
echo
"欄位 ".$meta->name." 的資訊:\n";
echo
"\tblob: $meta->blob
\tmax_length:
$meta->max_length
\tmultiple_key:
$meta->multiple_key
\tname:
$meta->name
\tnot_null:
$meta->not_null
\tnumeric:
$meta->numeric
\tprimary_key:
$meta->primary_key
\ttable:
$meta->table
\ttype:
$meta->type
\tunique_key:
$meta->unique_key
\tunsigned:
$meta->unsigned
\tzerofill:
$meta->zerofill
"
;
}
$t_stop = microtime(true);
$t_proc = $t_stop - $t_start;
echo
"查詢 1 的處理時間: ".number_format($t_proc * 1000, 3)." 毫秒\n";
unset(
$t_start);
unset(
$t_stop);
unset(
$t_proc);
$t_start = microtime(true);
$sql = mysql_query("DESCRIBE `table`");
while (
$res = mysql_fetch_array($sql, MYSQL_ASSOC)) {
print_r($res);
}
$t_stop = microtime(true);
$t_proc = $t_stop - $t_start;
echo
"查詢 2 的處理時間: ".number_format($t_proc * 1000, 3)." 毫秒\n";
?>

查詢 1 => 0.444 毫秒
查詢 2 => 1.146 毫秒

因此,為了方便使用,建議使用查詢 2... 但是,如果您是個效能狂,您應該使用查詢 1。
mwwaygoo AT hotmail DOT com
12 年前
使用 mysql_fetch_field 您可以產生更強健的 mysql_fetch_assoc 版本。

當查詢 2 個具有相同欄位名稱的表格時,通常您需要使用 mysql_fetch_row 來取得以整數鍵為索引的陣列,而不是以關聯鍵為索引的陣列。這是因為第二個表格中相同名稱的欄位將覆蓋從第一個表格回傳的資料。
然而,這個簡單的函數會在索引鍵的欄位名稱前面插入表格名稱,以防止交叉覆寫。

例如:SELECT * , 'test' AS test 4 FROM table AS T_1, table AS T_2 WHERE T_1.a=T_2.b

可能會產生

mysql_fetch_assoc() 回傳
array(
'index'=>2,
'a'=>'pear',
'b'=>'apple',
'test'=>'test',
4=>4
)

mysql_fetch_table_assoc() 回傳
array(
'T_1.index' =>1,
'T_1.a'=>'apple',
'T_1.b'=>'banana',
'T_2.index'=>2,
'T_2.a'=>'pear',
'T_2.b'=>'apple',
'test'=>'test',
4=>4
)

<?php
function mysql_fetch_table_assoc($resource)
{
// 此函式從查詢中取得所有資料,而不會覆寫相同的欄位
// 使用表名稱和欄位名稱作為索引

// 先取得資料
$data=mysql_fetch_row($resource);
if(!
$data) return $data; // 資料結束

// 取得欄位資訊
$fields=array();
$index=0;
$num_fields=mysql_num_fields($resource);
while(
$index<$num_fields)
{
$meta=mysql_fetch_field($resource, $index);
if(!
$meta)
{
// 如果沒有欄位資訊,則預設使用索引編號
$fields[$index]=$index;
}
else
{
$fields[$index]='';
// 處理欄位別名 - 即沒有表名稱 (SELECT T_1.a AS temp)
if(!empty($meta->table)) $fields[$index]=$meta->table.'.';
// 處理原始資料 - 即沒有欄位名稱 (SELECT 1)
if(!empty($meta->name)) $fields[$index].=$meta->name; else $fields[$index].=$index;
}
$index++;
}
$assoc_data=array_combine($fields, $data);
return
$assoc_data;
}
?>
jorachim at geemail dot com
16 年前
如果您想要取得表格中的欄位,一個簡單的 DESCRIBE 查詢就可以達到目的

<?php
$query
="DESCRIBE Users";
$result = mysql_query($query);

echo
"<ul>";

while(
$i = mysql_fetch_assoc($result))
echo
"<li>{$i['Field']}</li>";

echo
"</ul>";
?>

這個方法應該有效。
Jonathan
14 年前
應該注意,只有在表格的主鍵只有單一欄位時,`primary_key` 成員變數才會被設為 1。如果您的表格有多個欄位的主鍵,您將不會得到您可能預期的結果。

例如
CREATE TABLE `line_item_table` (
`liForeignKey1` int(11) unsigned not null,
`liForeignKey2` int(11) unsigned not null,
PRIMARY KEY (`liForeignKey1`, `liForeignKey2`)
) ENGINE=MyISAM;

您可能預期兩個欄位的 `primary_key` 都等於 1,但 `var_dump()` 會顯示這兩個欄位都得到以下結果
["primary_key"]=>int(0)

這是 PHP 5.2.13 和 MySQL 5.0.51 的情況
Daniel B
12 年前
一個簡單的函式來顯示查詢中的所有資料...

function dumpquery($query) {
$numfields = mysql_num_fields($query);
echo '<table border="1" bgcolor="white"><tr>';
for ($i = 0; $i<$numfields; $i += 1) {
$field = mysql_fetch_field($query, $i);
echo '<th>' . $field->name . '</th>';
}
echo '</tr>';
while ($fielddata = mysql_fetch_array($query)) {
echo '<tr>';
for ($i = 0; $i<$numfields; $i += 1) {
$field = mysql_fetch_field($query, $i);
echo '<td>' . $fielddata[$field->name] . '</td>';
}
echo '</tr>';
}
echo '</table>';
}
TALU
15 年前
XML 產生。

在線上伺服器上允許參數選擇資料庫和表格存在一些安全風險(除非使用者受到限制或將 $_GET 替換為固定值。)

輸出具有標準格式的 xml,用於 <config> 部分,以便在 Flash 中產生表單。

<?php
//
// makeXML.php?db=dbname&table=tablename
//

set_time_limit(300);

$host = "localhost";
$user = "root";
$password = "root";

$database = $_GET['db'];
$table = $_GET['table'];

mysql_connect($host,$user,$password);
@
mysql_select_db($database) or die( "無法選擇資料庫");


$querytext="SELECT * FROM ".$table;
$result=mysql_query($querytext);

if (
$result){
$num=mysql_num_rows($result);
}else{
$num=0;
}

?>
<?php
header
('Content-Type: text/xml');
echo
"<?xml version='1.0'?>";

if (
$num > 0){
?>
<<?php echo $table?>>
<config>
<?php
// 顯示欄位數量
echo "<numFields>".mysql_num_fields($result)."</numFields>";
$i = 0;
$primaryKey = "";
$nameArray = array();
$maxLengthArray = array();
$typeArray = array();
while (
$i < mysql_num_fields($result)) {
$meta = mysql_fetch_field($result, $i);
$nameArray[$i] = $meta->name;
$maxLengthArray[$i] = $meta->max_length;
$typeArray[$i] = $meta->type;
if (
$meta->primary_key){
$primaryKey = $meta->name;
}
$i++;
}
$i = 0;
echo
"<fieldNames>";
while (
$i < count($nameArray)) {
echo
"<field".$i.">".$nameArray[$i]."</field".$i.">";
$i++;
}
echo
"</fieldNames>";
$i = 0;
echo
"<fieldMaxLength>";
while (
$i < count($maxLengthArray)) {
echo
"<field".$i.">".$maxLengthArray[$i]."</field".$i.">";
$i++;
}
echo
"</fieldMaxLength>";
$i = 0;
echo
"<fieldType>";
while (
$i < count($typeArray)) {
echo
"<field".$i.">".$typeArray[$i]."</field".$i.">";
$i++;
}
echo
"</fieldType>";
?>
<primaryKey><?php echo $primaryKey?></primaryKey>
<numRecords><?php echo $num?></numRecords>
</config>
<?php
$i
=0;
while (
$i < $num) {
$ID=mysql_result($result,$i,"ID");
$value=mysql_result($result,$i,"value");
$title=mysql_result($result,$i,"title");
$description=mysql_result($result,$i,"description");
?>
<row>
<ID><?php echo $ID?></ID>
<weighting><?php echo $value?></weighting>
<title><?php echo $title?></title>
<description><?php echo $description?></description>
</row>
<?php
$i
= $i + 1;
}
?>
</<?php echo $table?>>

<?php
}
?>
php at brayra dot com
22 年前
我需要取得欄位資訊以及 enum/set 的值。這是我建立的函式,用於擴展 mysql_fetch_field 回傳的物件。我也決定以 "name" 和位置的方式,將表格的所有欄位回傳在一個欄位物件陣列中,就像 mysql_fetch_array 的做法一樣。

你可以使用以下方式測試它

<?php
$myfields
= GetFieldInfo('test_table');
print
"<pre>";
print_r($myfields);
print
"</pre>";
?>


現在欄位物件具有 'len'、'values' 和 'flags' 參數。
注意:'values' 只包含 set 和 enum 欄位的資料。

<?php
//這假設已經開啟資料庫連線
//我也使用常數 DB_DB 作為目前的資料庫。
function GetFieldInfo($table)
{
if(
$table == '') return false;
$fields = mysql_list_fields(DB_DB, $table);
if(
$fields){
$columns = mysql_query('show columns from ' . $table);
if(
$columns){
$num = mysql_num_fields($fields);
for(
$i=0; $i < $num; ++$i){
$column = mysql_fetch_array($columns);
$field = mysql_fetch_field($fields, $i);
$flags = mysql_field_flags($fields, $i);
if(
$flags == '') $flags=array();
else
$flags = explode(' ',$flags);
if (
ereg('enum.(.*).',$column['Type'],$match))
$field->values = explode(',',$match[1]);
if (
ereg('set.(.*).',$column['Type'],$match))
$field->values = explode(',',$match[1]);
if(!
$field->values) $field->values = array();
$field->flags = $flags;
$field->len = mysql_field_len($fields, $i);
$result_fields[$field->name] = $field;
$result_fields[$i] = $field;
}
mysql_free_result($columns);
}
mysql_free_result($fields);
return
$result_fields;
}
return
false;
}
?>

希望其他人也覺得這有用。
php [spat] hm2k.org
16 年前
這是對先前 mysql_column_exists 函式的改進。

<?php

function mysql_column_exists($table_name, $column_name, $link=false) {
$result = @mysql_query("SHOW COLUMNS FROM $table_name LIKE '$column_name'", $link);
return (
mysql_num_rows($result) > 0);
}

?>
eviltofu at gmail dot com
13 年前
MYSQLI_TYPE_BLOB 指示該欄位為 BLOB 或 TEXT。我認為你需要檢查 blob 值。如果它是 true,則它是 BLOB,否則它是 TEXT。有人可以確認嗎?
To Top