2011-01-04 23 views
12

Tôi đang viết một tập lệnh báo cáo nhanh chóng và dơ bẩn truy vấn báo cáo và gửi email kết quả. Khi sử dụng bảng điều khiển MySQL, các kết quả nằm trong một bảng được định dạng độc đáo:Định dạng kết quả của truy vấn MySQL như thể nó đã được chạy từ bảng điều khiển

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

Có cách nào dễ dàng để sao chép định dạng này khi tìm nạp kết quả bằng PHP không? Rõ ràng tôi có thể đạt được điều này bằng cách viết trình định dạng báo cáo của riêng tôi nhưng tôi đã hy vọng cho một điều gì đó thanh lịch hơn một chút.

+0

Không, bạn phải định dạng nó bản thân bạn. Khi bạn nhận được kết quả cho mysql của bạn không sử dụng máy khách mysql, bạn đang sử dụng php và các thư viện mysql. Định dạng được thực hiện bởi ứng dụng dòng lệnh. Nếu bạn muốn có cùng một định dạng, bạn sẽ phải tự làm điều đó. Nếu bạn muốn giúp đỡ làm điều đó, nó không nên quá khó – ehudokai

+0

@ehudokai Tôi hiểu sự khác biệt từ thư viện mysql của PHP và giao diện điều khiển. Tôi đã thực sự hy vọng cho một cái gì đó thông minh hơn. –

+0

Tôi hiểu :) Tôi đã viết ra những gì sẽ cần phải được thực hiện trong câu trả lời của tôi, nhưng nếu bạn không nhớ mô-đun PEAR Console_Table rằng @ mfonda đã đề cập có vẻ như nó làm điều tương tự. – ehudokai

Trả lời

12

Bạn có thể thực hiện việc này khá dễ dàng bằng cách sử dụng gói PEAR Console_Table. Chỉ cần lặp qua các kết quả MySQL của bạn và thêm các hàng vào bảng của bạn. Bạn có thể sử dụng phương thức Console_Table::setHeaders() để thêm tiêu đề cho các cột của mình, sau đó là phương thức Console_Table::addRow() để thêm từng hàng và cuối cùng là Console_Table::getTable() để hiển thị tiêu đề.

Không có gì được tích hợp vào PHP để thực hiện việc này. Nếu bạn không muốn sử dụng/viết mã để vẽ bảng điều khiển, chỉ cần chuyển -e query đến mysql qua PHP bằng cách sử dụng passthru(). Điều này sẽ làm việc truy vấn chấm dứt với cả ;\G:

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

Điều này không có ý nghĩa gì trong việc ghi nhớ cách thức bạn tìm nạp dữ liệu từ MySQL trong PHP. (ví dụ: Bạn thường tìm nạp hàng dữ liệu trên cùng một lúc hoặc dưới dạng mảng (mysql_fetch_array) hoặc một đối tượng (mysql_fetch_object).)

Như vậy, bạn cần phải viết hack của riêng mình để lấy tất cả các hàng và định dạng đầu ra theo cách này. (Điều đó nói rằng, nó phải là tầm thường để lấy dữ liệu và đầu ra nó như một bảng HTML - bạn có thể nhận được các tên trường qua array_keys nếu bạn sử dụng mysql_fetch_array, vv)

+0

Cảm ơn bạn đã phản hồi. Tôi nhận thức được tất cả các phương pháp tìm nạp và tôi không nghi ngờ khả năng của mình để đưa ra một trình định dạng bảng mô phỏng giao diện điều khiển. Tôi thực sự đang tìm kiếm một giải pháp nhẹ, được xây dựng sẵn có nguồn gốc từ MySQL hoặc PHP. Nếu một tùy chọn như vậy không tồn tại, tôi sẽ hài lòng với câu trả lời đó :) –

3

