Следующий код позволяет мне передать инструкцию SQL классу и вызвать его метод для отображения хорошей таблицы результатов, включая имена столбцов.
Однако, если результатов нет, я все равно хочу, чтобы имена столбцов отображались.
К сожалению, getColumnMeta
не возвращает никаких данных, как в других примерах, которые я нашел.
Кто-нибудь знает, как получить getColumnMeta (), работающий в этом примере, или иначе я могу получить имена полей из инструкции SQL, когда запрос возвращает нулевые строки?
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <style type="text/css"> table thead tr td { background-color: #ddd; padding: 5px; font-weight: bold; } table tbody tr td { background-color: #eee; padding: 5px; color: navy; } div.sqlCommand { font-family: courier; } h2 { border-bottom: 1px solid #777; } </style> </head> <body> <?php $sql = 'SELECT LastName,FirstName,Title FROM employee WHERE 1=2 ORDER BY LastName'; echo '<h2>sqlite</h2>'; $dbSqlite = new DbSqlite($sql); echo $dbSqlite -> displayHtmlTable(); class DbSqlite { protected $sql; protected $records = array(); protected $columnNames = array(); public function __construct($sql) { $this -> sql = $sql; $this -> initialize(); } protected function initialize() { $db = new PDO('sqlite:chinook.sqlite'); $result = $db -> query($this -> sql); $result -> setFetchMode(PDO::FETCH_ASSOC); $columnsAreDefined = false; while ($row = $result -> fetch()) { $this -> records[] = $row; if (!$columnsAreDefined) { foreach ($row as $columnName => $dummy) { $this -> columnNames[] = $columnName; } $columnsAreDefined = true; } } if (count($this -> records) == 0) { $total_column = $result -> columnCount(); var_dump($total_column); for ($x = 0; $x < $total_column; $x++) { $meta = $result -> getColumnMeta($x); //var_dump($meta); //bool(false) //$column[] = $meta['name']; } } } public function displayHtmlTable() { $r = ''; $r .= '<div class="sqlCommand">' . $this -> sql . '</div>'; $r .= '<table>'; $r .= '<thead>'; $r .= '<tr>'; foreach ($this->columnNames as $columnName) { $r .= '<td>' . $columnName . '</td>'; } $r .= '</tr>'; $r .= '</thead>'; $r .= '<tbody>'; foreach ($this->records as $record) { $r .= '<tr>'; foreach ($record as $data) { $r .= '<td>' . $data . '</td>'; } $r .= '</tr>'; } $r .= '</tbody>'; $r .= '<table>'; return $r; } } ?> </body> </html>
Мета-таблица sqlite_master
содержит всю информацию. Следующий код будет обрабатывать sqlite_master
в именах столбцов в виде $colnames
:
$colnames = array() ; $stmt = $dbh->prepare("SELECT sql FROM sqlite_master WHERE tbl_name = 'put_table_name_here'") ; $stmt->execute() ; $row = $stmt->fetch() ; $sql = $row[0] ; $r = preg_match("/\(\s*(\S+)[^,)]*/", $sql, $m, PREG_OFFSET_CAPTURE) ; while ($r) { array_push( $colnames, $m[1][0] ) ; $r = preg_match("/,\s*(\S+)[^,)]*/", $sql, $m, PREG_OFFSET_CAPTURE, $m[0][1] + strlen($m[0][0]) ) ; }
initialize()
и displayHtmlTable
initializeEmptyResult()
, который выполнит следующий запрос и просто заполнит $this->columnNames[]
: SELECT column_name FROM information_schema.columns WHERE table_name = 'my_table_name'
Запрос зависит от MySQL bu, должно быть больше альтернатив для других баз данных, или все же вы можете запускать DESCRIBE table
и анализировать имена столбцов из результата (должна быть SQL DBMS независящей).
Во-вторых, я думаю, что это легче сделать: если результаты не возвращаются из запроса, не отображаются имена coulmn или таблица вообще, просто выведите сообщение: «Результаты не найдены». Это может быть достигнуто в вашем методе displayHtmlTable
:
public function displayHtmlTable() { $r = ''; $r .= '<div class="sqlCommand">' . $this -> sql . '</div>'; if(count($this->records) > 0) { $r .= '<table>'; $r .= '<thead>'; $r .= '<tr>'; foreach ($this->columnNames as $columnName) { $r .= '<td>' . $columnName . '</td>'; } $r .= '</tr>'; $r .= '</thead>'; $r .= '<tbody>'; foreach ($this->records as $record) { $r .= '<tr>'; foreach ($record as $data) { $r .= '<td>' . $data . '</td>'; } $r .= '</tr>'; } $r .= '</tbody>'; $r .= '<table>'; } else { $r .= '<div class="no-results">No results found for query.</div>'; } return $r; }
И вам не нужно беспокоиться о именах столбцов …
EDIT: для первого случая найден запрос SQLite, который должен делать то же самое, что select * from information_schema.columns where table_name = 'xxx'
:
PRAGMA table_info(table-name);
Просто чтобы увеличить комментарий @shadyyx:
PRAGMA table_info(table-name);
У меня нет песочницы PDO_SQLITE, но с использованием встроенного драйвера SQLite3 этот фрагмент даст вам имена столбцов таблицы table-name в $ arrColumns :
$db = new SQLite3('db.sqlite'); $db->query('PRAGMA table_info(table-name)'); while ($col = $res->fetchArray(SQLITE3_ASSOC)) { $arrColnames[]=$col['name']; } print_r($arrColnames);