SQL
Класс для работы с базой данных
- Переменные
- sql->table
- sql->primary_key
- sql->has_one
- sql->belongs_to
- sql->has_many
- sql->has_and_belongs_to_many
- sql->check
- Методы
- sql::init()
- sql::using()
- sql::find()
- sql->query()
- sql->fetch()
- sql->fetch_array()
- sql->fetch_row()
- sql->fetch_pair()
- sql->fetch_column()
- sql->fetch_cell()
- sql->count()
- sql->exists()
- sql->with()
- sql->where()
- sql->having()
- sql->sort()
- sql->group()
- sql->limit()
- sql->page()
- sql->save()
- sql->delete()
- sql::table()
- sql::union()
- sql::stat()
- sql::raw()
Переменные
sql->table
Устанавливает реальное название табицы. Можно указать таблицу из другой БД.
Пример
class Table extends SQL {
public $table = 'example_table';
}
// или
class Table extends SQL {
public $table = 'some_db.prefix_table';
}
sql->primary_key
Установка первичного ключа, идентификатора. По умолчанию это id. Можно выбрать и нечисловой идентификатор.
Пример
// по id
$table = new Table(2);
// по какому-то иному полю с ключом unique
$table = new Table('Сосиски');
sql->has_one
Описывает связь типа один-к-одному. Например, у одной записи в блоге один автор.
Обратите внимание: связи строятся не на отношении класса к таблице, а на отношениях класса к классу.
Пример
class Post extends SQL {
// это оно
public $has_one = array('user');
}
class User extends SQL {
public $table = 'profiles';
public $has_many = array('posts');
}
Если модель имеет нестандартные ключи, то об этом надо явно указать в связях. В идеале у таблице post поле связующие с моделью user должно называться user_id, но в примере ниже оно имеет название poster_id.
class Post extends SQL {
// модель => array(ключ в данной таблице, ключ в связанной таблице)
public $has_one = array('user' => array('poster_id', 'id'));
// или так
/* public $has_one = array('user' => array(
'local' => 'poster_id',
'foreign' => 'id'
)); */
}
class User extends SQL {
public $table = 'profiles';
public $has_many = array('posts' => array('id', 'poster_id'));
}
sql->belongs_to
Описывает связь типа один-к-одному или один-ко-многим с другой стороны, когда один автор имеет всего одну запись в блоге.
Пример
class Post extends SQL {
public $has_one = array('user');
}
class User extends SQL {
public $table = 'profiles';
// это оно
public $belongs_to = array('post'); // тут один post
}
sql->has_many
Сзязь Много-к-одному, когда один пользователь может быть автором многих постов в блоге. Так же это обратная связь от один-к-одному.
Пример
class Post extends SQL {
public $has_one = array('user');
}
class User extends SQL {
public $table = 'profiles';
// это оно
public $has_many = array('posts'); // много данных из post поэтому posts
}
sql->has_and_belongs_to_many
Описывает тип связи много-ко-много. Например, один пост в блоге входит в много категорий, а в одной категории много записей из блога.
Пример
class Post extends SQL {
// это оно
public $has_and_belongs_to_many = array('categories');
}
class Category extends SQL {
// обратная сторона много-ко-многим точно такая же
public $has_and_belongs_to_many = array('posts');
}
sql->check
Валидация при сохранении. В случае неудачи, выбрасывается исключение Check_Except.
Пример
class Post extends SQL {
// это оно
protected $check = array(
'title' => array('int(20, 40)', 'Кривенький заголовок-то.')
);
}
$post = new Post;
$post->title = 'Сам ты кривенький.';
try {
$post->save();
} catch (Check_Except $e){
echo $e;
}
| post[title] | Кривенький заголовок-то. |
Более подробно о валидации можно почитать в описании класса Check.
Методы
sql::init()
Запускает SQL и создаёт соеденение с БД.
Пример
sql::init(array(
'driver' => 'драйвер', // по умолчанию PDO_MySQL
'username' => 'пользователь',
'password' => 'пароль',
'database' => 'сервер/база данных',
'prefix' => 'префикс',
'charset' => 'кодировка', // по умолчанию utf8
'profiler' => 'профайлер' // по умолчанию false
));
// или
sql::init(array(
'first' => array(
'driver' => 'драйвер', // по умолчанию PDO_MySQL
'username' => 'пользователь',
'password' => 'пароль',
'database' => 'сервер/база данных',
'prefix' => 'префикс',
'charset' => 'кодировка', // по умолчанию utf8
'profiler' => 'профайлер' // по умолчанию false
),
'second' => array(
...
),
'third' => array(
...
),
));
Названия ключей не имеют значения. Главным соеденением будет то, что стоит раньше. В примере это first.
sql::using()
Переключает соеденение или возвращает название текущего.
// first - текущее соеденение
print_r(sql::using());
// first - переключаем соеденение, возвращается название предыдущего
print_r(sql::using('second'));
// second
print_r(sql::using('first'));
sql::find()
Первым параметром можно указать массив или число (тогда ищет sql->primary_key записи).
Пример
$table = Table::find(); // "фабрика"
// то же, что new Table(2)
$table = Table::find(2);
// where (id = 2 or id = 3) and id > 4 and id in (5, 6, 7);
$table->find(array(
array(
array('id' => 2),
array('id' => 3)
),
'id > ?' => 4,
'id' => array(5, 6, 7),
));
sql->query()
Возвращает PDOStatement.
sql->fetch()
Возвращает массив данных.
Пример
$table = new Table;
print_r($table->fetch());
// или
print_r(sql::table('table')->fetch());
/* Array (
[0] => Array (
[id] => 1
[name] => Some
)
[1] => Array (
[id] => 2
[name] => Test
)
) */
sql->fetch_array()
Возвращает данные в виде многомерного сгруппированного связями массива.
Пример
Предположим, есть таблици post, categories и user. Одна запись в post может иметь связь с несколькими записями из таблицы categories и одной из таблицы user.
// ищем в таблице post идентификатор с номером 1
$post = new Post(1);
// явно указываем что нам нужно
$post->with('user.name', 'categories.name');
// получаем массив
print_r($post->fetch_array());
/* Array (
[id] => 2
[name] => Test
[user] => Array (
[name] => Великий Корнхолио
)
[categories] => Array (
[0] => Array (
[name] => PHP
)
[1] => Array (
[name] => Python
)
[2] => Array (
[name] => Lua
)
)
) */
Можно проигнорировать метод sql->with() и получать данные по ходу, но количество к базе будет значительным.
$post = new Post(1);
// 1
print_r($post->id);
// Test
print_r($post->name);
// Великий Корнхолио
print_r($post->user->name);
print_r($post->categories->fetch_array());
/* Array (
[0] => Array (
[name] => PHP
)
[1] => Array (
[name] => Python
)
[2] => Array (
[name] => Lua
)
) */
То же самое, что и выше, но с альтернативным синтаксисом доступа к обьектам.
$post = new Post(1);
// 1
print_r($post['id']);
// Test
print_r($post['name']);
// Великий Корнхолио
print_r($post['user']['name']);
print_r($post['categories']->fetch_array());
/* Array (
[0] => Array (
[name] => PHP
)
[1] => Array (
[name] => Python
)
[2] => Array (
[name] => Lua
)
) */
sql->fetch_row()
Возвращает результат в виде одного ряда.
Пример
// select id, name from table
/* Array (
[id] => 2
[name] => Test
) */
sql->fetch_pair()
Возвращает последовательность, в которой ключи одна колонка, а значения - другая.
Пример
// select id, name from table
/* Array (
[1] => Some
[2] => Test
) */
Можно указать номер возвращаемой колонки (по умолчанию 1) или номара (0 и 1, соответственно).
// select id, name from table
// $sql->fetch_pair()
/* Array (
[1] => Some
[2] => Test
) */
// $sql->fetch_pair(0)
/* Array (
[1] => 1
[2] => 2
) */
// $sql->fetch_pair(1, 1)
/* Array (
[Some] => Some
[Test] => Test
) */
sql->fetch_column()
Схожа с sql->fetch_pair(), но ключи всегда производны.
Пример
// select id, name from table
// $sql->fetch_column()
/* Array (
[0] => 1
[1] => 2
) */
// $sql->fetch_column(1)
/* Array (
[0] => Some
[1] => Test
) */
sql->fetch_cell()
Возвращает первую ячейку результата запроса.
sql->count()
Возвращает число найденых строк.
Пример
$table = Table::find('id > ?', 1);
// 1
print_r($table->count());
// или
// 1
print_r(count($table));
print_r($table->fetch());
/* Array (
[0] => Array (
[id] => 2
[name] => Test
)
) */
sql->exists()
Проверяет существование записи.
Пример
$table = new Table(2);
// false
print_r($table->exists());
sql->with()
Напрямую указывает что нужно получить и таким образом сократить кол-во запросов до минимума (обычно один с left join).
Пример
$post = new Post(1);
$post->with('user.name', 'concat("My", "S", "QL") as string');
print_r($post->fetch_array());
/* Array (
[id] => 2
[name] => Test
[user] => Array (
[name] => Великий Корнхолио
)
[string] => MySQL
) */
В выборке можно указывать "жадность" (*) для основной таблицы (происходит по умолчанию, если в sql->with() не фигурируют её поля) и для связанных таблиц - user.*, например.
sql->where()
Добавляет критерии поиска. То же самое, что sql->find().
sql->having()
Добавляет критерии поиска. То же самое, что sql->find() только... Ну, having же
sql->sort()
Добавляет сортировку. Можно указывать как отдельным методом на каждую сортировку, так и любым количеством параметров метода.
Пример
$table = new Table;
// order by id, name desc
$table->sort('id', '-name');
// или
// order by id, name desc
$table->sort(array('id', '-name'));
// или
// order by id, name desc
$table->sort('id');
$table->sort('-name');
sql->group()
Добавляет группировку по полю(ям). См. sql->sort для примера.
sql->limit()
Добавляет ограничение на количество выбранного. Пекрвыый параметр передаёт limit, второй - limit.
sql->page()
Метод учитывая sql->limit() позволяет сортировать данные по страницам.
Пример
// limit 10 offset 10
$table->page(10, 2);
sql->save()
Сохраняет данные и возвращает:
- при вставке число-идентификатор последней вставленной записи, либо false;
- при редактирование bool;
Пример
// вставляем данные
$table = new Table;
$table->name = 'And another test';
// 3
var_dump($table->save());
// или так
$table = new Table;
$table[]['name'] = 'And another test 2';
$table[]['name'] = 'And another test 3';
// Array([table] => Array([0] => 4 [1] => 5))
var_dump($table->save(true));
// редактируем данные
$table = new Table(2);
$table->name = 'Test [edited]';
// 1
var_dump($table->save());
"Сосисочным" метод.
$post = new Post(2);
$post->name .= ' [edited]';
$post->user->name = 'Some name';
var_dump($post->save());
/* Array
(
[post] => Array
(
[0] => 1
)
[user] => Array
(
[0] => 6
)
) */
Можно добавлять или редактировать все связанные данные.
$post = new Post;
// $post[2] === new Post(3)
// And another test
print_r($post[2]->name);
// $post[0] === new Post(1)
$post[0]->name .= ' [edited]';
$post[0]->user->name = 'Some name';
$post[0]->categories[0]->name = 'New name';
// Array ([0] => 1 [1] => 1 [1] => 1)
var_dump($post->save());
Обратите внимание: доступ к связаным данным осуществляется по ключу массива, где 0 первая запись, а последняя - на примере категорий - $post[0]->categories[count($post[0]->categories)
sql->delete()
Удаляет данные. Если не указан sql->where(), очищает таблицу.
sql::table()
"Фабрика". Вторым параметром можно указать ровно тоже, что и sql->find().
sql::union()
Объединяет несколько запросов.
Пример
$song1 = new Song(1);
$song1->with('id', 'title', 'artist.name');
$song5 = new Song(5);
$song5->with('id', 'title', 'artist.name');
$union = sql::union($song1, $song5);
$union->sort('title');
print_r($union->fetch());
/* Array
(
[0] => Array
(
[id] => 5
[title] => Love TKO
[artist.name] => Teddy Pendergrass
)
[1] => Array
(
[id] => 1
[title] => Santa Monica
[artist.name] => Theory of a Dead Man
)
) */
sql::stat()
Возвращает массив с данными по статистике. Указав первый параметр можно получить конкретный ключ массива.
sql::raw()
Плейсхолдер для "чистого" запроса.