Статьи

Использование базы данных Illuminate с Eloquent в приложении PHP без Laravel

Illuminate — это движок базы данных Laravel за вычетом Laravel. Он поставляется в комплекте с Eloquent ORM в Laravel. Если вы хотите создавать свои приложения PHP с ORM и предпочитаете не использовать Laravel, это руководство для вас.

В этом руководстве мы собираемся создать серверную часть для приложения для вопросов и ответов с PHP, базой данных Illuminate и Eloquent ORM.

  1. PHP: 5.5+
  2. MYSQL
  3. Композитор

Наше приложение выполнит десять задач:

  • Добавить пользователя.
  • Добавить вопрос
  • Добавить ответ на вопрос.
  • Upvote ответ.
  • Получите вопрос с ответами.
  • Получить все вопросы и пользователи, которые их задавали.
  • Получить конкретные вопросы, ответы и отзывы.
  • Подсчет вопросов конкретного пользователя.
  • Обновить ответ пользователя.
  • Удалить вопрос.

Сначала мы создаем каталог нашего проекта и структуру.

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

Наша проектная организация

Затем мы создаем файл index.php в основной папке проекта на том же уровне, что и папка приложения .

Мы будем использовать git, поэтому создадим файл .gitignore. Обратите внимание, что этот шаг не является обязательным.

Далее мы устанавливаем зависимости, необходимые для работы этого проекта. В основной папке проекта мы создадим файл composer.json. Затем вставьте это в наш файл composer.json.

1
2
3
4
5
6
{
 “name”: “illuminate-example/eloquent”,
 “description”: “Implementation of Database Queries with illuminate and Eloquent”,
 “type”: “project”,
 “require”: {}
}

Чтобы установить базу данных Illuminate, мы добавляем это в наш composer.json:
“illuminate/database”: “5.1.8”,

Далее мы добавляем автозагрузку psr-4 для наших моделей и контроллеров:

1
2
3
4
5
“autoload”: {
“psr-4”: {
“Controllers\\”: “app/controllers/”,
“Models\\”: “app/models/” }
}

Теперь наш файл composer.json должен выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
{
 “name”: “illuminate-example/eloquent”,
 “description”: “Implementation of Database Queries with illuminate and Eloquent”,
 “type”: “project”,
 “require”: {
 “illuminate/database”: “5.1.8”},
 “autoload”:
    {“psr-4”:
        { “Controllers\\”: “app/controllers/”,
            “Models\\”: “app/models/»
             
                 }
    }
}

Теперь мы запустим эти две команды composer в том же месте, что и наш файл composer.json:

1
2
composer install
composer dump-autoload -o

Это создаст папку vendor, которую мы можем добавить в gitignore (это также необязательный шаг).

Давайте добавим файл конфигурации для наших учетных данных базы данных.

В главном каталоге проекта мы создаем файл с именем config.php и определяем детали БД в файле Config.php. Обратите внимание, что значения должны быть заменены вашими собственными данными соединения.

1
2
3
4
5
6
7
<?php
 
defined(“DBDRIVER”)or define(‘DBDRIVER’,’mysql’);
defined(“DBHOST”)or define(‘DBHOST’,’localhost’);
defined(“DBNAME”)or define(‘DBNAME’,’eloquent-app’);
defined(“DBUSER”)or define(‘DBUSER’,’root’);
defined(“DBPASS”)or define(‘DBPASS’,’pass’);

Далее мы создаем схему для нашего приложения.

Прежде чем мы создадим схему для таблиц в нашей базе данных, стоит отметить, что мы можем добавить временные метки в нашу схему.

Eloquent ORM ожидает два столбца отметки времени, если мы хотим включить операцию отметки времени для конкретной таблицы / модели. Это created_at и updated_at . Если мы включаем временные метки для модели, Eloquent автоматически обновляет эти поля в соответствии со временем, когда мы создаем или обновляем запись.

