Intereting Posts
Изменение значения элемента узла XML в PHP и сохранение файла Как отключить ошибки кода состояния HTTP по умолчанию на сервере Zend? Помощь в массиве PHP / MySQL Преобразование числа с запятой в виде десятичной точки для плавания Оптимизация Imagick annotateImage php проверить, равна ли домену значению, затем выполнить действие Внедрить карту в javascript, которая поддерживает методы объектов как отображаемые функции? OAuth в Zend Framework 2 Как вставить несколько значений флажка в таблицу? Получить «правильный» год определенной даты с PHP DateTime Как отобразить список категорий, содержащих элементы в mysql Получать сообщения с помощью мета значения, используя флажок Невозможно добавить условие на неопределенную переменную результата в неагрегированном запросе Использование массивов в PDO UPDATE Подготовленное утверждение PHP array_search последовательно возвращает первый ключ массива

PHP: использование REGEX для получения имени tablen из запроса mysql

Рассмотрим эти три оператора mysql:

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

Теперь я не очень хорошо разбираюсь в REGEX, но хочу получить имя таблицы из запроса mysql. Может ли кто-нибудь создать его для меня с небольшим объяснением.

Благодаря,

Пытаться:

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

Это не будет работать, если запрос содержит более 1 таблицы.

В основном регулярное выражение выполняет поиск полного слова FROM в запросе и выбирает следующее слово в качестве имени таблицы.

Фактически вы можете использовать MySQL в качестве синтаксического анализатора и получать теги tablenames в своем запросе независимо от того, насколько сложна синтаксис SQL.

(Извините, что это последний ответ на ваш вопрос. У меня была такая же проблема сегодня и я нашел это решение.)

Просто префикс вашего запроса словом EXPLAIN, и набор результатов, возвращаемый PHP, будет включать id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra. Третий столбец – это имя каждой таблицы в вашем запросе.

Например, если ваш запрос был:

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

Использование:

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

И MySQL вернет это PHP:

 +----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+ | 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 | | +----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+ 

Теперь вы можете просто обрабатывать результаты, как и любой другой запрос.

Наивная реализация будет такой:

 preg_match("/\s+from\s+`?([az\d_]+)`?/i", $query, $match); echo $query . " => " . $match[1] . "\n"; 

Это сломается, если у вас есть подзапрос в списке SELECT (и, вероятно, в нескольких других случаях). Или когда ваше имя таблицы содержит символы рядом с az, номерами и символами подчеркивания.

Правильный анализ SQL не является тривиальным.

Для строки запроса, которую вы указали, необходимо выполнить следующее:

 preg_match_all('/from (\w+)/', $query, $tables); print_r($tables[1]); [0] => Users [1] => Blogs [2] => Feeds 

Но, как уже отмечалось в комментарии, создание полноценного анализатора SQL является нетривиальной задачей. Не ожидайте, что это будет использоваться по любым и всем запросам, которые вы бросаете против него.

Хотелось бы, чтобы я видел это раньше … Как и люди выше меня, это нетривиальные синтаксические выражения SQL. Чтобы выбрать имена таблиц из строки sql, было бы лучше сначала получить все имена таблиц, а затем найти совпадения в sql (при условии, что в вашей базе данных не будет миллиона таблиц). У меня просто есть функция под рукой, которая делает именно это:

 /* 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; } 

Надеюсь, что кто-то поможет …

Это должно сделать это:

 (SELECT|DELETE|UPDATE|INSERT INTO) (\*|[A-Z0-9_]+)(FROM)?([A-Z0-9_, ]+) 

Он будет работать с выбранным обновлением удаления и вставкой. Если вы используете tablename1, tablename2, он вернет его как массив