Простой REST API в PHP - Пошаговое руководство

В данной статье вы узнаете, как создать простой REST API в PHP.
  • 1. Обзор проекта
  • 1.1 Что такое REST API?
  • 1.2 Зачем нужен REST API?
  • 1.3 Где используется REST API?
  • 2. Файловая структура
  • 3. Настройка базы данных
  • 3.1 Создание таблицы категорий
  • 3.2 Дамп данных для таблицы категорий
  • 3.3 Создание таблицы товаров
  • 3.4 Дамп данных для таблицы товаров
  • 3.5 Подключение к базе данных
  • 4. Получение товаров
  • 4.1 Создание объекта Product
  • 4.2 Создание файла для чтения товаров
  • 4.3 Подключение к базе данных и таблице товаров
  • 4.4 Чтение товаров из базы данных
  • 4.5 Создание метода read()
  • 4.6 Уведомление пользователя о том, что товары не найдены
  • 5. Создание товаров
  • 5.1 Создание файла create.php
  • 5.2 Создание метода create()
  • 6. Получение одного товара
  • 6.1 Создание файла read_one.php
  • 6.2 Создание метода readOne()
  • 7. Обновление товара
  • 7.1 Создание файла update.php
  • 7.2 Создание метода update()
  • 8. Удаление товара
  • 8.1 Создание файла delete.php
  • 8.2 Создание метода delete()
  • 9. Поиск товаров
  • 9.1 Создание файла search.php
  • 9.2 Создание метода search()
  • 10. Пагинация товаров
  • 10.1 Создание файла read_paging.php
  • 10.2 Создание файла core.php
  • 10.3 Создание метода readPaging()
  • 10.4 Создание метода count()
  • 10.5 Получение массива пагинации
  • 11. Получение категорий
  • 11.1 Создание объекта Category
  • 11.2 Создание файла read.php
  • 11.3 Создание метода read()

1. Обзор проекта

1.1 Что такое REST API?

REST - это концепция (архитектура) для организации взаимодействия между независимыми объектами (приложениями) посредством протокола HTTP. Включает в себя набор принципов (рекомендаций) взаимодействия клиент-серверных приложений. Обычно он представлен в формате JSON.

API - интерфейс взаимодействия с каким-либо объектом (программой, приложением), включающий в себя набор правил, которые позволяют одному приложению общаться с другим. Эти «правила» могут включать в себя операции создания, чтения, обновления и удаления. Примером API может служить всем известная библиотека jQuery.

REST API позволяет вашему приложению взаимодействовать с одним или несколькими различными приложениями, используя концепции REST.

RESP API PHP

1.2 Зачем нужен REST API?

Во многих приложениях REST API необходим, потому что это самый легкий способ создания, чтения, обновления или удаления информации между различными приложениями через Интернет или протокол HTTP. Эта информация представляется пользователю в одно мгновение, особенно если вы используете JavaScript для отображения данных на веб-странице.

1.3 Где используется REST API?

REST API может использоваться любым приложением, которое может подключаться к Интернету. Если данные из приложения могут быть созданы, прочитаны, обновлены или удалены с помощью другого приложения, это обычно означает, что используется REST API.

2. Файловая структура

  • api/
    • config/
      • core.php
      • database.php
    • objects/
      • product.php
      • category.php
    • product/
      • create.php/
      • delete.php/
      • read.php/
      • read_paging.php/
      • read_one.php/
      • update.php/
      • search.php/
    • category/
      • read.php
    • shared/
      • utilities.php

3. Настройка базы данных

Используя PhpMyAdmin, создайте новую базу данных api_db. После этого выполните следующие SQL-запросы, чтобы создать новые таблицы с образцами данных.

3.1 Создание таблицы категорий