Существует третий столбец, который называется deleted_at . Тем не deleted_at метка времени deleted_at работает по-другому. Eloquent имеет функцию мягкого удаления, которая использует столбец deleted_at чтобы определить, была ли удалена запись. Если вы удаляете запись с помощью красноречивой функции «delete» и включаете Soft Delete, столбец обновляется со временем удаления. Эти удаленные элементы могут быть восстановлены в любое время.

В этом приложении мы будем использовать метки времени, поэтому мы будем использовать все три при создании нашей схемы.

Создайте таблицы с помощью следующих команд в MySQL:

1
2
3
4
5
6
7
8
9
CREATE TABLE `questions` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `question` tinytext,
 `user_id` int(11) DEFAULT NULL,
 `created_at` timestamp NULL DEFAULT NULL,
 `updated_at` timestamp NULL DEFAULT NULL,
 `deleted_at` timestamp NULL DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
01
02
03
04
05
06
07
08
09
10
CREATE TABLE `answers` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `answer` tinytext,
 `user_id` int(11) DEFAULT NULL,
 `question_id` int(11) DEFAULT NULL,
 `created_at` timestamp NULL DEFAULT NULL,
 `updated_at` timestamp NULL DEFAULT NULL,
 `deleted_at` timestamp NULL DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1
2
3
4
5
6
7
8
9
CREATE TABLE `upvotes` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `answer_id` int(11) DEFAULT NULL,
 `user_id` int(11) DEFAULT NULL,
 `created_at` timestamp NULL DEFAULT NULL,
 `updated_at` timestamp NULL DEFAULT NULL,
 `deleted_at` timestamp NULL DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
01
02
03
04
05
06
07
08
09
10
CREATE TABLE `users` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `username` varchar(100) DEFAULT NULL,
 `email` varchar(200) DEFAULT NULL,
 `password` varchar(200) DEFAULT NULL,
 `created_at` timestamp NULL DEFAULT NULL,
 `updated_at` timestamp NULL DEFAULT NULL,
 `deleted_at` timestamp NULL DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Мы продолжим создание файлов для моделей и контроллеров для наших таблиц в следующих местах:

  • project_folder / приложение / модели / question.php
  • project_folder / приложение / модели / answer.php
  • project_folder / приложение / модели / upvote.php
  • project_folder / приложение / модели / user.php
  • project_folder / приложение / модели / database.php
  • project_folder / приложение / контроллеры / questions.php
  • project_folder / приложение / контроллеры / answers.php
  • project_folder / приложение / контроллеры / upvotes.php
  • project_folder / приложение / контроллеры / users.php

Откройте файл models / database.php с помощью редактора.

Сначала мы создаем капсулу:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
 
namespace Models;
use Illuminate\Database\Capsule\Manager as Capsule;
 
class Database {
 
    function __construct() {
    $capsule = new Capsule;
    $capsule->addConnection([
     ‘driver’ => DBDRIVER,
     ‘host’ => DBHOST,
     ‘database’ => DBNAME,
     ‘username’ => DBUSER,
     ‘password’ => DBPASS,
     ‘charset’ => ‘utf8’,
     ‘collation’ => ‘utf8_unicode_ci’,
     ‘prefix’ => »,
    ]);
    // Setup the Eloquent ORM…
    $capsule->bootEloquent();
}
 
}

В приведенном выше файле мы инициализируем и настраиваем капсулу с константами, определенными в config.php, а затем загружаем eloquent.

Следующим шагом является создание сценария запуска. Это будет файл, в котором будет запущено все, что должно быть выполнено до того, как наше приложение заработает.

Мы создаем стартовый файл в папке project_folder / start.php, а затем в файле требуется файл автозагрузки Composer:

require 'vendor/autoload.php';

После этого нам требуется config.php, чтобы получить определенные учетные данные: require 'config.php';

Затем мы инициализируем класс базы данных.

1
2
3
4
5
6
<?php
 
use Models\Database;
 
//Boot Database Connection
new Database();

Ваш start.php должен выглядеть так:

