web-dev-qa-db-ja.com

外部SQL DBからのフィールドを値として配列として表示する

このようなSQLデータセットを用意してください。

    Title   Author  Device1 Device2 Device3
    Title1  j cool  inputA  inputA  inputB
    Title2  l maker inputA  inputB  inputC
    Title3  m smith inputB  inputB  inputB

このように表示したいです。

    Title   Author  header1 header2 header3
    Title1  j cool  inputA: inputB:
                    Device1 Device3
                    Device2 
    Title2  l maker inputA: inputB: inputC:
                    Device1 Device2 Device3
    Title3  m smith inputB:
                    Device1
                    Device2
                    Device3

wpdb に変換するには、テーブル内のHTMLとともに、次のphpを使用します。

    $sqlSelect = "SELECT * FROM titles WHERE `active` = 0 ORDER BY author, title";
    $myquery = $mysqli->query ($sqlSelect);
    if ($myquery = $mysqli->query ($sqlSelect)) {
      $result = array();
      while($row = mysqli_fetch_assoc($myquery)){
        $tmp = array();
        foreach (array('device1', 'device2', 'device3', 'device4') as $key) {
          if (!isset($tmp[$row[$key]])) $tmp[$row[$key]] = array();
          $tmp[$row[$key]][] = $key;
        }
        $result[$row['title'] . "</td><td>" . $row['author']] = $tmp;
       }

      $max = 0;
      foreach ($result as $data => $inputs) {
        $max = max($max, count($inputs));
      }
      // looping rows begins here
      foreach ($result as $data => $inputs) {
        print('<tr><td>' . $data . '</td>');
        foreach ($inputs as $input => $devices) {
          print('<td>' . $input . ':<br/>' . implode('<br/>', $devices) . '</td>');
        }
    //next two lines are for displaying no cells where there is no $data
        for ($i = 0; $i < $max - count($inputs); ++$i) {
          print('<td class="db"></td>');
        }

        print('</tr>');

これを試してみました:

    $mydb = new wpdb('user','password','database','server');
    $results = $mydb -> get_results("SELECT * FROM titles WHERE `active` = 1 ORDER BY author, title");
    $result = array();
    while ($result = $row) { //this doesn't work; and only one row without data except all devices displays without it 
        $tmp = array(); //ditto to the end

WordPressは$dataが好きではないようです。 wpdbでこれを行う方法はありますか?

1
motorbaby

あなたのテーブルがWordpressデータベースにあるのでなければ、私はこれにwpdbを使う理由がないと思います。また、結果のフェッチと変換のためのこの配列の処理を最終的なhtml出力の生成から分離すると、コードがはるかに明確になります(したがって、エラーが発生しにくくなります)。プレゼンテーションからロジックを分離します。

そこで、まず標準的な方法ですべてのデータを配列に入れます。

$query = ("SELECT * FROM titles WHERE `active` = 0 ORDER BY author, title");
$results_array = array();
$result = $mysqli->query($query);
while ($row = $result->fetch_assoc()) {
  $results_array[] = $row;
}

この配列の最初の行、たとえば$results_array[0]は、配列('Title' => 'Title 1','Author' => 'j cool', 'Device1' => 'inputA',...)になります。

編集:あるいは、wpdbクラスを使用したい場合は、上記のコードを次のように置き換えます。

$mydb = new wpdb('user','password','database','server');
$results_array = $mydb->get_results("SELECT * FROM titles WHERE `active` = 0 ORDER BY author, title",ARRAY_A);

$results_arrayは両方のアプローチで同じ内容を持ちます。残りのコードは変わりません。

編集終了

$results_arrayから、各Authorに、デバイスへのテーブルマッピング入力を関連付ける連想配列を取得します。

array('j cool' => array('inputA' => array('Device1', 'Device2'),
                        'inputB' => array('Device3')),
      'l maker' => array('inputA' => array('Device1'),
                        'inputB' => array('Device2'),
                        'inputC' => array('Device3')),
       'm this' => ...)

次のコードは、あなたが入力のすべての可能な値を前もって知っていて、そしてこれらが作者またはタイトルと正確に一致しないと仮定します。

 $inputs = array('inputA','inputB','inputC');

 $input_table = array();

 foreach ($results_array as $row) {
   $row_inputs = array();
   foreach ($inputs as $in) {
      //get all keys (devices) in $row  that have input $in as value
      $devices = array_keys($row,$in); 
      if (!empty($devices))
        $row_inputs[$in] = $devices;
   }
   $input_table[$row['Author']] = $row_inputs;
 }

これは、作者によってインデックスされた各行が上の例のような配列である配列を生成します。今タイトルを追加します。

$final_table = array();
foreach ($results_array as $row) {
  $final_table[] = array('Title' => $row['Title'],
                       'Author' => $row['Author'],
                       'Inputs' => $input_table[$row['Author']]);
}

最後に、結果の配列をhtmlで表示します。

$html = '';
//$html .= '<html><body>';
$html .= "<table>"; //add here code for table headers too

foreach ($final_table as $row) {
  //first row for author
  $html .= '<tr><td>'. $row['Title'] . '</td><td>' . $row['Author'] . '</td>';
  foreach (array_keys($row['Inputs']) as $in) {
    //output input names for this author
    $html .= '<td>'.$in.'</td>';
  }
  $html .= '</tr><td></td><td></td>';
  //second row for author, starting in third column
  foreach ($row['Inputs'] as $in => $devices) {
    $html .= '<td>'.implode(" ",$devices).'</td>';
  }
  $html .= '</tr>';
}

$html .= '</table>';
// $html .= </body></html>
echo $html;

好みに合わせてプレゼンテーションを微調整してください。

1
adelval

WP DB Driverプラグインをインストールし、wpdbを完全にスキップすることでうまくいきました。ただし、ページはヘッダーとフッターのテンプレートしか取得できません。 mysqliクエリはWordPressコーデックスと互換性がないようです。

0
motorbaby