CREATE TABLE IF NOT EXISTS `categories` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(256) NOT NULL,
    `description` text NOT NULL,
    `created` datetime NOT NULL,
    `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=19 ;

3.2 Дамп данных для таблицы категорий

INSERT INTO `categories` (`id`, `name`, `description`, `created`, `modified`) VALUES
(1, 'Fashion', 'Category for anything related to fashion.', '2014-06-01 00:35:07', '2014-05-30 17:34:33'),
(2, 'Electronics', 'Gadgets, drones and more.', '2014-06-01 00:35:07', '2014-05-30 17:34:33'),
(3, 'Motors', 'Motor sports and more', '2014-06-01 00:35:07', '2014-05-30 17:34:54'),
(5, 'Movies', 'Movie products.', '2019-05-20 10:22:05', '2019-08-20 10:30:15'),
(6, 'Books', 'Kindle books, audio books and more.', '2018-03-14 08:05:25', '2019-05-20 11:29:11'),
(13, 'Sports', 'Drop into new winter gear.', '2016-01-09 02:24:24', '2016-01-09 01:24:24');

3.3 Создание таблицы товаров

CREATE TABLE IF NOT EXISTS `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `description` text NOT NULL,
  `price` decimal(10,0) NOT NULL,
  `category_id` int(11) NOT NULL,
  `created` datetime NOT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=65 ;

3.4 Дамп данных для таблицы товаров

INSERT INTO `products` (`id`, `name`, `description`, `price`, `category_id`, `created`, `modified`) VALUES
(1, 'LG P880 4X HD', 'My first awesome phone!', '336', 3, '2014-06-01 01:12:26', '2014-05-31 17:12:26'),
(2, 'Google Nexus 4', 'The most awesome phone of 2013!', '299', 2, '2014-06-01 01:12:26', '2014-05-31 17:12:26'),
(3, 'Samsung Galaxy S4', 'How about no?', '600', 3, '2014-06-01 01:12:26', '2014-05-31 17:12:26'),
(6, 'Bench Shirt', 'The best shirt!', '29', 1, '2014-06-01 01:12:26', '2014-05-31 02:12:21'),
(7, 'Lenovo Laptop', 'My business partner.', '399', 2, '2014-06-01 01:13:45', '2014-05-31 02:13:39'),
(8, 'Samsung Galaxy Tab 10.1', 'Good tablet.', '259', 2, '2014-06-01 01:14:13', '2014-05-31 02:14:08'),
(9, 'Spalding Watch', 'My sports watch.', '199', 1, '2014-06-01 01:18:36', '2014-05-31 02:18:31'),
(10, 'Sony Smart Watch', 'The coolest smart watch!', '300', 2, '2014-06-06 17:10:01', '2014-06-05 18:09:51'),
(11, 'Huawei Y300', 'For testing purposes.', '100', 2, '2014-06-06 17:11:04', '2014-06-05 18:10:54'),
(12, 'Abercrombie Lake Arnold Shirt', 'Perfect as gift!', '60', 1, '2014-06-06 17:12:21', '2014-06-05 18:12:11'),
(13, 'Abercrombie Allen Brook Shirt', 'Cool red shirt!', '70', 1, '2014-06-06 17:12:59', '2014-06-05 18:12:49'),
(26, 'Another product', 'Awesome product!', '555', 2, '2014-11-22 19:07:34', '2014-11-21 20:07:34'),
(28, 'Wallet', 'You can absolutely use this one!', '799', 6, '2014-12-04 21:12:03', '2014-12-03 22:12:03'),
(31, 'Amanda Waller Shirt', 'New awesome shirt!', '333', 1, '2014-12-13 00:52:54', '2014-12-12 01:52:54'),
(42, 'Nike Shoes for Men', 'Nike Shoes', '12999', 3, '2015-12-12 06:47:08', '2015-12-12 05:47:08'),
(48, 'Bristol Shoes', 'Awesome shoes.', '999', 5, '2016-01-08 06:36:37', '2016-01-08 05:36:37'),
(60, 'Rolex Watch', 'Luxury watch.', '25000', 1, '2016-01-11 15:46:02', '2016-01-11 14:46:02');

3.5 Подключение к базе данных

Приведенный ниже код показывает учетные данные базы данных и метод для получения подключения к базе данных с помощью PDO.

