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(资源 $result, 整数 $field_offset = 0): 对象

返回一个包含字段信息的 对象。此函数可用于获取有关提供的查询结果中字段的信息。

参数

result

正在评估的结果 资源。此结果来自对 mysql_query() 的调用。

field_offset

数字字段偏移量。如果未指定字段偏移量,则检索尚未通过此函数检索的下一个字段。field_offset0 开始。

返回值

返回一个包含字段信息的 对象。对象的属性为

  • 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)." ms\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)." ms\n";
?>

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

因此,为了方便使用,建议使用查询2...但是,如果您是性能发烧友,则应使用查询1。
mwwaygoo AT hotmail DOT com
12年前
使用 mysql_fetch_field,您可以生成更强大的 mysql_fetch_assoc 版本。

当查询具有相同字段名的两个表时,通常需要使用 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() 返回
数组(
'index'=>2,
'a'=>'pear',
'b'=>'apple',
'test'=>'test',
4=>4
)

mysql_fetch_table_assoc() 返回
数组(
'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年前
我需要获取字段信息和枚举/集合值。这是我创建的函数,用于扩展 mysql_fetch_field 返回的对象。此外,我还决定通过“名称”和位置以类似于 mysql_fetch_array 的方式将表的所有字段返回到字段对象数组中。

您可以使用以下代码进行测试

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


字段对象现在具有 'len'、'values' 和 'flags' 参数。


注意:'values' 仅包含集合和枚举字段的数据。

<?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 值。如果为真,则为 BLOB,否则为 TEXT。有人可以确认吗?
To Top