|
|
|
|
|
|
|
|
|
|
Один из наиболее важных инструментов, используемых при создании модулей IPB и модификаций его кода - интерфейс базы данных. Используя методы, предоставляемые объектом $ipsclass→DB, вы получаете простой и мощный способ работы с базой данных вашего форума.
В этой статье мы рассмотрим методы объекта $ipsclass→DB, с помощью которых программист может манипулировать базой данных форума. Сначала мы обратимся к простым функциям выборки — simple_select() и simple_select_with_join() и методам обработки данных, которые они возвращают. Затем будут рассмотрены методы вставки, удаления и обновления данных, а в самом конце — универсальный метод build_query, конструирующий запросы любой сложности.
Допустим, вам необходимо получить данные из таблицы форума с помощью оператора SELECT. Специально для этого в объекте ipsclass предусмотрен метод simple_select(). Рассмотрим пример его использования:
$this->ipsclass->DB->simple_select( 'title,state', 'topics', 'starter_id = 1' ); $this->ipsclass->DB->exec_query();
Здесь:
Таким образом, в данном примере происходит выборка заголовков (title) и статусов (state) всех тем (topics), которые были начаты администратором (пользователем, чем ID равен единице; starter_id = 1). Обратите внимание, что после вызова метода simple_select() обязательно должен быть вызван метод exec_query(). Он-то и выполняет запрос, построенный с помощью метода simple_select(). После других методов — например, do_update() или do_insert() — метод exec_query() использовать не нужно.
Этот метод добавляет к создаваемому запросу конструкцию LIMIT: она ограничивает область, в которой будет производиться выборка данных и задаёт предельное количество строк, возвращаемых в результате запроса. Рассмотрим пример использования:
$this->ipsclass->DB->simple_select( 'name,mgroup', 'members', 'allow_admin_mails = 1' ); $this->ipsclass->DB->simple_limit( 10, 5 ); $this->ipsclass->DB->exec_query();
Как мы уже знаем из предыдущих примеров, функция simple_select в данном случае создаст запрос, который извлекает значения полей name (логин пользователя) и mgroup (идентификатор его основной группы) из таблицы ibf_members. Выборка вернёт только те записи, где поле allow_admin_mails равно единице, то есть данные тех пользователей, которые разрешили приём писем от администрации форума. Вторая строка примера добавляет к сформированному запросу конструкцию LIMIT 10,5 — то есть поиск будет производиться, начиная с 11-й строки и в результате выборки будет не больше 5-и строк.
Параметр сдвига (offset) можно опускать. Например, следующий код вернёт первого в таблице пользователя, чей логин совпадает с отображаемым именем:
$this->ipsclass->DB->simple_select( '*', 'members', 'name = members_display_name' ); $this->ipsclass->DB->simple_limit( 1 ); $this->ipsclass->DB->exec_query();
Существует также модификация метода — simple_limit_with_check(). Синтаксис этой функции идентичен оригинальной, за одним исключением: преждем чем добавить к создаваемому запросу конструкцию LIMIT, она проверяет её наличие в тексте запроса и в случае положительного результата не выполняется. Таким образом исключается возможная ошибка SQL-запроса из-за задания двух конструкций LIMIT.
Итак, вы выполнили некий SQL-запрос. Что дальше? Как теперь получить данные, которые вернул сервер?
Вам нужно использовать метод fetch_row(), который вернет полученные от сервера данные в виде ассоциативного массива. Например:
$data = $this->ipsclass->DB->fetch_row();
Обратите внимание: если в результате SQL-запроса вы рассчитывали получить больше одной строки, нужно обрабатывать полученные данные, пока они не закончатся. Ваш код в этом случае будет иметь примерно такой вид:
while( $row = $this->ipsclass->DB->fetch_row() ) { // Манипулируем данными строки. Например, заносим в массив. Вот так: $all_rows[] = $row; }
После выполнения этой конструкции в массив $all_rows будут занесены все строки, которые вернул вам сервер баз данных после обработки запроса.
Синтаксис метода, удаляющего строки из таблицы, очень прост и выглядит примерно так:
$this->ipsclass->DB->simple_delete( 'spider_logs', 'bot=MyBot' ); $this->ipsclass->DB->exec_query();
Здесь первый оператор — это название таблицы, из которой следует удалять данные, а второй — условие их удаления (аналог SQL-оператора WHERE). В этом примере из таблицы ibf_spider_logs будут удалены все строки, в которых поле bot имеет значение «MyBot» (то есть, будут удалены все данные посещений форума ботом, определённым как MyBot).
Обратите внимание, что если вы опустите второй параметр и укажите только название таблицы, из неё будут удалены все данные, а счётчик автоинкрементных полей будет обнулён (то есть, выполнится SQL-запрос TRUNCATE). Будьте осторожны!
In the case that you need to check for the rows returned, or the affected rows, you have two functions at your disposal: [code]$num_rows = $this→ipsclass→DB→get_num_rows();[/code] get_num_rows() does exactly what it says, it will return the number of rows returned by the query just executed. It returns 0 for 0, so you can do a true/false check on the returned value. [code]$affect_rows = $this→ipsclass→DB→get_affected_rows();[/code] get_affected_rows() will return the number of rows changed in an update query, delete query, or insert query.
Дописать про методы семейства simple_* и вообще про build_query, тут и трети нет.
Если вам необходимо выполнить более сложную выборку (и не только выборку, запрос может быть любого типа и ниже мы это рассмотрим) - используйте метод build_query(). Метод использует очень гибкие параметры. Расммотрим пример обработки двух таблиц через привычный LEFT JOIN:
$join_array = array( 'select' => 'b.*', 'from' => array( 'table_b' => 'b' ), 'where' => 'a.this_thing = b.this_other', 'type' => 'left' ); $this->ipsclass->DB->build_query( array( 'select' => 'a.*', 'from' => array( 'table_name' => 'a' ), 'where' => 'a.this = 4', 'add_join' => $join_array, 'limit' => array( 0,15 ) ) ); $this->ipsclass->DB->exec_query();
В целях удобочитаемости кода IBResource.ru рекомендует вам формировать запрос из фрагментов: так, в этом примере массив $join_array сначала задан, а потом использован в методе build_query(). Рассмотрим части этого массива:
m.id = mex.id.Вы можете использовать метод build_query для обновления, вставки данных и многих других операций.
The parameters are nearly identical to the [i]$join_array[/i], except for the key 'add_join'. This is where you would pass the [i]$join_array[/i] to the function so that the proper join SQL can be generated.
By using the do_update() and do_insert() functions, you can process an update or insert query in just one function call. [code]$this→ipsclass→DB→do_update( 'some_table', array( 'fieldname' ⇒ 0, 'fieldtwo' ⇒ 'new_value' ), 'this_field = 5' );[/code] The first parameter is the table you wish to update. Second parameter is an array of each field that you need to update, and their new values. Third, and very important, is the WHERE clause. Leave this out and you'll get a nice table of the exact same values :P
The do_insert() syntax is identical, except for the missing WHERE clause: [code]$this→ipsclass→DB→do_insert( 'some_table', array( 'field_to_insert' ⇒ 'the_value' ) );[/code] If your DB schema has default values in certain fields, and you don't want to change them on insert, you don't have to specify the field name in the array.
There are more methods and tricks to using the DB layer, however these are the most commonly used in most modifications, and in the products themselves. If anyone would like to expand on the other functions, feel free :)
Работает на DokuWiki |