Создайте папку api и откройте её. Создайте папку config и в ней создайте файл database.php со следующим кодом.

<?php
class Database {

    // укажите свои учетные данные базы данных

    private $host = "localhost";
    private $db_name = "api_db";
    private $username = "root";
    private $password = "";
    public $conn;

    // получаем соединение с БД

    public function getConnection(){

        $this->conn = null;

        try {
            $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
            $this->conn->exec("set names utf8");
        } catch(PDOException $exception){
            echo "Connection error: " . $exception->getMessage();
        }

        return $this->conn;
    }
}
?>

4. Получение товаров

4.1 Создание объекта Product

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

Мы будем использовать этот класс для чтения данных из базы. Откройте папку API. Создайте папку objects. Откройте папку её и создайте файл product.php. Поместите в него следующий код.

<?php
class Product {

    // подключение к базе данных и таблице 'products'

    private $conn;
    private $table_name = "products";

    // свойства объекта

    public $id;
    public $name;
    public $description;
    public $price;
    public $category_id;
    public $category_name;
    public $created;

    // конструктор для соединения с базой данных

    public function __construct($db){
        $this->conn = $db;
    }

    // здесь будет метод read()

}
?>

4.2 Создание файла для чтения товаров

Код ниже содержит заголовки о том, кто может читать этот файл и какой тип содержимого он будет возвращать.

В данном случае наш файл read.php может быть прочитан кем угодно (звездочка * означает все) и вернет данные в формате JSON.

Откройте папку API. Создайте в ней папку product. Откройте её и создайте файл read.php со следующим кодом.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

// подключение к базе данных будет здесь

4.3 Подключение к базе данных и таблице товаров

В приведенном ниже коде мы подключаем файлы database.php и product.php. Это файлы, которые мы создали ранее.

Нам нужно использовать метод getConnection() класса Database для получения соединения с базой данных. Мы передаем это подключение классу Product.

Замените комментарий // подключение к базе данных будет здесь в файле read.php следующим кодом.

// подключение базы данных и файл, содержащий объекты

include_once '../config/database.php';
include_once '../objects/product.php';

// получаем соединение с базой данных

$database = new Database();
$db = $database->getConnection();

// инициализируем объект

$product = new Product($db);
 
// чтение товаров будет здесь

4.4 Чтение товаров из базы данных

В приведенном ниже коде мы используем метод read() класса Product для чтения данных из базы. Через переменную $num мы проверяем, найдены ли записи.

Если найдены записи, мы перебираем их с помощью цикла while, добавляем каждую запись в массив $products_arr, устанавливаем код ответа 200 OK и показываем его пользователю в формате JSON.

Замените комментарий // чтение товаров будет здесь в файле read.php следующим кодом.

// запрашиваем товары

$stmt = $product->read();
$num = $stmt->rowCount();

// проверка, найдено ли больше 0 записей

if ($num>0) {

    // массив товаров

    $products_arr=array();
    $products_arr["records"]=array();

    // получаем содержимое нашей таблицы

    // fetch() быстрее, чем fetchAll()

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){

        // извлекаем строку

        extract($row);

        $product_item=array(
            "id" => $id,
            "name" => $name,
            "description" => html_entity_decode($description),
            "price" => $price,
            "category_id" => $category_id,
            "category_name" => $category_name
        );

        array_push($products_arr["records"], $product_item);
    }

    // устанавливаем код ответа - 200 OK

    http_response_code(200);

    // выводим данные о товаре в формате JSON

    echo json_encode($products_arr);
}

// 'товары не найдены' будет здесь

4.5 Создание метода read()

Мы использовали метод read() в предыдущем разделе, но он пока ещё не существует в классе Product. Нам нужно добавить этот метод. С помощью кода ниже, мы делаем запрос для получения записей из базы данных.

Откройте папку objects. Откройте файл product.php. Поместите следующий код в класс Product перед последней закрывающей фигурной скобкой вместо комментария // здесь будет метод read().

// метод read() - получение товаров

