我想用php检测mysql查询中的所有表。我看到mysql_field_table()函数适用于普通查询。但是当你为表使用替代名称( table_name AS new_name )时,它返回替代名称而不是真实姓名,我怎么用正则表达式修复它。但现在我的问题是现在使用这样的高级查询:
SELECT mail_id, mail_date, mail_from, mail_to, mail_subject, (
(
SELECT COUNT(*)
FROM `sys_messagecenter_qmails`
WHERE qmail_mail_id = mail_id
) + (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
WHERE rel_mail_id = mail_id
)
) AS email_total, (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
WHERE rel_mail_id = mail_id
) AS email_sent, (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
INNER JOIN `sys_email_receives` ON receive_reply_to = rel_sent_id
WHERE rel_mail_id = mail_id
) AS email_reply FROM `sys_messagecenter_emails` WHERE mail_draft='No'
ORDER BY mail_id ASC LIMIT 0,10
现在我想我需要一些正则表达式来检测查询中的所有真实表名。或任何其他完美的解决方案我怎么能这样做?
答案 0 :(得分:2)
$query
中查询)
if(preg_match_all('/((FROM|JOIN) `(.*)`)/', $query, $matches)) {
$tables = array_unique($matches[3]);
print_r($tables);
}
答案 1 :(得分:2)
我还需要从查询中提取表名。然后我编写自己的脚本,它几乎适用于所有基本查询。
$tables = array();
$sql ="SELECT m.`id` FROM my_table m INNER JOIN mytable_2 m2 ON(m.`id` = m2.`m_id`) ";
$query_structure = explode( ' ', strtolower( preg_replace('!\s+!', ' ', $sql) ) );
$searches_from = array_keys( $query_structure , 'from');
$searches_join = array_keys( $query_structure , 'join');
$searches_update = array_keys( $query_structure , 'update');
$searches_into = array_keys( $query_structure , 'into');
$searches = array_merge($searches_join , $searches_from , $searches_update , $searches_into );
foreach($searches as $search ){
if(isset($query_structure[$search+1])){
$tables[] = trim( $query_structure[$search+1] , '` ');
}
}
print_r($tables);
希望这会有所帮助
答案 2 :(得分:0)
这不是最优雅的解决方案,但是已经通过了我到目前为止运行的所有测试:
function get_table_name($query) {
$query = trim(str_replace(PHP_EOL, ' ', $query));
$table = '';
if(strtolower(substr($query, 0, 12)) == 'create table') {
$start = stripos($query, 'CREATE TABLE') + 12;
$end = strpos($query, '(');
$length = $end - $start;
$table = substr($query, $start, $length);
}
elseif(strtolower(substr($query, 0, 6)) == 'update') {
$end = stripos($query, 'SET');
$table = substr($query, 6, $end);
}
elseif(strtolower(substr($query, 0, 11)) == 'alter table') {
$parts = explode(' ', $query);
$table = $parts[2];
}
elseif(strtolower(substr($query, 0, 11)) == 'insert into') {
$parts = explode(' ', $query);
$table = $parts[2];
}
elseif(strtolower(substr($query, 0, 12)) == 'create index') {
$parts = explode(' ', $query);
$table = $parts[4];
}
elseif(strtolower(substr($query, 0, 6)) == 'select') {
$parts = explode(' ', $query);
foreach($parts as $i => $part) {
if(trim(strtolower($part)) == 'from') {
$table = $parts[$i + 1];
break;
}
}
}
elseif(strtolower(substr($query, 0, 29)) == 'create unique clustered index') {
$parts = explode(' ', $query);
$table = $parts[6];
}
elseif(strtolower(substr($query, 0, 22)) == 'create clustered index') {
$parts = explode(' ', $query);
$table = $parts[5];
}
elseif(strtolower(substr($query, 0, 15)) == 'exec sp_columns') {
$parts = explode(' ', $query);
$table = str_replace("'", '', $parts[2]);
}
elseif(strtolower(substr($query, 0, 11)) == 'delete from') {
$parts = explode(' ', $query);
$table = str_replace("'", '', $parts[2]);
}
return trim(str_replace(['`', '[', ']'], ['', '', ''], $table));
}
答案 3 :(得分:0)
我使用下面的代码(a与var_dump等效):
/**
* Only works if the table names and database names don't have a space or a dot in them.
*/
$queries = [
"select * from my_table",
"select * from `my_table`",
"select * from my_db.my_table",
"select * from my_db.`my_table`",
"select id from my_table where x=2",
"select id from my_table mt inner join other_table ot on ot.my_table_id=mt.id where mt.x=2",
"SELECT mail_id, mail_date, mail_from, mail_to, mail_subject, (
(
SELECT COUNT(*)
FROM `sys_messagecenter_qmails`
WHERE qmail_mail_id = mail_id
) + (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
WHERE rel_mail_id = mail_id
)
) AS email_total, (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
WHERE rel_mail_id = mail_id
) AS email_sent, (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
INNER JOIN `sys_email_receives` ON receive_reply_to = rel_sent_id
WHERE rel_mail_id = mail_id
) AS email_reply FROM `sys_messagecenter_emails` WHERE mail_draft='No'
ORDER BY mail_id ASC LIMIT 0,10 ",
"select count(*) as count from (
select
user_id,
permission_group_id,
concat(uhpg.user_id, '. ', u.pseudo) as user_id_plus,
concat(uhpg.permission_group_id, '. ', pg.name) as permission_group_id_plus
from lud_user_has_permission_group uhpg
inner join lud_user u on uhpg.user_id=u.id
inner join lud_permission_group pg on uhpg.permission_group_id=pg.id
) as ttt",
];
$tables = [];
foreach ($queries as $query) {
a($query);
if (preg_match_all('!((FROM|JOIN)\s([\S]+))!i', $query, $matches)) {
$tables = array_unique($matches[3]);
array_walk($tables, function (&$v) {
$p = explode('.', $v, 2);
$v = array_pop($p);
$v = trim($v, '`');
});
$tables = array_filter($tables, function ($v) {
return ('(' !== $v);
});
a($tables);
}
}
哪个给出以下输出:
string(22) "select * from my_table"
array(1) {
[0] => string(8) "my_table"
}
string(24) "select * from `my_table`"
array(1) {
[0] => string(8) "my_table"
}
string(28) "select * from my_db.my_table"
array(1) {
[0] => string(8) "my_table"
}
string(30) "select * from my_db.`my_table`"
array(1) {
[0] => string(8) "my_table"
}
string(33) "select id from my_table where x=2"
array(1) {
[0] => string(8) "my_table"
}
string(89) "select id from my_table mt inner join other_table ot on ot.my_table_id=mt.id where mt.x=2"
array(2) {
[0] => string(8) "my_table"
[1] => string(11) "other_table"
}
string(810) "SELECT mail_id, mail_date, mail_from, mail_to, mail_subject, (
(
SELECT COUNT(*)
FROM `sys_messagecenter_qmails`
WHERE qmail_mail_id = mail_id
) + (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
WHERE rel_mail_id = mail_id
)
) AS email_total, (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
WHERE rel_mail_id = mail_id
) AS email_sent, (
SELECT COUNT(*)
FROM `sys_messagecenter_rels`
INNER JOIN `sys_email_receives` ON receive_reply_to = rel_sent_id
WHERE rel_mail_id = mail_id
) AS email_reply FROM `sys_messagecenter_emails` WHERE mail_draft='No'
ORDER BY mail_id ASC LIMIT 0,10 "
array(4) {
[0] => string(24) "sys_messagecenter_qmails"
[1] => string(22) "sys_messagecenter_rels"
[4] => string(18) "sys_email_receives"
[5] => string(24) "sys_messagecenter_emails"
}
string(360) "select count(*) as count from (
select
user_id,
permission_group_id,
concat(uhpg.user_id, '. ', u.pseudo) as user_id_plus,
concat(uhpg.permission_group_id, '. ', pg.name) as permission_group_id_plus
from lud_user_has_permission_group uhpg
inner join lud_user u on uhpg.user_id=u.id
inner join lud_permission_group pg on uhpg.permission_group_id=pg.id
) as ttt"
array(3) {
[1] => string(29) "lud_user_has_permission_group"
[2] => string(8) "lud_user"
[3] => string(20) "lud_permission_group"
}