Bạn có thể sử dụng hoặc backticks exec và thực sự chạy nó từ dòng lệnh thông qua php. Rõ ràng lệnh mysql có một chuyển đổi -H bạn có thể sử dụng, và nó sẽ xuất ra định dạng HTML. Đã không thử nó mặc dù, nhưng điều đó có thể nhìn tốt quá.

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

2 dòng, không có gói lê, số trang thanh lịch nhanh hơn và bẩn hơn bao nhiêu.

5

Bạn phải làm điều đó cho mình.

thực hiện vòng lặp để tìm kích thước tối đa cho mỗi cột. Sau đó, xuất mỗi hàng đệm thành kích thước đó +2 với khoảng trắng ở đầu và cuối. tách riêng từng cột bằng |

Sử dụng + và - để tạo trên cùng và dưới cùng của bạn.

Thật khó để đưa ra một ví dụ cụ thể mà không biết bạn đang sử dụng gì để có được kết quả của mình. Nhưng giả sử bạn đang sử dụng mysql_query. Đây là một ví dụ.

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

Điều đó sẽ làm điều đó (Tôi hy vọng tôi không bỏ lỡ dấu chấm phẩy trong đó :)).

Hy vọng điều đó sẽ hữu ích!

+0

Nếu tôi chấm dứt truy vấn bằng \ G thì sao? Đầu ra thay đổi hoàn toàn từ kiểu bảng thành kiểu dọc. Tôi thực sự, thực sự không muốn viết trình định dạng của riêng tôi vì MySQL thực hiện công việc rất tốt. –

+0

@mikeB, nếu bạn muốn mysql, chỉ cần sử dụng mysql. Bạn có thể chạy mysql từ exec như những người khác đã nói. – ehudokai

0

có vẻ như bạn chỉ cần sử dụng bất kỳ một trong các phương pháp exec hoặc backticks. Tôi không chắc chắn về '\ G' thingy ... nhưng, tôi đã xuất bản một hàm php gọi là query2Table() cách đây vài tháng @http://www.logicwizards.net/php-query2table - dựa trên chức năng tôi đã tái chế trong nhiều năm. Tôi có một bó mà tôi đã tích luỹ qua nhiều năm: query2xml, query2excel, query2json, v.v.Tôi nghĩ rằng tôi vẫn còn có perl cũ & asp phiên bản một nơi nào đó, quá. Về cơ bản, trong giải pháp của tôi, bạn chỉ có thể vượt qua nó chuỗi truy vấn và nó tự động nhổ ra một bảng html bằng cách sử dụng tên cột được lấy từ kết quả dưới dạng hàng tiêu đề của bảng. Nó cũng phát triển để lấp đầy chiều rộng của đối tượng container được thừa kế của nó.

query2table("select * from table;"); 

Tôi có một nhiều hơn đến nay phiên bản query2AjaxTable() mà kết thúc tốt đẹp tất cả mọi thứ lên độc đáo trong một lớp học và cho biết thêm jQuery sắp xếp & animations - nhưng nó chưa sẵn sàng để công bố được nêu ra.

Nếu chức năng chút ngớ ngẩn của tôi không giúp bạn, trong tình trạng khó xử của bạn, có thể ai đó sẽ tìm thấy nó hữu ích ...

+0

Liên kết không còn hoạt động. –

1

tôi tối ưu hóa the answer of @ehudokai nên sử dụng vòng ít hơn (5 so với 9). Và cho đầy đủ tôi đã thêm dòng lệnh, số liệu thống kê và đầu ra lỗi, quá:

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

Ví dụ

CHỌN

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) 

Lỗi:

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 

CẬP NHẬT

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

Xây dựng về câu trả lời mfonda, bạn có thể thực sự dễ dàng tải các Console_Table pear package với nhà soạn nhạc bây giờ: 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'], 
     ['...', '...'] 
    ] 
); 

này kết quả đầu ra:

+---------+----------+ 
| column | headings | 
+---------+----------+ 
| 1st row | values | 
| 2nd row | values | 
| ...  | ...  | 
+---------+----------+ 
Các vấn đề liên quan