function read(){

    // выбираем все записи

    $query = "SELECT
                c.name as category_name, p.id, p.name, p.description, p.price, p.category_id, p.created
            FROM
                " . $this->table_name . " p
                LEFT JOIN
                    categories c
                        ON p.category_id = c.id
            ORDER BY
                p.created DESC";

    // подготовка запроса

    $stmt = $this->conn->prepare($query);

    // выполняем запрос

    $stmt->execute();

    return $stmt;
}

4.6 Уведомление пользователя о том, что товары не найдены

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

В приведенном ниже коде мы устанавливаем код ответа 404 - Не найдено и сообщение, что Товары не найдены.

Замените комментарий // 'товары не найдены' будет здесь в файле read.php следующим кодом.

else {

    // установим код ответа - 404 Не найдено

    http_response_code(404);

    // сообщаем пользователю, что товары не найдены

    echo json_encode(array("message" => "Товары не найдены."), JSON_UNESCAPED_UNICODE);
}

5. Создание товаров

5.1 Создание файла create.php

Откройте папку product и создайте в ней файл create.php со следующим содержимым.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

// получаем соединение с базой данных

include_once '../config/database.php';

// создание объекта товара

include_once '../objects/product.php';

$database = new Database();
$db = $database->getConnection();

$product = new Product($db);
 
// получаем отправленные данные

$data = json_decode(file_get_contents("php://input"));
 
// убеждаемся, что данные не пусты

if (
    !empty($data->name) &&
    !empty($data->price) &&
    !empty($data->description) &&
    !empty($data->category_id)
) {

    // устанавливаем значения свойств товара

    $product->name = $data->name;
    $product->price = $data->price;
    $product->description = $data->description;
    $product->category_id = $data->category_id;
    $product->created = date('Y-m-d H:i:s');

    // создание товара

    if($product->create()){

        // установим код ответа - 201 создано

        http_response_code(201);

        // сообщим пользователю

        echo json_encode(array("message" => "Товар был создан."), JSON_UNESCAPED_UNICODE);
    }

    // если не удается создать товар, сообщим пользователю

    else {

        // установим код ответа - 503 сервис недоступен

        http_response_code(503);

        // сообщим пользователю

        echo json_encode(array("message" => "Невозможно создать товар."), JSON_UNESCAPED_UNICODE);
    }
}

// сообщим пользователю что данные неполные

else {

    // установим код ответа - 400 неверный запрос

    http_response_code(400);

    // сообщим пользователю

    echo json_encode(array("message" => "Невозможно создать товар. Данные неполные."), JSON_UNESCAPED_UNICODE);
}
?>

5.2 Создание метода create()

Откройте папку objects. Откройте файл product.php и добавьте следующий код внутри класса Product (objects / product.php).

// метод create - создание товаров

function create(){

    // запрос для вставки (создания) записей

    $query = "INSERT INTO
                " . $this->table_name . "
            SET
                name=:name, price=:price, description=:description, category_id=:category_id, created=:created";

    // подготовка запроса

    $stmt = $this->conn->prepare($query);

    // очистка

    $this->name=htmlspecialchars(strip_tags($this->name));
    $this->price=htmlspecialchars(strip_tags($this->price));
    $this->description=htmlspecialchars(strip_tags($this->description));
    $this->category_id=htmlspecialchars(strip_tags($this->category_id));
    $this->created=htmlspecialchars(strip_tags($this->created));

    // привязка значений

    $stmt->bindParam(":name", $this->name);
    $stmt->bindParam(":price", $this->price);
    $stmt->bindParam(":description", $this->description);
    $stmt->bindParam(":category_id", $this->category_id);
    $stmt->bindParam(":created", $this->created);

    // выполняем запрос

    if ($stmt->execute()) {
        return true;
    }

    return false;
}

6. Получение одного товара

6.1 Создание файла read_one.php

Откройте папку product, создайте в ней файл read_one.php со следующим содержимым.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: GET");
header("Access-Control-Allow-Credentials: true");
header("Content-Type: application/json");

// подключение файла для соединения с базой и файл с объектом