1
2
3
4
5
6
7
<?php
require ‘config.php’;
require ‘vendor/autoload.php’;
use Models\Database;
//Initialize Illuminate Database Connection
new Database();
?>

Включите start.php в ваш index.php, так как это будет наш основной файл.

Наш файл index.php теперь выглядит так:

1
2
3
<?php
require ‘start.php’;
?>

Далее мы можем начать работать над нашими контроллерами и моделями. В project_folder / app / models / question.php мы добавляем это:

01
02
03
04
05
06
07
08
09
10
11
12
13
<?php
 
namespace Models;
 
use \Illuminate\Database\Eloquent\Model;
 
class Question extends Model {
     
    protected $table = ‘questions’;
     
}
 
?>

Затем в project_folder /app/controllers/questions.php :

1
2
3
4
5
6
7
8
<?php
namespace Controllers;
 
class Questions{
     
}
 
?>

В project_folder /app/controllers/answers.php мы делаем то же самое:

1
2
3
4
5
6
7
<?php
namespace Controllers;
 
class Answers{
     
}
?>

В пользовательской модели ( project_folder /app/models/user.php) мы добавляем следующий код для определения нашего пространства имен, расширяем модель Eloquent и определяем имя таблицы ( protected $table ) и какие поля в таблицах можно заполнять массовым созданием ( protected $fillable ).

1
2
3
4
5
6
7
8
9
<?php
namespace Models;
use \Illuminate\Database\Eloquent\Model;
 
class User extends Model {
    protected $table = ‘users’;
    protected $fillable = [‘username’,’email’,’pass’];
}
?>

В контроллере пользователей ( project_folder /app/controllers/user.php ) мы определяем наше пространство имен и класс как обычно:

1
2
3
4
5
6
7
<?php
namespace Controllers;
 
class Users{
     
}
?>

Затем, чтобы создать пользователя, в контроллере users мы импортируем пространство имен Model пользователя, use Models\User; , а затем добавьте функцию для создания пользователя.

1
2
3
4
5
6
<?php
 
   public static function create_user($username, $email, $password){
       $user = User::create([‘username’=>$username,’email’=>$email,’password’=>$password]);
       return $user;
   }

Наш пользовательский контроллер теперь выглядит следующим образом.

01
02
03
04
05
06
07
08
09
10
11
12
13
<?php
 
namespace Controllers;
use Models\User;
 
class Users {
     
    public static function create_user($username, $email, $password){
        $user = User::create([‘username’=>$username,’email’=>$email,’password’=>$password]);
        return $user;
    }
}
?>

Затем в index.php мы добавляем эти строки и запускаем приложение для создания нового пользователя.

1
2
3
4
5
6
<?php
 
use Controllers\Users;
 
// Import user controller
$user = Users::create_user(“user1”,”[email protected]”,”user1_pass”);

Чтобы добавить вопрос, мы импортируем пространство имен модели вопроса в контроллер вопросов и напишем функцию create_question :

use Models\Question;

Потом:

1
2
3
4
5
6
7
<?php
 
public static function create_question($question,$user_id){
 
    $question = Question::create([‘question’=>$question,’user_id’=>$user_id]);
    return $question;
}

Мы использовали модели массового создания Eloquent для вставки этой записи, но прежде чем она заработает, нам нужно разрешить заполнение этих полей, потому что модели Eloquent по умолчанию защищают от массового создания.

Итак, мы переходим к модели question и добавляем в класс protected $fillable свойство protected $fillable .

protected $fillable = ['question','user_id'];

Для этого импортируйте контроллер вопросов в index.php и статически вызовите функцию create_question :

use Controllers\Question;

Затем создайте вопрос с вопросом и идентификатором пользователя в качестве параметров:

$question = Questions::create_question("Have you ever met your doppelganger?",1);

Возвращает объект модели в случае успеха.

Теперь мы запустим скрипт index.php с разными записями, чтобы добавить больше вопросов в базу данных.

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

01
02
03
04
05
06
07
08
09
10
11
<?php
namespace Models;
use \Illuminate\Database\Eloquent\Model;
 
