I wanna detect all tables in an mysql query with php. I saw mysql_field_table() function that is work for normal queries. but when you use alternative name for a table (table_name AS new_name) it return alternative name not the real name, how ever I fix it by a regex. but now my problem is now with advanced queries like this:
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
now I think I need some regex for detect all real table names in a query. or any other perfect solution. how can I do this?
sorry... here a solution to extract it (if your query in $query
)
if(preg_match_all('/((FROM|JOIN) `(.*)`)/', $query, $matches)) {
$tables = array_unique($matches[3]);
print_r($tables);
}
I also need to extract table name from queries.Then I write my own script which works on almost every basic query.
$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);
Hope this will help
This isn't the most elegant of solutions however has passed all of the tests I've run so far:
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));
}