PHP: Bir mysql sorgudan tabloismi almak için regex kullanarak

5 Cevap php

Bu üç mysql ifadeleri düşünün:

select * from Users;
select id, title, value from Blogs;
select id, feelURL, feelTitle from Feeds where id = 1; 

Şimdi Regex çok iyi değil im, ama mysql sorgudan tablo adını almak istiyorum. Birisi muhtemelen küçük bir açıklama ile benim için bir tane yaratabilir.

Teşekkürler,

5 Cevap

Deneyin:

preg_match('/\bfrom\b\s*(\w+)/i',$query,$matches)

Sorgu 1'den fazla tablo varsa bu işe yaramaz.

Temelde regex sorguda tam sözcük FROM için arayışları ve tablo adı olarak aşağıdaki kelimeyi seçer.

Aslında çözümleyici olarak MySQL kullanabilirsiniz olursa olsun ve ne kadar karmaşık SQL sözdizimi sorgusunda tablenames alabilirsiniz.

(Bu soruya bir geç tepki olduğunu Üzgünüm - Ben sadece bugün aynı sorun vardı ve bu çözümü buldum.)

Sadece kelime ile sorgu İZAH önek ve PHP döndü ayarlanmış sonuçları id, select_type, masa, tipi, possible_keys, anahtar, key_len, ref, satırlar, Ekstra içerecektir. Üçüncü sütun sizin sorgusunda her tablonun adıdır.

Örneğin, sorgu varsa:

select count(*) from ey_def left join ey_rels on def_id=item_id;

Kullanın:

explain select count(*) from ey_def left join ey_rels on def_id=item_id;

Ve MySQL PHP için bu dönecektir:

+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | ey_def  | index | NULL          | PRIMARY | 4       | NULL |   87 | Using index |
|  1 | SIMPLE      | ey_rels | ALL   | NULL          | NULL    | NULL    | NULL |  123 |             |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+

Artık sadece başka bir sorgu gibi sonuçlarını işleyebilir.

Saf bir uygulama bu olacaktır:

preg_match("/\s+from\s+`?([a-z\d_]+)`?/i", $query, $match);

echo $query . " => " . $match[1] . "\n";

Bir SELECT alan listesindeki alt sorgu (ve muhtemelen diğer birkaç durumlarda) olduğunda bu will bölünürler. Ya da tablo adı az, sayılar ve alt yanında karakterler içerdiğinde.

Doğru SQL ayrıştırma önemsiz değildir.

Verdiğiniz sorgu dizesi için aşağıdaki yapmalıdır:

preg_match_all('/from (\w+)/', $query, $tables);

print_r($tables[1]);

[0] => Users
[1] => Blogs
[2] => Feeds

Ama tam teşekküllü bir SQL çözümleyici oluşturulurken, zaten bir açıklama işaret gibi önemsiz olmayan bir iştir. Bu buna karşı atmak herhangi bir ve tüm sorgulara kullanılabilir olmasını beklemeyin.

Bunu daha önce ... bana yukarıda belirtilen insan gibi, önemsiz olmayan ayrıştırma sql tablolar bulunuyor gördük isterdim. Bir sql dize tablo adlarını seçmek için, (sizin veritabanındaki bir milyon tablolar yok sağlayan) sql eşleşmeleri sonra bulmak, her şeyden önce tablo adlarını almak için daha iyi bir fikir olacaktır. Ben sadece bu yüzden sadece bunu yapar taraftan bir işleve sahip olur:

/*
  Takes a sql statement and attempts to get a table name from it.
  This assumes a database is already specified in the connection.

  [$sql]: string; SQL statement that was executed
  [$conn]: resource; MySQLi connection resource

  returns table name string
 */  
function get_table_names($sql,$conn){
    //declare variables
    $table_array = array();
    $table_string = "";

    //get all the table names in the selected database
    $sql2 = "SHOW TABLES";
    $result = mysqli_query($conn, $sql2);

    //display an error if something went wrong
    if (!$result) {
        echo "DB Error, could not list tables\n";
        echo 'MySQL Error: ' . mysqli_error($conn);
        exit;
    }

    //fetch the rows and push the table names into $table_array
    while ($row = mysqli_fetch_row($result)) {
        array_push($table_array, $row[0]);
    }

    //loop through all the tables in the database
    foreach($table_array as $table){
        if(strpos($sql,$table)){ //if match is found append to string
            $table_string .= " $table ";
        }
    }

    //return a string of table name matches
    return $table_string;
}

O birisi yardımcı olur umarım ...