[PHP, API] На php тоже может быть легко и быстро
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
На мой взгляд, язык php всегда был довольно хорошим решением для создания сложного бекэнда веб-приложений, а в девяностые и нулевые приобрел такую огромную популярность (именно огромную, сопоставимую с IE для веб-серфига того времени) в первую очередь благодаря легкости, скорости разработки и поддержки кода. Но те времена прошли. Сегодня считается, что приложения на php стали монструозны, долго и сложно запускаемы, способны работать только с подтягиванием множества зависимостей в директорию /vendor...Зачастую все именно так, но я хочу попробовать вам показать, что может быть иначе. Попробуем сделать простое API и приложить не больше усилий чем при использовании Node.js или Go.Под катом мой пример того, как можно быстро и без лишней головной боли сделать API на php.Я решил использовать понравившийся мне по работе в нескольких проектах фреймворк Slim (https://www.slimframework.com/), потому что имею опыт написания/поддержки с нуля и роутера, и ORM, а также поддержки самописных CMS, и это точно не про "быстро и легко".Для решения на фреймворке Slim не понадобится устанавливать дополнительных расширений на php. Кроме, конечно же, самого сервера (Apache 2, Nginx или другого на наш вкус), сервера баз данных и composer, но этот набор обычно уже есть и на серверах, и тем более на хостинге. Теперь начинаем кухарить (cooking app):
mkdir my-slim-api && cd my-slim-api
composer init
На этом шаге нужно заполнить данные о новом приложении так, чтобы в результате получился файл composer.json примерно такого вида:
{
"name": "zhukmax/slim",
"type": "project",
"license": "MIT",
"autoload": {
"psr-4": {
"Zhukmax\\Slim\": "src/"
}
},
"require": {}
}
Устанавливаем зависимости, сам Slim, а также реализацию интерфейсов http-сообщений (PSR-7) и интерфейсов фабрик http-сообщений (PSR-17):
composer require slim/slim:"4.*"
composer require slim/psr7
Теперь мы можем создать простое API в одном index-файле, возвращающее, как сейчас "модно-молодежно", json строку в теле ответа:
<?php
require __DIR__ . '/vendor/autoload.php';
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
$app = AppFactory::create();
$app->get('/', function (Request $request, Response $response, $args) {
$data = array('name' => 'Max', 'role' => 'web developer');
$response->getBody()->write(json_encode($data));
return $response->withHeader('Content-Type', 'application/json');
});
$app->run();
При этом укажем в composer.json информацию, что нам требуется расширение php-json (и если расширение не установлено – установим)
"require": {
"slim/slim": "4.*",
"slim/psr7": "^1.4",
"ext-json": "*"
}
Работа с данными из MySQLВ Slim придется сначала установить стороннее решение для удобной работы с базой, так как сам фреймворк поставляется без ORM. Можно использовать и решение от Laravel Eloquent и популярную Doctrine, которая также подойдет и для работы с NoSQL базами. Для нашей статьи выберем Idiorm за простоту использования.
composer require j4mie/idiorm
Настраиваем подключение и запрашиваем данные:
<?php
ORM::configure([
// Обратите внимание, что localhost не работает по умолчанию,
// прежде чем паниковать попробуйте 127.0.0.1
'connection_string' => 'mysql:host=127.0.0.1;dbname=mydb',
'username' => 'root',
'password' => '124'
]);
$app->get('/users', function (Request $request, Response $response, $args) {
$users = ORM::forTable("users")->find_array();
$response->getBody()->write(json_encode($users));
return $response;
});
Теперь, если запустить приложение и проверить url, мы получим список всех записей в таблице users в виде json-строки.Создать, обновить, получить и удалитьВсе должно работать отлично, и теперь можно создать методы для получения одного пользователя, добавления нового пользователя, изменения и удаления. Для этого используем GET, POST, PUT и DELETE http-запросы и их обработку.
<?php
$app->post('/users', function (Request $request, Response $response, $args) {
$parsedBody = $request->getParsedBody();
$user = ORM::forTable("users")->create();
$user->name = $parsedBody['name'] ?? '';
if ($user->save()) {
$successRes = $response->withStatus(201);
$successRes->getBody()->write(json_encode([
"message" => "Success"
]));
return $successRes;
} else {
$errorRes = $response->withStatus(501);
$errorRes->getBody()->write(json_encode([
"message" => "Error"
]));
return $errorRes;
}
});
Мы, конечно же, хотим, чтобы наш код был готов к ошибкам, и поэтому пишем их обработку в теле функции. Кроме того, что мы добавили обработку ошибки сохранения нового пользователя в таблице, еще можно сделать проверку соответствия полей определенным шаблонам, например, их обязательность. Но для этого лучше подходят модели, которые могут немного по-разному создаваться в зависимости от выбранного ORM. В Idiorm нет стандарта оформления класса моделей, да и описание фильтров и шаблонов немного за рамками данной статьи, так что оставим это за скобками. Мы же хотим быстро сделать рабочее API, а доводить его до ума можно годами, как показывает практика.Контроллеры и actionsХранить код всех запросов и их обработки в одном index.php файле – затея не из лучших, поэтому давайте воспользуемся возможностью фреймворка по созданию контроллеров. В обработчике маршрута оставим только описание пути и ссылку на нужный нам метод в классе-контроллере.
$app->get('/users/{id}', [UserController::class, "getOne"]);
Что мне лично нравится у Slim – мы можем соблюдать негласный стандарт об использовании слова action в наименовании методов, а можем от него отойти в пользу другого локального стандарта. Теперь, когда мы используем не лямбда-функции, а полноценные классы, мы можем удобно вынести повторяющийся код в отдельный приватный метод, как и сделано в примере ниже. Либо создавать хелперы и трейты. Не то чтобы мы не могли это все делать раньше, но как же теперь мило сердцу получается.
<?php
class UserController
{
public function getOne(Request $request, Response $response, $args): Response
{
$id = (int)$args['id'] ?? 0;
$user = ORM::forTable("table1")->findOne($id);
if (!$user) {
return self::errorResponse($response, 404, "Error text");
}
$response->getBody()->write(json_encode([
"id" => $user->id,
"name" => $user->name
]));
return $response;
}
private static function errorResponse(Response $response, int $code, string $text): Response
{
$errorRes = $response->withStatus($code);
$errorRes->getBody()->write(json_encode([
"message" => $text
]));
return $errorRes;
}
}
ИтогВ первую очередь, я удовлетворил свой собственный интерес. Мне хотелось быстро набросать на php простое API, как я много раз делал на Express, когда создавал приложения на Angular и требовалось что-то поднять на backend. И я считаю, что описанный вариант более чем достоин для использования. Он предполагает возможность развиваться, увеличивать количество строк кода. При этом может быть поддерживаемым и недорогим решением, так как достаточно прост в освоении даже не очень опытным web-разработчиком.Так как помещать весь код в статью довольно неудобно и она сильно увеличится, я сделал на github репозиторий (https://github.com/ZhukMax/slim-api), в котором можно посмотреть весь получившийся код.
===========
Источник:
habr.com
===========
Похожие новости:
- [Анализ и проектирование систем, Интерфейсы, API] Проектирование интеграции с веб-сервисом
- [PHP] Отказоустойчивая работа с Redis
- [PHP] Избегая автобусов (перевод)
- [Разработка веб-сайтов, Анализ и проектирование систем, IT-инфраструктура, API, Софт] gRPC vs REST, что выбрать для нового сервера?
- [Системное администрирование, PHP, MySQL, IT-инфраструктура, Nginx] Установка Ispconfig3 на ubuntu 20.04 (nginx+php-fpm+mysql)
- [Машинное обучение, Искусственный интеллект] Чат-бот для отзывов из Google Play. Опыт QuData
- [PHP, Программирование, Тестирование веб-сервисов] Веб-скрейпинг на PHP (перевод)
- [Разработка веб-сайтов, JavaScript, Node.JS, API, TypeScript] Декларативный API на Next.JS — реальность?
- [Научно-популярное] В Денисовой пещере на Алтае найдены следы Homo sapiens
- [Научно-популярное] Антропологи обнаружили в Израиле неопределённый вид Homo
Теги для поиска: #_php, #_api, #_slim, #_api, #_rest_api, #_php, #_blog_kompanii_reksoft (
Блог компании Reksoft
), #_php, #_api
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 05:17
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
На мой взгляд, язык php всегда был довольно хорошим решением для создания сложного бекэнда веб-приложений, а в девяностые и нулевые приобрел такую огромную популярность (именно огромную, сопоставимую с IE для веб-серфига того времени) в первую очередь благодаря легкости, скорости разработки и поддержки кода. Но те времена прошли. Сегодня считается, что приложения на php стали монструозны, долго и сложно запускаемы, способны работать только с подтягиванием множества зависимостей в директорию /vendor...Зачастую все именно так, но я хочу попробовать вам показать, что может быть иначе. Попробуем сделать простое API и приложить не больше усилий чем при использовании Node.js или Go.Под катом мой пример того, как можно быстро и без лишней головной боли сделать API на php.Я решил использовать понравившийся мне по работе в нескольких проектах фреймворк Slim (https://www.slimframework.com/), потому что имею опыт написания/поддержки с нуля и роутера, и ORM, а также поддержки самописных CMS, и это точно не про "быстро и легко".Для решения на фреймворке Slim не понадобится устанавливать дополнительных расширений на php. Кроме, конечно же, самого сервера (Apache 2, Nginx или другого на наш вкус), сервера баз данных и composer, но этот набор обычно уже есть и на серверах, и тем более на хостинге. Теперь начинаем кухарить (cooking app): mkdir my-slim-api && cd my-slim-api
composer init {
"name": "zhukmax/slim", "type": "project", "license": "MIT", "autoload": { "psr-4": { "Zhukmax\\Slim\": "src/" } }, "require": {} } composer require slim/slim:"4.*"
composer require slim/psr7 <?php
require __DIR__ . '/vendor/autoload.php'; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; $app = AppFactory::create(); $app->get('/', function (Request $request, Response $response, $args) { $data = array('name' => 'Max', 'role' => 'web developer'); $response->getBody()->write(json_encode($data)); return $response->withHeader('Content-Type', 'application/json'); }); $app->run(); "require": {
"slim/slim": "4.*", "slim/psr7": "^1.4", "ext-json": "*" } composer require j4mie/idiorm
<?php
ORM::configure([ // Обратите внимание, что localhost не работает по умолчанию, // прежде чем паниковать попробуйте 127.0.0.1 'connection_string' => 'mysql:host=127.0.0.1;dbname=mydb', 'username' => 'root', 'password' => '124' ]); $app->get('/users', function (Request $request, Response $response, $args) { $users = ORM::forTable("users")->find_array(); $response->getBody()->write(json_encode($users)); return $response; }); <?php
$app->post('/users', function (Request $request, Response $response, $args) { $parsedBody = $request->getParsedBody(); $user = ORM::forTable("users")->create(); $user->name = $parsedBody['name'] ?? ''; if ($user->save()) { $successRes = $response->withStatus(201); $successRes->getBody()->write(json_encode([ "message" => "Success" ])); return $successRes; } else { $errorRes = $response->withStatus(501); $errorRes->getBody()->write(json_encode([ "message" => "Error" ])); return $errorRes; } }); $app->get('/users/{id}', [UserController::class, "getOne"]);
<?php
class UserController { public function getOne(Request $request, Response $response, $args): Response { $id = (int)$args['id'] ?? 0; $user = ORM::forTable("table1")->findOne($id); if (!$user) { return self::errorResponse($response, 404, "Error text"); } $response->getBody()->write(json_encode([ "id" => $user->id, "name" => $user->name ])); return $response; } private static function errorResponse(Response $response, int $code, string $text): Response { $errorRes = $response->withStatus($code); $errorRes->getBody()->write(json_encode([ "message" => $text ])); return $errorRes; } } =========== Источник: habr.com =========== Похожие новости:
Блог компании Reksoft ), #_php, #_api |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 05:17
Часовой пояс: UTC + 5