かつて同様のテーブルがあり、SQLを使用してデータを個々の行として返すことになりました。SQLを使用するようにオブジェクトを変更し、質問で使用した形式に従ってテーブルにデータを出力する単純な関数を作成しました。
私が使用した主なクエリ集計関数は、MySQLGROUP_CONCATです。これはimplode()
関数に似ています。デフォルトの区切り文字はコンマであるため、メタデータにコンマがある場合はSEPARATOR 'yourSeparator'
、列名の後に角かっこ内を追加することで、別のマーカーに変更できます。distinct
列名の前を使用して、group_concat内の個別の行のみを選択することもできます。
ステートメント内にテーブルヘッダーセクションを配置したtry
ので、結果がない場合は、半分生成されたテーブルが表示されません。
<?php
class myUser
{
public $ID;
public $name;
public $metas;
}
class myTables
{
public $SQL="
select
ID,
name,
GROUP_CONCAT(metavalue) as metas
FROM
table1
GROUP BY
ID,
name;";
public function outputTable()
{
$hostname="mysql:host=localhost;dbname=test";
$username="testdb";
$password="testdbpassword";
try{
echo "
<table>
<thead>
<th>Name</th>
<th>MetaValue</th>
</thead>
<tbody>
";
$dbh = new PDO($hostname, $username, $password);
$stmt = $dbh->query($this->SQL);
$obj = $stmt->setFetchMode(PDO::FETCH_INTO, new myUser);
foreach($stmt as $myUser)
{
echo "
<tr><td>".$myUser->name."</td><td><ul>";
$metas=explode(",", $myUser->metas);
for($i=0;$i<count($metas);$i++)
{
echo "<li>".$metas[$i]."</li>";
}
echo "</ul></td></tr>";
}
unset($obj);
unset($stmt);
unset($dbh);
echo "
</tbody>
</table>
";
}
catch(PDOException $e){
echo 'Error : '.$e->getMessage();
exit();
}
}
}
$myPage= new myTables();
$myPage->outputTable();
?>
出力例:
<table>
<thead>
<th>Name</th>
<th>MetaValue1</th>
</thead>
<tbody>
<tr><td>Rose</td><td><ul><li>Drinker</li><li>Nice Person</li><li>Runner</li></ul></td></tr>
<tr><td>Gary</td><td><ul><li>Player</li><li>Funny</li></ul></td></tr>
</tbody>
</table>
Autonum
集計関数をバグしているので、クエリからを切り取りました。ただし、それが必要な場合は、同様の方法で集約する必要があります。このgroup_concat
関数はnullフィールドをスキップするため、巧妙にそれらを取り込む必要があります。そうしないと、autonumIDが結果と一致しません。ここでは、関数coalesce()
内の単純なものを使用してこれを行いました。group_concat
これらの余分なビットに対応するために、オブジェクトを少し書き直しました。これで必要なすべてが実行されます。falseに設定したプライベート変数によって設定されるデバッグノートを残しましたが、isDebug
trueに設定すると、オブジェクトが関数を実行するときに追加情報が得られます。ソースデータは実際にははるかに複雑であると私は思うので、これはデバッグに役立ちます。
<?php
class myUser
{
public $ID;
public $name;
public $metaDesc;
public $metaNum;
public $metaDescs;
public $metaNums;
}
// Basic User stored here. One Object per Row is created.
class myTables
{
private $isDebug=false; // Change this to true to get all validation messages;
private $hostname="mysql:host=localhost;dbname=test";
private $username="testdb";
private $password="testdbpassword";
private $myUsers=array();
private $curUser = myUser;
private $userCount=0;
private $SQL="
select
ID,
name,
GROUP_CONCAT(coalesce(metavalue,'null')) as metaDesc,
group_concat(autonum) as metaNum
FROM
table1
GROUP BY
ID,
name;";
public function getuserData()
{
$dbh = new PDO($this->hostname, $this->username, $this->password);
$stmt = $dbh->query($this->SQL);
$obj = $stmt->setFetchMode(PDO::FETCH_INTO, new myUser);
$userCount=0;
foreach($stmt as $myUser)
{
$this->myUsers[$userCount]=new myUser;
$this->myUsers[$userCount]->ID=$myUser->ID;
$this->myUsers[$userCount]->name=$myUser->name;
$this->myUsers[$userCount]->metaDesc=$myUser->metaDesc;
$this->myUsers[$userCount]->metaNum=$myUser->metaNum;
$userCount++;
}
$this->userCount=$userCount;
if($this->isDebug){echo "There are ".$this->userCount." users found.<br>";}
unset($obj);
unset($stmt);
unset($dbh);
}
// Pulls the data from the database and populates the this->object.
public function outputTable()
{
echo "
<table>
<thead>
<th>Name</th>
<th>MetaValue</th>
</thead>
<tbody>
";
for($i=0; $i<$this->userCount; $i++)
{
if($this->isDebug){echo "Running main cycle. There are ".$this->userCount." elements.";}
$this->myUsers[$i]->metaDescs=explode(',', $this->myUsers[$i]->metaDesc);
$this->myUsers[$i]->metaNums=explode(',', $this->myUsers[$i]->metaNum);
if($this->isDebug){echo "This user has ".(count($this->myUsers[$i]->metaDescs))." segments<br>";}
if($this->isDebug){echo "My first segment is ".($this->myUsers[$i]->metaDesc)."<br>";}
echo "<tr><td>".$this->myUsers[$i]->name."</td><td><ul>";
for($j=0;$j<count($this->myUsers[$i]->metaDescs);$j++)
{
echo "<li>ID: ".$this->myUsers[$i]->metaNums[$j]." - ".$this->myUsers[$i]->metaDescs[$j]."</li>";
}
echo "</ul></td></tr>";
}
echo "
</tbody>
</table>
";
}
// Outputs the data held in the object into the table as required.
}
$myPage= new myTables();
$myPage->getUserData();
$myPage->outputTable();
?>
出力は次のようになります。
<table>
<thead>
<th>Name</th>
<th>MetaValue</th>
</thead>
<tbody>
<tr><td>Rose</td><td><ul><li>ID: 1 - Drinker</li><li>ID: 2 - Nice Person</li><li>ID: 3 - Runner</li></ul></td></tr>
<tr><td>Gary</td><td><ul><li>ID: 4 - Player</li><li>ID: 5 - Funny</li><li>ID: 6 - null</li><li>ID: 7 - Smelly</li></ul></td></tr>
</tbody>
</table>
Name MetaValue
Rose
ID: 1 - Drinker
ID: 2 - Nice Person
ID: 3 - Runner
Gary
ID: 4 - Player
ID: 5 - Funny
ID: 6 - null
ID: 7 - Smelly