私がやりたいのは、テーブルが存在するかどうかを確認することだけで、それを理解することができません。
私はもう試した:
_for ($r = 0; $r < count($tableArray); $r++) {
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query = "select * from `#__".$tableArray[$r]."` LIMIT 1";
$db->setQuery($query);
if ($db->setQuery($query) !== False) {
$results = $db->loadAssocList();
echo "<br>".$tableArray[$r]."table found";
} else {
echo "<br>".$tableArray[$r]."table NOT found";
}
}
_
また、反復可能なJoomlaテーブル名の配列を取得しようとしました。
_Array('table1','table2','table3' etc
_
_SHOW TABLES
_でこれを行うことができますが、これにより、それぞれ1つのエントリを持つ配列の大きな配列が生成されます。
最後に私がやったことを含めています。どちらの回答も役に立ちました。
テーブルの配列を取得するためにこれを行いました:
_$db = JFactory::getDbo();
$results = $db->setQuery('SHOW TABLES')->loadColumn();
_
次に、in_array()
を使用して、探していたテーブルがそこにあるかどうかを確認しました。
_$prefix = $db->getPrefix();
for ($r = 0; $r < count($tableArray); $r++) {
if (in_array($prefix.$tableArray[$r], $results)) {
echo "<br>Found ".$tableArray[$r];
}else{
echo "<br>Missing ".$tableArray[$r];
}
}
_
_$tableArray
_は、チェックするテーブル名を保持する配列です。
_SHOW TABLES
_を使用すると、loadColumn()
で結果を読み込み、テーブル名を値として含む単純な配列を受け取ります。
_print_r(JFactory::getDbo()->setQuery('SHOW TABLES')->loadColumn());
_
出力:
_Array
(
[0] => tbl_assets
[1] => tbl_associations
[2] => tbl_banner_clients
[3] => tbl_banner_tracks
[4] => tbl_banners
...
)
_
あなたをつまずきそうなのは、あなたの_$tableArray
_にプレフィックスがないことです。 FROM
句でテーブル名の前に_#__
_を追加するため、これはクエリで明らかです。結果セットはレンダリングされたプレフィックスとテーブル名を配信するため、入力配列の値は結果セットの値と一致しません。
*重要:ベストプラクティスの問題として、データベースクエリの反復を常に回避するようにしてください。複数のクエリを不必要に実行すると、システムの負荷は言うまでもなく、ページの読み込みが遅くなります。
私は私のローカルホストで成功するために以下をテストしました。これは完全に動的になるように作成しました(データベース名やテーブルのプレフィックスをハードコーディングしないでください)。
結果セットのテーブル名をフィルタリングしたくない場合は、これを使用できます。
_$db = JFactory::getDbo();
$results = $db->setQuery('SHOW TABLES')->loadColumn();
$prefix = $db->getPrefix();
foreach ($tableArray as $t) {
echo "<br>" , (in_array($prefix.$t, $results) ? "Found " : "Missing ") , $t;
}
_
それ以外の場合は、クエリロジックを拡張して結果セットをフィルタリングできます。
コード:
_$tableArray = ["banners", "content", "cucumbers"];
try {
$db = JFactory::getDbo();
$config = JFactory::getConfig();
$dbname = $config->get('db');
$prefix = $db->getPrefix();
foreach ($tableArray as $t) {
$q_tablenames[] = $db->q($prefix.$t); // prefix and quote-wrap for the query
}
$query = $db->getQuery(true)
->select("SUBSTRING(table_name, 7)")
->from("information_schema.tables")
->where(["table_schema = " . $db->q($dbname), "table_name IN (" . implode(',', $q_tablenames) . ")"]);
// echo $query->dump(); // never show to public
$db->setQuery($query);
$found = $db->loadColumn();
foreach ($tableArray as $tablename) {
echo "<div>$tablename table " , (in_array($tablename, $found) ? "" : "not ") , "found</div>";
}
} catch (Exception $e) {
JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error'); // never show actual error to public
}
_
出力:
_banners table found
content table found
cucumbers table not found
_
より詳細なクエリを使用している理由は、実際にはneedを抽出していないためですeveryデータベースからテーブル名--に存在するものだけが必要です配列。これは、マイクロ最適化ではなく、「直接コーディングの意図」に関するものです(これについては、ベンチマークを行いません)。
_$tableArray
_値にはプレフィックスが事前に適合されていないため、IN
データにはプレフィックスが付けられます。 SELECT
は、foreach()
ループでの単純な比較のためにプレフィックスを削除します。
以下は、同じ結果を達成する_SHOW TABLES
_を使用した代替アプローチです。
_$tableArray = ["banners", "content", "cucumbers"];
try {
$db = JFactory::getDbo();
$config = JFactory::getConfig();
$dbname = $config->get('db');
$prefix = $db->getPrefix();
foreach ($tableArray as $t) {
$q_tablenames[] = $db->q($prefix . $t); // prefix and quote-wrap for the query
}
$db->setQuery("SHOW TABLES FROM " . $db->qn($dbname) . " WHERE " . $db->qn("Tables_in_$dbname") . " IN (" . implode(',', $q_tablenames) . ")");
$found = $db->loadColumn();
foreach ($tableArray as $tablename) {
echo "<div>$tablename table " , (in_array($prefix.$tablename, $found) ? "" : "not ") , "found</div>";
}
} catch (Exception $e) {
JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error'); // never show to public
}
_