Berry Framework

Фреймворк, в который собраны функции использованные в различных проектах. В том числе: ORM, шаблонизатор и ряд других полезных в хозяйстве вещей.

Скачать
trunk-версия (650 КБ)
Наверх

SQL

Класс для работы с базой данных

Переменные

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()

Сохраняет данные и возвращает:

  1. при вставке число-идентификатор последней вставленной записи, либо false;
  2. при редактирование bool;
Если перевым параметром задать true, то вёрнётся массив содержащий указанные выше типы в виде (array)ключ (имя таблицы) => значения.

Пример

// вставляем данные
$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) - 1].

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()

Плейсхолдер для "чистого" запроса.