Форматирование результатов запроса MySQL, как если бы он запускался с консоли
Я пишу быстрый и грязный отчет script, который запрашивает отчет и отправляет результаты по электронной почте. При использовании консоли MySQL результаты находятся в хорошо отформатированной таблице:
mysql> select * from users;
+-----------+------------+-------+
| firstname | city | zip |
+-----------+------------+-------+
| Maria | Holland | 12345 |
| Rene | Doylestown | 65432 |
| Helen | Conway | 98745 |
+-----------+------------+-------+
3 rows in set (0.01 sec)
Есть ли простой способ реплицировать это форматирование при получении результатов с помощью PHP? Очевидно, я мог бы добиться этого, написав собственный форматировщик отчетов, но я надеялся, что что-то немного более элегантное.
Ответы
Ответ 1
Вы могли бы сделать это довольно легко, используя Console_Table пакет PEAR. Просто запустите свои результаты MySQL и добавьте строки в таблицу. Вы можете использовать метод Console_Table::setHeaders()
, чтобы добавить заголовки для своих столбцов, затем метод Console_Table::addRow()
для добавления каждой строки и, наконец, Console_Table::getTable()
, чтобы отобразить его.
Для PHP ничего не встроено в PHP. Если вы не хотите использовать/писать код для рисования консольных таблиц, просто передайте -e query
в mysql через PHP, используя passthru()
. Это будет работать с запросами, завершенными как с ;
, так и \G
:
passthru("mysql -e '$query;' database_name");
Ответ 2
Вы должны сделать это сами.
выполните цикл, чтобы найти максимальный размер для каждого столбца. Затем выводите каждое дополнение строки до этого размера +2 с пространством в начале и конце. разделите каждый столбец на |.
Используйте + и - для создания верхнего и нижнего.
Трудно дать конкретный пример, не зная, что вы используете, чтобы получить ваши результаты. Но предположим, что вы используете mysql_query. Вот пример.
$conn = mysql_connect("localhost", "mysql_user", "mysql_password");
mysql_select_db("mydbname");
$result = mysql_query("SELECT * FROM myTable");
//first get your sizes
$sizes = array();
$row = mysql_fetch_assoc($result);
foreach($row as $key=>$value){
$sizes[$key] = strlen($key); //initialize to the size of the column name
}
while($row = mysql_fetch_assoc($result)){
foreach($row as $key=>$value){
$length = strlen($value);
if($length > $sizes[$key]) $sizes[$key] = $length; // get largest result size
}
}
mysql_data_seek($result, 0); //set your pointer back to the beginning.
//top of output
foreach($sizes as $length){
echo "+".str_pad("",$length+2,"-");
}
echo "+\n";
// column names
$row = mysql_fetch_assoc($result);
foreach($row as $key=>$value){
echo "| ";
echo str_pad($key,$sizes[$key]+1);
}
echo "|\n";
//line under column names
foreach($sizes as $length){
echo "+".str_pad("",$length+2,"-");
}
echo "+\n";
//output data
do {
foreach($row as $key=>$value){
echo "| ";
echo str_pad($value,$sizes[$key]+1);
}
echo "|\n";
} while($row = mysql_fetch_assoc($result));
//bottom of output
foreach($sizes as $length){
echo "+".str_pad("",$length+2,"-");
}
echo "+\n";
Это сделало бы (надеюсь, я не пропустил точку с запятой):).
Надеюсь, что это поможет!
Ответ 3
Вы можете использовать exec или backticks и фактически запускать его из командной строки через php. По-видимому, в команде mysql есть ключ -H, который вы можете использовать, и он будет выводить HTML-формат. Однако не пробовал, но это тоже может показаться хорошим.
echo '<pre>';
echo `mysql -u user -ppass -e "select * from table;" database_name`;
2 строки, не грушевые пакеты, насколько более элегантным он может получить для быстрой и грязной страницы статистики.
Ответ 4
Я оптимизировал ответ @ehudokai, поэтому он использует меньше циклов (5 против 9). И для полноты я добавил также командную строку, статистику и вывод ошибок:
<pre>
<?php
$db = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
$start = microtime(true);
$sql = "SELECT * FROM myTable";
$result = mysqli_query($db, $sql);
$exec_time = microtime(true) - $start;
// obtain the maximum string length of all column headings and rows
$colwidths = array();
while ($row = mysqli_fetch_assoc($result)) {
foreach ($row as $key => $value) {
// heading
if (!isset($colwidths[ $key ])) {
$colwidths[ $key ] = strlen($key) + 2;
}
// rows
$colwidths[ $key ] = max($colwidths[ $key ], strlen($value) + 2);
}
}
echo 'mysql>' . trim($sql) . PHP_EOL;
// SELECT, SHOW, DESCRIBE, EXPLAIN = resource
// INSERT, UPDATE, DELETE, DROP = true
// Error = false
if (!is_bool($result)) {
if ($colwidths) {
mysqli_data_seek($result, 0);
while ($row = mysqli_fetch_assoc($result)) {
// create and display horizontal line and column headings
if (!isset($header)) {
$header = '| ';
$line = '+';
foreach ($row as $key => $value) {
$line .= str_repeat('-', $colwidths[ $key ] + 2) . '+';
$header .= str_pad($key, $colwidths[ $key ]) . ' | ';
}
echo $line . PHP_EOL;
echo $header . PHP_EOL;
echo $line . PHP_EOL;
}
// display row values
foreach ($row as $key => $value) {
echo '| ' . str_pad($value, $colwidths[ $key ] + 1);
}
echo '|' . PHP_EOL;
}
echo $line . PHP_EOL;
}
mysqli_free_result($result);
}
$affectedrows = mysqli_affected_rows($db);
if ($result === false) {
echo PHP_EOL . 'ERROR ' . mysqli_errno($db) . ': ' . mysqli_error($db);
}
else if ($result === true) {
echo 'Query OK, ' . $affectedrows . ' rows affected (' . round($exec_time / $iterations * 1000) . ' ms)';
}
else if ($affectedrows) {
echo $affectedrows . ' rows in set (' . round($exec_time / $iterations * 1000) . ' ms)';
}
else {
echo 'Empty set (' . round($exec_time / $iterations * 1000) . ' ms)';
}
?>
</pre>
<сильные > Примеры
SELECT
mysql>SELECT
topic_id,
MATCH(text) AGAINST('tuning') AS score
FROM
topics
WHERE
MATCH(text) AGAINST('tuning' IN BOOLEAN MODE)
ORDER BY
score DESC
LIMIT 10
+----------+--------------------+
| topic_id | score |
+----------+--------------------+
| 153257 | 5.161948204040527 |
| 17925 | 4.781417369842529 |
| 66459 | 4.648380279541016 |
| 373176 | 4.570812702178955 |
| 117173 | 4.55166482925415 |
| 167016 | 4.462575912475586 |
| 183286 | 4.4519267082214355 |
| 366132 | 4.348565101623535 |
| 95502 | 4.293642520904541 |
| 29615 | 4.178250789642334 |
+----------+--------------------+
10 rows in set (141 ms)
Ошибка:
mysql>SELECT * WHERE 1=1
ERROR 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE 1=1' at line 1
ОБНОВЛЕНИЕ
mysql>UPDATE topics_search SET topic_id = topic_id WHERE topic_id = 2
Query OK, 0 rows affected (0 ms)
Ответ 5
На основе ответа mfonda вы можете легко загрузить Console_Table pear package с композитором: https://packagist.org/packages/pear/console_table
$ composer require pear/console_table
<?php
//Suppress E_DEPRECATED errors for statically calling a non-static method (this package is pretty old!)
error_reporting(E_ALL & ~E_DEPRECATED);
require __DIR__ . '/vendor/autoload.php';
//echo "<pre>"; #uncomment this line if running script in a browser
//The class isn't namespaced so just call it directly like so:
echo Console_Table::fromArray(
['column', 'headings'],
[
['1st row', 'values'],
['2nd row', 'values'],
['...', '...']
]
);
Выводится:
+---------+----------+
| column | headings |
+---------+----------+
| 1st row | values |
| 2nd row | values |
| ... | ... |
+---------+----------+
Ответ 6
Это не имеет никакого отношения к тому, как вы извлекаете данные из MySQL в PHP. (т.е. вы обычно выбираете строку данных в каждый момент времени либо как массив (mysql_fetch_array), либо объект (mysql_fetch_object).
Таким образом, вам нужно будет написать свой собственный взлом, чтобы захватить все строки и форматировать вывод таким образом. (Тем не менее, должно быть тривиально захватывать данные и выводить их как таблицу HTML - вы можете получить имена полей через array_keys, если вы используете mysql_fetch_array и т.д.)
Ответ 7
похоже, что вам просто нужно использовать любой из методов exec или backticks. Я не уверен насчет '\ G' thingy... но я опубликовал php-функцию, называемую query2Table() несколько месяцев назад @http://www.logicwizards.net/php-query2table - на основе функции, которую я перерабатывал в течение многих лет. У меня есть куча, накопленная за эти годы: query2xml, query2excel, query2json и т.д. Я думаю, что у меня все еще есть старые версии perl и asp.
В основном, в моем решении вы можете просто передать ему строку запроса, и она динамически выплевывает таблицу html, используя имена столбцов, полученные из результатов в виде строки заголовка таблицы. Он также растет, чтобы заполнить ширину унаследованного объекта контейнера.
query2table("select * from table;");
У меня есть более современная версия query2AjaxTable(), которая хорошо переносит все в классе и добавляет сортировку и анимацию jQuery - но она еще не готова к публикации.
Если моя глупая маленькая функция не поможет вам, в вашей дилемме, может быть, кто-то другой найдет ее полезной...