include_once '../config/database.php';
include_once '../objects/product.php';

// получаем соединение с базой данных

$database = new Database();
$db = $database->getConnection();

// подготовка объекта

$product = new Product($db);

// установим свойство ID записи для чтения

$product->id = isset($_GET['id']) ? $_GET['id'] : die();

// прочитаем детали товара для редактирования

$product->readOne();

if ($product->name!=null) {

    // создание массива

    $product_arr = array(
        "id" =>  $product->id,
        "name" => $product->name,
        "description" => $product->description,
        "price" => $product->price,
        "category_id" => $product->category_id,
        "category_name" => $product->category_name
    );

    // код ответа - 200 OK

    http_response_code(200);

    // вывод в формате json

    echo json_encode($product_arr);
}

else {
    // код ответа - 404 Не найдено

    http_response_code(404);

    // сообщим пользователю, что товар не существует

    echo json_encode(array("message" => "Товар не существует."), JSON_UNESCAPED_UNICODE);
}
?>

6.2 Создание метода readOne()

Откройте папку objects. Откройте файл product.php и добавьте следующий код внутри класса Product.

// используется при заполнении формы обновления товара

function readOne() {

    // запрос для чтения одной записи (товара)

    $query = "SELECT
                c.name as category_name, p.id, p.name, p.description, p.price, p.category_id, p.created
            FROM
                " . $this->table_name . " p
                LEFT JOIN
                    categories c
                        ON p.category_id = c.id
            WHERE
                p.id = ?
            LIMIT
                0,1";

    // подготовка запроса

    $stmt = $this->conn->prepare( $query );

    // привязываем id товара, который будет обновлен

    $stmt->bindParam(1, $this->id);

    // выполняем запрос

    $stmt->execute();

    // получаем извлеченную строку

    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    // установим значения свойств объекта

    $this->name = $row['name'];
    $this->price = $row['price'];
    $this->description = $row['description'];
    $this->category_id = $row['category_id'];
    $this->category_name = $row['category_name'];
}

7. Обновление товара

7.1 Создание файла update.php

Откройте папку product, создайте в ней файл update.php и поместите в него следующий код.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

// подключаем файл для работы с БД и объектом Product

include_once '../config/database.php';
include_once '../objects/product.php';

// получаем соединение с базой данных

$database = new Database();
$db = $database->getConnection();

// подготовка объекта

$product = new Product($db);

// получаем id товара для редактирования

$data = json_decode(file_get_contents("php://input"));

// установим id свойства товара для редактирования

$product->id = $data->id;

// установим значения свойств товара

$product->name = $data->name;
$product->price = $data->price;
$product->description = $data->description;
$product->category_id = $data->category_id;

// обновление товара

if ($product->update()) {

    // установим код ответа - 200 ok

    http_response_code(200);

    // сообщим пользователю

    echo json_encode(array("message" => "Товар был обновлён."), JSON_UNESCAPED_UNICODE);
}

// если не удается обновить товар, сообщим пользователю

else {

    // код ответа - 503 Сервис не доступен

    http_response_code(503);

    // сообщение пользователю

    echo json_encode(array("message" => "Невозможно обновить товар."), JSON_UNESCAPED_UNICODE);
}
?>

7.2 Создание метода update()

В папке objects откройте файл product.php и добавьте новый метод update() внутри класса Product.

// метод update() - обновление товара

function update(){

    // запрос для обновления записи (товара)

    $query = "UPDATE
                " . $this->table_name . "
            SET
                name = :name,
                price = :price,
                description = :description,
                category_id = :category_id
            WHERE
                id = :id";

    // подготовка запроса

    $stmt = $this->conn->prepare($query);

    // очистка

    $this->name=htmlspecialchars(strip_tags($this->name));
    $this->price=htmlspecialchars(strip_tags($this->price));
    $this->description=htmlspecialchars(strip_tags($this->description));
    $this->category_id=htmlspecialchars(strip_tags($this->category_id));
    $this->id=htmlspecialchars(strip_tags($this->id));

    // привязываем значения

    $stmt->bindParam(':name', $this->name);
    $stmt->bindParam(':price', $this->price);
    $stmt->bindParam(':description', $this->description);
    $stmt->bindParam(':category_id', $this->category_id);
    $stmt->bindParam(':id', $this->id);

    // выполняем запрос

    if ($stmt->execute()) {
        return true;
    }

    return false;
}