class Answer extends Model {
     
    protected $table = ‘answers’;
    protected $fillable = [‘answer’,’user_id’,’question_id’];
     
}
?>

Затем в контроллере ответов мы пишем эти строки:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?php
 
namespace Controllers;
use Models\Answer;
 
 
class Answers {
 
    public static function add_answer($answer,$question_id,$user_id){
        $answer = Answer::create([‘answer’=>$answer,’question_id’=>$question_id,’user_id’=>$user_id]);return $answer;
    }
}
 
?>

Затем в index.php мы можем создать ответ на вопрос с идентификатором 1, который мы добавили ранее, с идентификатором пользователя 2. Не забудьте сначала импортировать контроллер ответов в index.php.

1
2
3
4
5
<?php
 
use Controllers\Answers;
 
    $answers = Answers::add_answer(“This is an answer”,1,2);

Чтобы предотвратить несколько записей, прокомментируйте все другие вызовы в index.php перед запуском нового.

Это почти те же самые шаги, к которым мы привыкли.

Поэтому мы скопируем это в модель Upvote по адресу project_folder / app / models / upvote.php .

01
02
03
04
05
06
07
08
09
10
11
12
13
<?php
namespace Models;
 
use \Illuminate\Database\Eloquent\Model;
 
 
class Upvote extends Model {
 
    protected $table = ‘upvotes’;
    protected $fillable = [‘answer_id’,’user_id’];
      
}
 ?>

Затем в контроллеры ответов мы импортируем пространство имен Upvote Model.

use Models\Upvote;

Затем мы создаем функцию upvote_answer .

1
2
3
4
5
6
<?php
 
   public static function upvote_answer($answer_id,$user_id){
       $upvote = Upvote::create([‘answer_id’=>$answer_id,’user_id’=>$user_id]);
       return $upvote;
   }

В index.php мы можем вызвать функцию с фиктивным идентификатором пользователя, чтобы поднять ответ с идентификатором 1.

$upvote = Answers::upvote_answer(1,14);

Для подобных задач мы можем использовать отношения Eloquent.

Типы отношений включают один к одному, один ко многим, много ко многим и т. Д.

При использовании этих отношений Eloquent предполагает, что в моделях существует внешний ключ в форме имя модели _id . Для этой задачи отношение является отношением один ко многим, потому что одному вопросу может принадлежать любое количество ответов.

Сначала мы определяем эту связь, добавляя эту функцию в нашу модель вопроса.

1
2
3
4
5
6
<?php
 
public function answers()
{
    return $this->hasMany(‘\Models\Answer’);
}

Затем в контроллере вопросов мы пишем функцию для получения вопросов с ответами.

1
2
3
4
5
6
7
<?php
 
public static function get_questions_with_answers(){
  
    $questions = Question::with(‘answers’)->get()->toArray();
    return $questions;
}

Это возвращает вопросы с соответствующими ответами.

В index.php мы комментируем все остальные вызовы и запускаем:

$all = Questions::get_questions_with_answers();

Мы можем var_dump или print_r переменной $all чтобы увидеть результаты.

Это отношение один к одному, потому что один вопрос имеет одного пользователя, поэтому мы добавим это в модель вопроса.

1
2
3
4
5
6
<?php
 
public function user()
{
    return $this->belongsTo(‘\Models\User’);
}

Затем мы создаем функцию в контроллере вопросов и используем функцию with в модели вопросов.

1
2
3
4
5
6
7
<?php
 
public static function get_questions_with_users(){
 
    $questions = Question::with(‘user’)->get()->toArray();
    return $questions;
}

В index.php прокомментируйте все остальные и запустите это:

$all_with_users = Questions::get_questions_with_users();

Сначала мы определяем отношение между ответами и ответами. Ответ имеет много откликов, поэтому отношения один ко многим.

Поэтому мы добавляем следующую функцию в нашу модель ответа:

1
2
3
4
5
6
<?php
 
public function upvotes()
{
    return $this->hasMany(‘\Models\Upvote’);
}

