Как получить "имена полей" с помощью PHP ADOdb?
Я использую PHP ADOdb, и я могу получить набор результатов:
$result = &$db->Execute($query);
Как я могу получить имена полей из этой строки и пройти через них?
(Я использую базу данных доступа, если это имеет значение.)
6 ответов
Это будет зависеть от вашего режима извлечения - если вы установите для параметра FetchMode значение ADODB_FETCH_NUM (вероятно, по умолчанию), каждая строка содержит плоский массив столбцов. Если вы установите для параметра FetchMode значение ADODB_FETCH_ASSOC, вы получите ассоциативный массив, в котором вы можете получить доступ к каждому значению по ключу. Следующее взято из документации ADODB - http://phplens.com/lens/adodb/docs-adodb.htm
$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')
Чтобы просмотреть набор результатов:
$result = &$db->Execute($query);
foreach ($result as $row) {
print_r($row);
}
Небольшое улучшение в решении, опубликованном @thetaiko.
Если вам нужны ТОЛЬКО имена полей, добавьте LIMIT 1
до конца вашего выбора оператора (как показано ниже). Это скажет серверу отправлять вам одну строку с именами столбцов, а не отправлять вам всю таблицу.
SELECT * FROM table LIMIT 1;
Я работаю с таблицей, которая содержит 9,1 млн записей, поэтому это незначительное изменение значительно ускоряет запрос!
Это функция, которую я использую для возврата массива полей - я убрал некоторые дополнительные вещи, которые, например, позволяют ему работать с другими БД, отличными от MySQL.
function getFieldNames($strTable, $cn) {
$aRet = array();
# Get Field Names:
$lngCountFields = 0;
$strSQL = "SELECT * FROM $strTable LIMIT 1;";
$rs = $cn->Execute($strSQL)
or die("Error in query: \n$strSQL\n" . $cn->ErrorMsg());
if (!$rs->EOF) {
for ($i = 0; $i < $rs->FieldCount(); $i++) {
$fld = $rs->FetchField($i);
$aRet[$lngCountFields] = $fld->name;
$lngCountFields++;
}
}
$rs->Close();
$rs = null;
return $aRet;
}
Изменить: просто чтобы указать, что, как я уже сказал, я убрал некоторые дополнительные вещи, и поэтому проверка EOF больше не нужна в приведенной выше, сокращенной версии.
Если вам нужны имена столбцов даже для пустых таблиц или для объединений нескольких таблиц, используйте это:
$db->Execute("SELECT .......");
// FieldTypesArray - Reads ColoumnInfo from Result, even for Joins
$colInfo = $res->FieldTypesArray();
$colNames = array();
foreach($colNames as $info) $colInfo[] = $info->name;
Изначально я пытался использовать MetaColumnNames, но он дал разные результаты в VisualPHPUnit и на реальном сайте, работая на одном и том же сервере, поэтому в итоге я сделал что-то вроде этого:
$sql = "select column_name, column_key, column_default, data_type, table_name, table_schema from information_schema.columns";
$sql .= ' where table_name="'.$table.'" and table_schema="'.$database_name.'"';
$result = $conn->Execute($sql);
while($row = $result->fetchRow()) {
$out[] = strToUpper($row['column_name']);
}
Я думаю, что это должно работать с mysql, mssql и postgres. Преимущество этого заключается в том, что вы можете получить имена столбцов, даже если запрос из таблицы возвращает пустой набор.
OP запрашивает список имен полей, которые будут результатом выполнения оператора sql, хранящегося в $query.
Использование $result->fetchRow(), даже если режим выборки установлен на ассоциативный, ничего не вернет, если никакие записи не соответствуют критериям, установленным $query. Массив $result->fields также будет пустым и не даст никакой информации для получения списка имен полей.
На самом деле мы не знаем, что находится внутри оператора $query. Кроме того, установка лимита на 1 может быть несовместима со всеми драйверами баз данных, поддерживаемыми PHP ADOdb.
Ответ Radon8472 правильный, но правильный код может быть:
$result = $db->Execute($query);
// FieldTypesArray - an array of ADOFieldObject Objects
// read from $result, even for empty sets or when
// using * as field list.
$colInfo = [];
if (is_subclass_of($result, 'ADORecordSet')){
foreach ($result->FieldTypesArray() as $info) {
$colInfo[] = $info->name;
}
}
У меня есть привычка проверять имя класса $result, поскольку PHP ADOdb вернет false в случае сбоя выполнения.