8. Удаление товара

8.1 Создание файла delete.php

Откройте папку product и создайте файл delete.php со следующим содержимым.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

// подключим файл для соединения с базой и объектом Product

include_once '../config/database.php';
include_once '../objects/product.php';

// получаем соединение с БД

$database = new Database();
$db = $database->getConnection();

// подготовка объекта

$product = new Product($db);

// получаем id товара

$data = json_decode(file_get_contents("php://input"));

// установим id товара для удаления

$product->id = $data->id;

// удаление товара

if ($product->delete()) {

    // код ответа - 200 ok

    http_response_code(200);

    // сообщение пользователю

    echo json_encode(array("message" => "Товар был удалён."), JSON_UNESCAPED_UNICODE);
}

// если не удается удалить товар

else {

    // код ответа - 503 Сервис не доступен

    http_response_code(503);

    // сообщим об этом пользователю

    echo json_encode(array("message" => "Не удалось удалить товар."));
}
?>

8.2 Создание метода delete()

В папке objects откройте файл product.php и добавьте новый метод в класс Product.

// метод delete - удаление товара

function delete(){

    // запрос для удаления записи (товара)

    $query = "DELETE FROM " . $this->table_name . " WHERE id = ?";

    // подготовка запроса

    $stmt = $this->conn->prepare($query);

    // очистка

    $this->id=htmlspecialchars(strip_tags($this->id));

    // привязываем id записи для удаления

    $stmt->bindParam(1, $this->id);

    // выполняем запрос

    if ($stmt->execute()) {
        return true;
    }

    return false;
}

9. Поиск товаров

9.1 Создание файла search.php

В папке product создайте файл search.php со следующим кодом.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

// подключение необходимых файлов

include_once '../config/core.php';
include_once '../config/database.php';
include_once '../objects/product.php';

// создание подключения к БД

$database = new Database();
$db = $database->getConnection();

// инициализируем объект

$product = new Product($db);

// получаем ключевые слова

$keywords=isset($_GET["s"]) ? $_GET["s"] : "";

// запрос товаров

$stmt = $product->search($keywords);
$num = $stmt->rowCount();

// проверяем, найдено ли больше 0 записей

if ($num>0) {

    // массив товаров

    $products_arr=array();
    $products_arr["records"]=array();

    // получаем содержимое нашей таблицы

    // fetch() быстрее чем fetchAll()

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
        // извлечём строку

        extract($row);

        $product_item=array(
            "id" => $id,
            "name" => $name,
            "description" => html_entity_decode($description),
            "price" => $price,
            "category_id" => $category_id,
            "category_name" => $category_name
        );

        array_push($products_arr["records"], $product_item);
    }

    // код ответа - 200 OK

    http_response_code(200);

    // покажем товары

    echo json_encode($products_arr);
}

else {
    // код ответа - 404 Ничего не найдено

    http_response_code(404);

    // скажем пользователю, что товары не найдены

    echo json_encode(array("message" => "Товары не найдены."), JSON_UNESCAPED_UNICODE);
}
?>

9.2 Создание метода search()

В папке objects откройте product.php и добавьте метод search().

// метод search - поиск товаров

function search($keywords){

    // выборка по всем записям

    $query = "SELECT
                c.name as category_name, p.id, p.name, p.description, p.price, p.category_id, p.created
            FROM
                " . $this->table_name . " p
                LEFT JOIN
                    categories c
                        ON p.category_id = c.id
            WHERE
                p.name LIKE ? OR p.description LIKE ? OR c.name LIKE ?
            ORDER BY
                p.created DESC";

    // подготовка запроса

    $stmt = $this->conn->prepare($query);

    // очитска

    $keywords=htmlspecialchars(strip_tags($keywords));
    $keywords = "%{$keywords}%";

    // привязка

    $stmt->bindParam(1, $keywords);
    $stmt->bindParam(2, $keywords);
    $stmt->bindParam(3, $keywords);

    // выполняем запрос

    $stmt->execute();

    return $stmt;
}