Затем в контроллере вопросов мы создаем функцию для получения этого:

1
2
3
4
5
6
7
<?php
 
public static function get_question_answers_upvotes($question_id){
 
    $questions = Question::find($question_id)->answers()->with(‘upvotes’)->get()->toArray();
    return $questions;
}

Как и в предыдущих шагах, мы комментируем все остальные вызовы index.php и запускаем это:

$one_question = Questions::get_question_answers_upvotes(1);

Мы можем напечатать переменную $one_question чтобы увидеть результаты.

Сначала мы импортируем модель вопроса в контроллеры пользователей:

use Models\Question;

Затем мы пишем эту функцию:

1
2
3
4
5
6
7
<?php
 
public static function question_count($user_id){
 
    $count = Question::where(‘user_id’,$user_id)->count();
    return $count;
}

В index.php мы комментируем другие вызовы и добавляем эту строку:

$user_question_count = Users::question_count(1);

Это возвращает целое число, которое является количеством вопросов, которые были добавлены пользователем с идентификатором 1.

Мы можем напечатать переменную $user_question_count и запустить index.php, чтобы увидеть результаты.

Концепция обновления с помощью Eloquent ORM довольно проста. Сначала мы находим запись, а затем мутируем и сохраняем.

Теперь в контроллеры ответов добавим эту функцию:

1
2
3
4
5
6
7
8
<?php
 
public static function update_answer($answer_id,$new_answer){
    $answer = Answer::find($answer_id);
    $answer->answer = $new_answer;
    $updated = $answer->save();
    return $updated;
}

В index.php мы можем комментировать все остальные вызовы и обновлять ответ с идентификатором 1 следующим образом:

$update_answer = Answers::update_answer(1,”This is an updated answer”);

Это возвращает логическое значение — true — если обновление прошло успешно.

В этом последнем задании мы реализуем Eloquent SoftDelete.

Сначала мы расскажем модели вопроса, чтобы она использовала SoftDeletes , импортировав пространство имен SoftDeletes , а затем используя признак SoftDeletes в нашем классе.

use Illuminate\Database\Eloquent\SoftDeletes;

Затем после строки объявления класса мы добавляем эту строку:

use SoftDeletes;

Затем мы добавляем deleted_at к protected $dates свойству protected $dates deleted_at для модели. Это обязательные шаги.

protected $dates = ['deleted_at'];

Наша модель вопроса теперь выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
 
namespace Models;
 
use \Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
 
class Question extends Model {
 
 
    use SoftDeletes;
 
    protected $table = ‘questions’;
    protected $fillable = [‘question’,’user_id’];
    protected $dates = [‘deleted_at’];
 
    public function answers()
    {
        return $this->hasMany(‘\Models\Answer’);
    }
 
    public function user()
    {
        return $this->belongsTo(‘\Models\User’);
    }
 
 }
 
 ?>

Затем мы создаем функцию delete_question в контроллере вопросов.

1
2
3
4
5
6
7
8
9
<?php
 
public static function delete_question($question_id){
 
    $question = Question::find($question_id);
    $deleted = $question->delete();
    return $deleted;
 
}

Запустите в index.php:

$delete = Questions::delete_question(1);

Поздравляем! Вы только что построили полнофункциональный бэкэнд с Illuminate и Eloquent. И нам не нужно было писать так много кода, чтобы достичь всего этого.

Код для этого урока можно найти на GitHub .

Illuminate также поставляется с Query Builder, который вы можете использовать для еще более сложных запросов к базе данных, и это определенно то, что вы хотите экспериментировать и использовать в своем приложении.

Единственное, чего не хватает в автономной базе данных Illuminate, — это миграции баз данных, что является прекрасной особенностью Laravel и Lumen, микрофрейм Laravel. Вы должны рассмотреть возможность использования обоих в своих приложениях, чтобы воспользоваться преимуществами полезных функций, которые они поставляют.

Вы можете узнать больше о Eloquent на официальной странице документации Eloquent .