2011-01-04 47 views
12

Estoy escribiendo un script de informes rápido y sucio que consulta un informe y envía un correo electrónico con los resultados. Cuando se utiliza la consola de MySQL son los resultados en una tabla con un formato agradable:Formateo de los resultados de una consulta MySQL como si se hubiera ejecutado desde la consola

mysql> select * from users; 
+-----------+------------+-------+ 
| firstname | city  | zip | 
+-----------+------------+-------+ 
| Maria  | Holland | 12345 | 
| Rene  | Doylestown | 65432 | 
| Helen  | Conway  | 98745 | 
+-----------+------------+-------+ 
3 rows in set (0.01 sec) 

¿Hay una manera fácil de replicar este formato cuando ir a buscar los resultados con PHP? Obviamente, pude lograr esto escribiendo mi propio formateador de informes, pero esperaba algo un poco más elegante.

+0

No, usted tiene que formatearlo tú mismo. Cuando obtienes resultados para mysql no estás usando el cliente mysql, estás usando php y las bibliotecas mysql. El formateo es algo hecho por el cliente de línea de comando. Si quieres el mismo formato, tendrás que hacerlo tú mismo. Si quieres ayuda para hacerlo, no debería ser demasiado difícil – ehudokai

+0

@ehudokai Entiendo las diferencias de las librerías mysql de PHP y la consola. Realmente estaba esperando algo más inteligente. –

+0

Entiendo :) Escribí lo que necesitaría hacer en mi respuesta, pero si no te importa los módulos de PEAR Console_Table que se menciona en @mfonda parece que hace lo mismo. – ehudokai

Respuesta

12

Puede hacer esto fácilmente usando el paquete Console_Table PEAR. Recorra sus resultados de MySQL y agregue filas a su tabla. Puede usar el método Console_Table::setHeaders() para agregar los encabezados de sus columnas, luego el método Console_Table::addRow() para agregar cada fila, y finalmente Console_Table::getTable() para mostrarlo.

No hay nada integrado en PHP para hacer esto. Si no desea utilizar/escribir código para dibujar tablas de consola, simplemente pase -e query a mysql vía PHP usando passthru(). Esto funcionará consultas terminados con tanto ; y \G:

passthru("mysql -e '$query;' database_name"); 
0

Esto no tiene ningún sentido teniendo en cuenta la manera en que se obtienen datos de MySQL en PHP. (Es decir: Por lo general, recupera una fila onw de datos a la vez, ya sea en forma de matriz (mysql_fetch_array) o un objeto (mysql_fetch_object).)

Por lo tanto, lo que se necesita para escribir su propio truco para agarrar todas las filas y formatee la salida de esta manera. (Dicho esto, debería ser trivial obtener los datos y generarlos como una tabla HTML; puede obtener los nombres de los campos a través del array_keys si usa mysql_fetch_array, etc.)

+0

Gracias por la respuesta. Estoy al tanto de todos los métodos de búsqueda y no dudo de mi habilidad para encontrar un formateador de tablas que emule la consola. Realmente estoy buscando una solución ligera y preconstruida nativa de MySQL o PHP. Si tal opción no existe, estaría contento con esa respuesta :) –

3

Puede usar exec o backticks y ejecutarlo desde la línea de comando a través de php. Aparentemente el comando mysql tiene un modificador -H que puede usar, y dará como resultado un formato HTML. Aunque no lo he intentado, también podría verse bien.

echo '<pre>'; 
echo `mysql -u user -ppass -e "select * from table;" database_name`; 

2 líneas, no hay paquetes de PEAR, cuánto más elegante que puede conseguir para una página rápida y estadísticas sucios.

5

que tiene que hacer usted mismo.

haga un ciclo para encontrar el tamaño máximo para cada columna. A continuación, imprima cada relleno de fila a ese tamaño +2 con un espacio al principio y al final. separe cada columna con un |.

Use + y - para crear su parte superior e inferior.

Es difícil dar un ejemplo concreto sin saber lo que está utilizando para obtener sus resultados. Pero suponiendo que estés usando mysql_query. Aquí hay un ejemplo.

$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"; 

Eso lo haría (espero no haber perdido un punto y coma allí :)).

Espero que ayude!

+0

¿Qué pasa si termino una consulta con \ G? La salida cambia completamente del estilo de la mesa al estilo vertical. Realmente, realmente no quiero escribir mi propio formateador ya que MySQL hace un muy buen trabajo. –

+0

@mikeB, si quieres mysql, simplemente usa mysql. Puede ejecutar mysql desde el ejecutivo como otros han dicho. – ehudokai

0

Parece que solo tiene que usar cualquiera de los métodos de ejecución o backticks. No estoy seguro del asunto '\ G' ... pero publiqué una función php llamada query2Table() hace unos meses @http://www.logicwizards.net/php-query2table, basada en una función que he estado reciclando durante años. Tengo un grupo que he acumulado a lo largo de los años: query2xml, query2excel, query2json, etc.Creo que todavía tengo las viejas versiones de asp & en algún lado, también.

Básicamente, en mi solución, puede simplemente pasarle la cadena de consulta y escindir dinámicamente una tabla html utilizando nombres de columna obtenidos de los resultados como la fila de encabezado de la tabla. También crece para llenar el ancho de su objeto contenedor heredado.

query2table("select * from table;"); 

que tienen una más actualizada versión query2AjaxTable() que envuelve todo muy bien en una clase y añade jQuery clasificación & animaciones - pero no está listo para publicar aún.

Si mi función poco tonto no le ayuda, en su dilema, tal vez alguien más le resultará útil ...

+0

El enlace ya no funciona. –

1

optimicé the answer of @ehudokai por lo que utiliza menos bucles (5 frente a 9). Y para la integridad he añadido la línea de comandos, las estadísticas y la salida de error, también:

<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> 

Ejemplos

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) 

error:

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 

ACTUALIZACIÓN

mysql>UPDATE topics_search SET topic_id = topic_id WHERE topic_id = 2 
Query OK, 0 rows affected (0 ms) 
1

Sobre la base de la respuesta de mfonda, realmente se puede cargar fácilmente el Console_Table pear package con el compositor ahora: 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'], 
     ['...', '...'] 
    ] 
); 

Este salidas:

+---------+----------+ 
| column | headings | 
+---------+----------+ 
| 1st row | values | 
| 2nd row | values | 
| ...  | ...  | 
+---------+----------+ 
Cuestiones relacionadas