10. Пагинация товаров

10.1 Создание файла read_paging.php

В папке product создайте файл read_paging.php со следующим кодом.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

// подлючение файлов

include_once '../config/core.php';
include_once '../shared/utilities.php';
include_once '../config/database.php';
include_once '../objects/product.php';

// utilities

$utilities = new Utilities();

// создание подключения

$database = new Database();
$db = $database->getConnection();

// инициализация объекта

$product = new Product($db);

// запрос товаров

$stmt = $product->readPaging($from_record_num, $records_per_page);
$num = $stmt->rowCount();

// если больше 0 записей

if ($num>0) {

    // массив товаров

    $products_arr=array();
    $products_arr["records"]=array();
    $products_arr["paging"]=array();

    // получаем содержимое нашей таблицы

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
        // извлечение строки

        extract($row);

        $product_item=array(
            "id" => $id,
            "name" => $name,
            "description" => html_entity_decode($description),
            "price" => $price,
            "category_id" => $category_id,
            "category_name" => $category_name
        );

        array_push($products_arr["records"], $product_item);
    }

    // подлючим пагинацию

    $total_rows=$product->count();
    $page_url="{$home_url}product/read_paging.php?";
    $paging=$utilities->getPaging($page, $total_rows, $records_per_page, $page_url);
    $products_arr["paging"]=$paging;

    // установим код ответа - 200 OK

    http_response_code(200);

    // вывод в json-формате

    echo json_encode($products_arr);
} else {

    // код ответа - 404 Ничего не найдено

    http_response_code(404);

    // сообщим пользователю, что товаров не существует

    echo json_encode(array("message" => "Товары не найдены."), JSON_UNESCAPED_UNICODE);
}
?>

10.2 Создание файла core.php

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

Откройте папку config и создайте в ней файл core.php со следующим содержимым.

<?php
// показывать сообщения об ошибках

ini_set('display_errors', 1);
error_reporting(E_ALL);

// URL домашней страницы

$home_url="http://localhost/api/";

// страница указана в параметре URL, страница по умолчанию одна

$page = isset($_GET['page']) ? $_GET['page'] : 1;

// установка количества записей на странице

$records_per_page = 5;

// рассчёт для запроса предела записей

$from_record_num = ($records_per_page * $page) - $records_per_page;
?>

10.3 Создание метода readPaging()

В папке objects откройте файл product.php и добвьте метод readPaging(). Этот метод вернет список записей, ограниченный тем, что мы установили в $records_per_page фале core.php.

// чтение товаров с пагинацией

public function readPaging($from_record_num, $records_per_page){

    // выборка

    $query = "SELECT
                c.name as category_name, p.id, p.name, p.description, p.price, p.category_id, p.created
            FROM
                " . $this->table_name . " p
                LEFT JOIN
                    categories c
                        ON p.category_id = c.id
            ORDER BY p.created DESC
            LIMIT ?, ?";

    // подготовка запроса

    $stmt = $this->conn->prepare( $query );

    // свяжем значения переменных

    $stmt->bindParam(1, $from_record_num, PDO::PARAM_INT);
    $stmt->bindParam(2, $records_per_page, PDO::PARAM_INT);

    // выполняем запрос

    $stmt->execute();

    // вернём значения из базы данных

    return $stmt;
}

10.4 Создание метода count()

Так же в классе Product (файл product.php) добавьте метод count() для создания массива пагинации.

// используется для пагинации товаров

public function count(){
    $query = "SELECT COUNT(*) as total_rows FROM " . $this->table_name . "";

    $stmt = $this->conn->prepare( $query );
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    return $row['total_rows'];
}

10.5 Получение массива пагинации

В корне создайте папку shared, в ней файл utilities.php со следующим кодом.

<?php
class Utilities {

    public function getPaging($page, $total_rows, $records_per_page, $page_url){

        // массив пагинации

        $paging_arr=array();

        // кнопка для первой страницы

        $paging_arr["first"] = $page>1 ? "{$page_url}page=1" : "";

        // подсчёт всех товаров в базе данных для подсчета общего количества страниц

        $total_pages = ceil($total_rows / $records_per_page);

        // диапазон ссылок для показа

        $range = 2;

        // отображать диапозон ссылок вокруг текущей страницы

        $initial_num = $page - $range;
        $condition_limit_num = ($page + $range) + 1;

        $paging_arr['pages']=array();
        $page_count=0;

        for($x=$initial_num; $x<$condition_limit_num; $x++){
            // убедимся, что $x > 0 И $x <= $total_pages

            if ( ($x > 0) && ($x <= $total_pages) ) {
                $paging_arr['pages'][$page_count]["page"]=$x;
                $paging_arr['pages'][$page_count]["url"]="{$page_url}page={$x}";
                $paging_arr['pages'][$page_count]["current_page"] = $x==$page ? "yes" : "no";

                $page_count++;
            }
        }

        // кнопка для последней страницы

        $paging_arr["last"] = $page<$total_pages ? "{$page_url}page={$total_pages}" : "";

        // формат json

        return $paging_arr;
    }
}
?>

11. Получение категорий

11.1 Создание объекта Category

Откройте папку objects и создайте новый файл category.php со следующим кодом.

<?php
class Category{

    // соединение с БД и таблицей 'categories'

    private $conn;
    private $table_name = "categories";

    // свойства объекта

    public $id;
    public $name;
    public $description;
    public $created;

    public function __construct($db){
        $this->conn = $db;
    }

    // используем раскрывающийся список выбора

    public function readAll(){
        // выборка всех данных

        $query = "SELECT
                    id, name, description
                FROM
                    " . $this->table_name . "
                ORDER BY
                    name";
 
        $stmt = $this->conn->prepare( $query );
        $stmt->execute();
 
        return $stmt;
    }
}
?>

11.2 Создание файла read.php

Создайте новую папку category в корне, и в ней файл read.php со следующим кодом.

<?php
// необходимые HTTP-заголовки

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

// подключение файлов для соединения с БД и файл с объектом Category

include_once '../config/database.php';
include_once '../objects/category.php';

// создание подключения к базе данных

$database = new Database();
$db = $database->getConnection();

// инициализация объекта

$category = new Category($db);

// запрос для категорий

$stmt = $category->read();
$num = $stmt->rowCount();

// проверяем, найдено ли больше 0 записей

if ($num>0) {

    // массив

    $categories_arr=array();
    $categories_arr["records"]=array();

    // получим содержимое нашей таблицы

    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
        // извлекаем строку

        extract($row);

        $category_item=array(
            "id" => $id,
            "name" => $name,
            "description" => html_entity_decode($description)
        );

        array_push($categories_arr["records"], $category_item);
    }

    // код ответа - 200 OK

    http_response_code(200);

    // покажем данные категорий в формате json

    echo json_encode($categories_arr);
} else {

    // код ответа - 404 Ничего не найдено

    http_response_code(404);

    // сообщим пользователю, что категории не найдены

    echo json_encode(array("message" => "Категории не найдены."), JSON_UNESCAPED_UNICODE);
}
?>

11.3 Создание метода read()

Откройте в папке objects файл category.php и создайте метод read() для класса Category.

// используем раскрывающийся список выбора

public function read(){

    // выбираем все данные

    $query = "SELECT
                id, name, description
            FROM
                " . $this->table_name . "
            ORDER BY
                name";

    $stmt = $this->conn->prepare( $query );
    $stmt->execute();

    return $stmt;
}

Frontend часть данного приложения (продолжение) - jQuery + AJAX + JSON

Оригинал статьи.

Если вам понравилась данная статья, рекомендую к прочтению создание регистрации и авторизации в php с использованием JWT.

admin
11/11/2019 16:54