Лаб. работа "Создание веб-приложений с использованием Slim"

Цель работы

Изучение основ разработки веб-приложений с использованием фреймворка Slim. Освоение навыков создания простых веб-приложений, маршрутизации запросов и работы с шаблонами.

Введение

Slim — это микрофреймворк для PHP, который предназначен для быстрого и простого создания веб-приложений и API. Он минималистичен и предоставляет основные функции, необходимые для разработки, такие как маршрутизация запросов, обработка HTTP-сообщений и внедрение зависимостей.

Оборудование и ПО

  • Компьютер с установленной операционной системой (Windows, macOS, Linux).
  • Веб-сервер (Apache, Nginx) или встроенный сервер PHP.
  • PHP версии 7.2 или выше.
  • Composer — менеджер зависимостей для PHP.
  • Браузер для тестирования приложений.

Теоретическая часть

  1. Основы Slim: Slim Framework предоставляет базовую структуру для веб-приложений и API. Его простота делает его идеальным для небольших приложений, где важны производительность и гибкость.
  2. Маршрутизация: В Slim маршруты определяются с помощью методов GET, POST, PUT и DELETE. Каждый маршрут связан с определенным URI и анонимной функцией, которая обрабатывает запрос.
  3. Middleware: Middleware позволяет изменять запросы и ответы на этапе их обработки, что удобно для реализации функций аутентификации, логирования и обработки ошибок.
  4. Внедрение зависимостей: Slim поддерживает внедрение зависимостей через контейнеры, такие как PHP-DI или Pimple.

Практическая часть

1. Установка Slim Framework

  • Установите Composer, если он еще не установлен.

  • Создайте новый проект и установите Slim:

    1composer create-project slim/slim-skeleton [project-name]
    

2. Создание простого маршрута

  • В файле public/index.php добавьте следующий код:

     1<?php
     2use Psr\Http\Message\ResponseInterface as Response;
     3use Psr\Http\Message\ServerRequestInterface as Request;
     4use Slim\Factory\AppFactory;
     5
     6require __DIR__ . '/../vendor/autoload.php';
     7
     8$app = AppFactory::create();
     9
    10$app->get('/hello/{name}', function (Request $request, Response $response, $args) {
    11    $name = $args['name'];
    12    $response->getBody()->write("Hello, $name");
    13    return $response;
    14});
    15
    16$app->run();
    
  • Запустите встроенный сервер PHP:

    1php -S localhost:8080 -t public
    
  • Откройте браузер и перейдите по адресу http://localhost:8080/hello/World.

3. Добавление Middleware

  • Добавьте middleware для логирования времени выполнения запросов:

    1$app->add(function (Request $request, RequestHandler $handler): Response {
    2    $start = microtime(true);
    3    $response = $handler->handle($request);
    4    $time = microtime(true) - $start;
    5    $response->getBody()->write('<!-- Time: ' . $time . 'ms -->');
    6    return $response;
    7});
    

4. Работа с шаблонами:

  • Установите Twig для работы с шаблонами:

    1composer require slim/twig-view
    
  • Настройте Twig в index.php:

     1use Slim\Views\Twig;
     2use Slim\Views\TwigMiddleware;
     3
     4$app = AppFactory::create();
     5
     6$twig = Twig::create('../templates', ['cache' => false]);
     7$app->add(TwigMiddleware::create($app, $twig));
     8
     9$app->get('/greet/{name}', function (Request $request, Response $response, $args) use ($twig) {
    10    return $twig->render($response, 'greet.twig', ['name' => $args['name']]);
    11});
    12
    13$app->run();
    
  • Создайте шаблон templates/greet.twig:

    1<!DOCTYPE html>
    2<html>
    3<head>
    4    <title>Greet</title>
    5</head>
    6<body>
    7    <h1>Hello, {{ name }}!</h1>
    8</body>
    9</html>
    

5. Работа с базой данных

1. Установка и настройка базы данных

Для начала установим и настроим подключение к базе данных MySQL.

  1. Установите MySQL на ваш компьютер, если он еще не установлен.

  2. Создайте базу данных для вашего проекта. Например, назовем её slim_app.

    1CREATE DATABASE slim_app;
    
  3. Создайте таблицу для пользователей в базе данных slim_app.

    1CREATE TABLE users (
    2    id INT AUTO_INCREMENT PRIMARY KEY,
    3    name VARCHAR(255) NOT NULL,
    4    email VARCHAR(255) NOT NULL UNIQUE
    5);
    
  4. Установите зависимости для работы с базой данных через Composer.

    1composer require vlucas/phpdotenv
    

2. Настройка подключения к базе данных

Создайте файл .env в корне вашего проекта и добавьте туда настройки подключения к базе данных.

1DB_HOST=127.0.0.1
2DB_NAME=slim_app
3DB_USER=root
4DB_PASS=your_password

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

 1<?php
 2use Psr\Http\Message\ResponseInterface as Response;
 3use Psr\Http\Message\ServerRequestInterface as Request;
 4use Slim\Factory\AppFactory;
 5use DI\Container;
 6use Dotenv\Dotenv;
 7
 8require __DIR__ . '/../vendor/autoload.php';
 9
10// Загрузка переменных окружения
11$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
12$dotenv->load();
13
14$container = new Container();
15AppFactory::setContainer($container);
16
17$container->set('db', function() {
18    $host = $_ENV['DB_HOST'];
19    $db = $_ENV['DB_NAME'];
20    $user = $_ENV['DB_USER'];
21    $pass = $_ENV['DB_PASS'];
22    $charset = 'utf8mb4';
23
24    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
25    $options = [
26        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
27        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
28        PDO::ATTR_EMULATE_PREPARES   => false,
29    ];
30
31    try {
32        return new PDO($dsn, $user, $pass, $options);
33    } catch (\PDOException $e) {
34        throw new \PDOException($e->getMessage(), (int)$e->getCode());
35    }
36});
37
38$app = AppFactory::create();
39
40$app->get('/users', function (Request $request, Response $response, $args) {
41    $db = $this->get('db');
42    $stmt = $db->query('SELECT * FROM users');
43    $users = $stmt->fetchAll();
44    $response->getBody()->write(json_encode($users));
45    return $response->withHeader('Content-Type', 'application/json');
46});
47
48$app->run();

3. Создание маршрута для добавления нового пользователя

Создайте форму для добавления нового пользователя и маршрут для обработки этой формы.

  • Добавьте шаблон формы add_user.twig в папку templates.

     1<!DOCTYPE html>
     2<html>
     3<head>
     4    <title>Add User</title>
     5</head>
     6<body>
     7    <h1>Add New User</h1>
     8    <form action="/add_user" method="post">
     9        <label for="name">Name:</label>
    10        <input type="text" id="name" name="name">
    11        <label for="email">Email:</label>
    12        <input type="email" id="email" name="email">
    13        <button type="submit">Add User</button>
    14    </form>
    15</body>
    16</html>
    
  • Обновите файл index.php, чтобы добавить маршрут для отображения формы и обработки данных из формы.

     1$app->get('/add_user', function (Request $request, Response $response, $args) use ($twig) {
     2    return $twig->render($response, 'add_user.twig');
     3});
     4
     5$app->post('/add_user', function (Request $request, Response $response, $args) {
     6    $data = $request->getParsedBody();
     7    $name = $data['name'];
     8    $email = $data['email'];
     9
    10    $db = $this->get('db');
    11    $stmt = $db->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
    12    $stmt->execute(['name' => $name, 'email' => $email]);
    13
    14    return $response->withHeader('Location', '/users')->withStatus(302);
    15});
    

6. Реализация API для работы с данными

1. Подготовка базы данных

Для начала, убедитесь, что у вас уже создана таблица пользователей. Если нет, создайте её в базе данных slim_app.

1CREATE TABLE users (
2    id INT AUTO_INCREMENT PRIMARY KEY,
3    name VARCHAR(255) NOT NULL,
4    email VARCHAR(255) NOT NULL UNIQUE
5);

2. Обновление конфигурации Slim

Внесите следующие изменения в index.php, чтобы добавить маршруты для API:

  1<?php
  2use Psr\Http\Message\ResponseInterface as Response;
  3use Psr\Http\Message\ServerRequestInterface as Request;
  4use Slim\Factory\AppFactory;
  5use DI\Container;
  6use Dotenv\Dotenv;
  7
  8require __DIR__ . '/../vendor/autoload.php';
  9
 10// Загрузка переменных окружения
 11$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
 12$dotenv->load();
 13
 14$container = new Container();
 15AppFactory::setContainer($container);
 16
 17$container->set('db', function() {
 18    $host = $_ENV['DB_HOST'];
 19    $db = $_ENV['DB_NAME'];
 20    $user = $_ENV['DB_USER'];
 21    $pass = $_ENV['DB_PASS'];
 22    $charset = 'utf8mb4';
 23
 24    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
 25    $options = [
 26        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
 27        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
 28        PDO::ATTR_EMULATE_PREPARES   => false,
 29    ];
 30
 31    try {
 32        return new PDO($dsn, $user, $pass, $options);
 33    } catch (\PDOException $e) {
 34        throw new \PDOException($e->getMessage(), (int)$e->getCode());
 35    }
 36});
 37
 38$app = AppFactory::create();
 39
 40// Получение всех пользователей
 41$app->get('/api/users', function (Request $request, Response $response, $args) {
 42    $db = $this->get('db');
 43    $stmt = $db->query('SELECT * FROM users');
 44    $users = $stmt->fetchAll();
 45    $response->getBody()->write(json_encode($users));
 46    return $response->withHeader('Content-Type', 'application/json');
 47});
 48
 49// Получение пользователя по ID
 50$app->get('/api/users/{id}', function (Request $request, Response $response, $args) {
 51    $id = $args['id'];
 52    $db = $this->get('db');
 53    $stmt = $db->prepare('SELECT * FROM users WHERE id = :id');
 54    $stmt->execute(['id' => $id]);
 55    $user = $stmt->fetch();
 56    if ($user) {
 57        $response->getBody()->write(json_encode($user));
 58        return $response->withHeader('Content-Type', 'application/json');
 59    } else {
 60        $response->getBody()->write(json_encode(['message' => 'User not found']));
 61        return $response->withStatus(404)->withHeader('Content-Type', 'application/json');
 62    }
 63});
 64
 65// Создание нового пользователя
 66$app->post('/api/users', function (Request $request, Response $response, $args) {
 67    $data = $request->getParsedBody();
 68    $name = $data['name'];
 69    $email = $data['email'];
 70
 71    $db = $this->get('db');
 72    $stmt = $db->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
 73    $stmt->execute(['name' => $name, 'email' => $email]);
 74    $user = [
 75        'id' => $db->lastInsertId(),
 76        'name' => $name,
 77        'email' => $email
 78    ];
 79    $response->getBody()->write(json_encode($user));
 80    return $response->withStatus(201)->withHeader('Content-Type', 'application/json');
 81});
 82
 83// Обновление пользователя по ID
 84$app->put('/api/users/{id}', function (Request $request, Response $response, $args) {
 85    $id = $args['id'];
 86    $data = $request->getParsedBody();
 87    $name = $data['name'];
 88    $email = $data['email'];
 89
 90    $db = $this->get('db');
 91    $stmt = $db->prepare('UPDATE users SET name = :name, email = :email WHERE id = :id');
 92    $stmt->execute(['name' => $name, 'email' => $email, 'id' => $id]);
 93    $user = [
 94        'id' => $id,
 95        'name' => $name,
 96        'email' => $email
 97    ];
 98    $response->getBody()->write(json_encode($user));
 99    return $response->withHeader('Content-Type', 'application/json');
100});
101
102// Удаление пользователя по ID
103$app->delete('/api/users/{id}', function (Request $request, Response $response, $args) {
104    $id = $args['id'];
105    $db = $this->get('db');
106    $stmt = $db->prepare('DELETE FROM users WHERE id = :id');
107    $stmt->execute(['id' => $id]);
108    $response->getBody()->write(json_encode(['message' => 'User deleted']));
109    return $response->withHeader('Content-Type', 'application/json');
110});
111
112$app->run();

3. Тестирование API

Теперь, когда все маршруты настроены, вы можете протестировать их с помощью инструмента Postman или curl. Вот несколько примеров запросов:

  • Получение всех пользователей:

    1curl -X GET http://localhost:8080/api/users
    
  • Получение пользователя по ID:

    1curl -X GET http://localhost:8080/api/users/1
    
  • Создание нового пользователя:

    1curl -X POST http://localhost:8080/api/users -d "name=John Doe&email=john.doe@example.com"
    
  • Обновление пользователя по ID:

    1curl -X PUT http://localhost:8080/api/users/1 -d "name=Jane Doe&email=jane.doe@example.com"
    
  • Удаление пользователя по ID:

    1curl -X DELETE http://localhost:8080/api/users/1
    

7. Реализация аутентификации

1. Подготовка базы данных

Для начала, добавим таблицу пользователей в базу данных slim_app, которая будет включать поля для имени, электронной почты и пароля.

1CREATE TABLE users (
2    id INT AUTO_INCREMENT PRIMARY KEY,
3    name VARCHAR(255) NOT NULL,
4    email VARCHAR(255) NOT NULL UNIQUE,
5    password VARCHAR(255) NOT NULL
6);

2. Настройка конфигурации Slim

Убедитесь, что ваш файл index.php настроен для подключения к базе данных и добавьте маршруты для регистрации и авторизации пользователей.

  1<?php
  2use Psr\Http\Message\ResponseInterface as Response;
  3use Psr\Http\Message\ServerRequestInterface as Request;
  4use Slim\Factory\AppFactory;
  5use DI\Container;
  6use Dotenv\Dotenv;
  7use Slim\Middleware\SessionMiddleware;
  8
  9require __DIR__ . '/../vendor/autoload.php';
 10
 11// Загрузка переменных окружения
 12$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
 13$dotenv->load();
 14
 15$container = new Container();
 16AppFactory::setContainer($container);
 17
 18$container->set('db', function() {
 19    $host = $_ENV['DB_HOST'];
 20    $db = $_ENV['DB_NAME'];
 21    $user = $_ENV['DB_USER'];
 22    $pass = $_ENV['DB_PASS'];
 23    $charset = 'utf8mb4';
 24
 25    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
 26    $options = [
 27        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
 28        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
 29        PDO::ATTR_EMULATE_PREPARES   => false,
 30    ];
 31
 32    try {
 33        return new PDO($dsn, $user, $pass, $options);
 34    } catch (\PDOException $e) {
 35        throw new \PDOException($e->getMessage(), (int)$e->getCode());
 36    }
 37});
 38
 39$app = AppFactory::create();
 40
 41// Middleware для работы с сессиями
 42$app->add(SessionMiddleware::class);
 43
 44// Регистрация пользователя
 45$app->post('/register', function (Request $request, Response $response, $args) {
 46    $data = $request->getParsedBody();
 47    $name = $data['name'];
 48    $email = $data['email'];
 49    $password = password_hash($data['password'], PASSWORD_DEFAULT);
 50
 51    $db = $this->get('db');
 52    $stmt = $db->prepare('INSERT INTO users (name, email, password) VALUES (:name, :email, :password)');
 53    $stmt->execute(['name' => $name, 'email' => $email, 'password' => $password]);
 54
 55    $response->getBody()->write(json_encode(['message' => 'User registered successfully']));
 56    return $response->withHeader('Content-Type', 'application/json');
 57});
 58
 59// Авторизация пользователя
 60$app->post('/login', function (Request $request, Response $response, $args) {
 61    $data = $request->getParsedBody();
 62    $email = $data['email'];
 63    $password = $data['password'];
 64
 65    $db = $this->get('db');
 66    $stmt = $db->prepare('SELECT * FROM users WHERE email = :email');
 67    $stmt->execute(['email' => $email]);
 68    $user = $stmt->fetch();
 69
 70    if ($user && password_verify($password, $user['password'])) {
 71        $_SESSION['user_id'] = $user['id'];
 72        $_SESSION['user_name'] = $user['name'];
 73        $response->getBody()->write(json_encode(['message' => 'Login successful']));
 74    } else {
 75        $response->getBody()->write(json_encode(['message' => 'Invalid email or password']));
 76        return $response->withStatus(401)->withHeader('Content-Type', 'application/json');
 77    }
 78    return $response->withHeader('Content-Type', 'application/json');
 79});
 80
 81// Middleware для проверки аутентификации
 82$authenticate = function (Request $request, RequestHandler $handler) {
 83    if (!isset($_SESSION['user_id'])) {
 84        $response = new \Slim\Psr7\Response();
 85        $response->getBody()->write(json_encode(['message' => 'Unauthorized']));
 86        return $response->withStatus(401)->withHeader('Content-Type', 'application/json');
 87    }
 88    return $handler->handle($request);
 89};
 90
 91// Пример защищенного маршрута
 92$app->get('/profile', function (Request $request, Response $response, $args) {
 93    $response->getBody()->write(json_encode([
 94        'user_id' => $_SESSION['user_id'],
 95        'user_name' => $_SESSION['user_name']
 96    ]));
 97    return $response->withHeader('Content-Type', 'application/json');
 98})->add($authenticate);
 99
100$app->run();

3. Создание шаблонов для регистрации и авторизации

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

  1. register.twig:
 1<!DOCTYPE html>
 2<html>
 3<head>
 4    <title>Register</title>
 5</head>
 6<body>
 7    <h1>Register</h1>
 8    <form action="/register" method="post">
 9        <label for="name">Name:</label>
10        <input type="text" id="name" name="name">
11        <label for="email">Email:</label>
12        <input type="email" id="email" name="email">
13        <label for="password">Password:</label>
14        <input type="password" id="password" name="password">
15        <button type="submit">Register</button>
16    </form>
17</body>
18</html>
  1. login.twig:
 1<!DOCTYPE html>
 2<html>
 3<head>
 4    <title>Login</title>
 5</head>
 6<body>
 7    <h1>Login</h1>
 8    <form action="/login" method="post">
 9        <label for="email">Email:</label>
10        <input type="email" id="email" name="email">
11        <label for="password">Password:</label>
12        <input type="password" id="password" name="password">
13        <button type="submit">Login</button>
14    </form>
15</body>
16</html>

4. Настройка маршрутов для отображения страниц регистрации и авторизации

Обновите index.php, чтобы добавить маршруты для отображения форм регистрации и авторизации.

1$app->get('/register', function (Request $request, Response $response, $args) use ($twig) {
2    return $twig->render($response, 'register.twig');
3});
4
5$app->get('/login', function (Request $request, Response $response, $args) use ($twig) {
6    return $twig->render($response, 'login.twig');
7});

5. Тестирование аутентификации

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

  • Откройте браузер и перейдите по адресу http://localhost:8080/register, чтобы зарегистрировать нового пользователя.
  • Перейдите по адресу http://localhost:8080/login, чтобы авторизоваться.
  • После успешной авторизации вы можете получить доступ к защищенному маршруту http://localhost:8080/profile.

8. Интеграция с внешним API OpenWeatherMap

1. Регистрация и получение API ключа

  1. Перейдите на сайт OpenWeatherMap и зарегистрируйтесь, чтобы получить API ключ.
  2. Сохраните свой API ключ, он понадобится для запросов к API.

2. Настройка конфигурации Slim

Добавьте ваш API ключ в файл .env.

1WEATHER_API_KEY=your_api_key_here

3. Установка GuzzleHTTP

GuzzleHTTP — это PHP HTTP-клиент, который мы будем использовать для отправки запросов к API OpenWeatherMap.

1composer require guzzlehttp/guzzle

4. Создание шаблона для отображения данных о погоде

Добавьте следующий шаблон в папку templates для отображения данных о погоде.

  1. weather.twig:
 1<!DOCTYPE html>
 2<html>
 3<head>
 4    <title>Weather</title>
 5</head>
 6<body>
 7    <h1>Weather in {{ city }}</h1>
 8    {% if weather %}
 9        <p>Temperature: {{ weather.main.temp }} &deg;C</p>
10        <p>Weather: {{ weather.weather[0].description }}</p>
11    {% else %}
12        <p>{{ error }}</p>
13    {% endif %}
14</body>
15</html>

5. Настройка маршрута для отображения данных о погоде

Обновите index.php, чтобы добавить маршрут для отображения данных о погоде на странице.

 1$app->get('/weather/{city}', function (Request $request, Response $response, $args) use ($twig) {
 2    $city = $args['city'];
 3    $apiKey = $_ENV['WEATHER_API_KEY'];
 4    $url = "http://api.openweathermap.org/data/2.5/weather?q={$city}&appid={$apiKey}&units=metric";
 5
 6    $client = new \GuzzleHttp\Client();
 7    try {
 8        $apiResponse = $client->get($url);
 9        $data = json_decode($apiResponse->getBody(), true);
10        return $twig->render($response, 'weather.twig', [
11            'city' => $city,
12            'weather' => $data
13        ]);
14    } catch (\Exception $e) {
15        return $twig->render($response, 'weather.twig', [
16            'city' => $city,
17            'error' => 'Unable to fetch weather data'
18        ]);
19    }
20});

6. Тестирование интеграции с внешним API

Теперь, когда все маршруты и шаблоны настроены, вы можете протестировать интеграцию с внешним API.

  • Откройте браузер и перейдите по адресу http://localhost:8080/weather/London, чтобы увидеть текущую погоду в Лондоне.

9. Интеграция с API Nominatim

1. Настройка конфигурации Slim

Обновите файл index.php, чтобы добавить маршруты для получения координат города с использованием API Nominatim и получения данных о погоде с использованием API OpenWeatherMap.

 1<?php
 2use Psr\Http\Message\ResponseInterface as Response;
 3use Psr\Http\Message\ServerRequestInterface as Request;
 4use Slim\Factory\AppFactory;
 5use DI\Container;
 6use Dotenv\Dotenv;
 7use Slim\Middleware\SessionMiddleware;
 8
 9require __DIR__ . '/../vendor/autoload.php';
10
11// Загрузка переменных окружения
12$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
13$dotenv->load();
14
15$container = new Container();
16AppFactory::setContainer($container);
17
18$container->set('db', function() {
19    $host = $_ENV['DB_HOST'];
20    $db = $_ENV['DB_NAME'];
21    $user = $_ENV['DB_USER'];
22    $pass = $_ENV['DB_PASS'];
23    $charset = 'utf8mb4';
24
25    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
26    $options = [
27        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
28        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
29        PDO::ATTR_EMULATE_PREPARES   => false,
30    ];
31
32    try {
33        return new PDO($dsn, $user, $pass, $options);
34    } catch (\PDOException $e) {
35        throw new \PDOException($e->getMessage(), (int)$e->getCode());
36    }
37});
38
39$app = AppFactory::create();
40$app->add(SessionMiddleware::class);
41
42// Маршруты регистрации и авторизации  (как было описано ранее)
43
44// Получение данных о погоде с использованием API Nominatim и OpenWeatherMap
45$app->get('/weather/{city}', function (Request $request, Response $response, $args) {
46    $city = $args['city'];
47    $weatherApiKey = $_ENV['WEATHER_API_KEY'];
48    $nominatimUrl = "https://nominatim.openstreetmap.org/search?q={$city}&format=json&limit=1";
49
50    $client = new \GuzzleHttp\Client();
51    try {
52        // Запрос к Nominatim API для получения координат города
53        $nominatimResponse = $client->get($nominatimUrl);
54        $locationData = json_decode($nominatimResponse->getBody(), true);
55
56        if (empty($locationData)) {
57            $response->getBody()->write(json_encode(['error' => 'City not found']));
58            return $response->withStatus(404)->withHeader('Content-Type', 'application/json');
59        }
60
61        $latitude = $locationData[0]['lat'];
62        $longitude = $locationData[0]['lon'];
63
64        // Запрос к OpenWeatherMap API для получения данных о погоде по координатам
65        $weatherUrl = "http://api.openweathermap.org/data/2.5/weather?lat={$latitude}&lon={$longitude}&appid={$weatherApiKey}&units=metric";
66        $weatherResponse = $client->get($weatherUrl);
67        $weatherData = json_decode($weatherResponse->getBody(), true);
68
69        $response->getBody()->write(json_encode($weatherData));
70        return $response->withHeader('Content-Type', 'application/json');
71    } catch (\Exception $e) {
72        $response->getBody()->write(json_encode(['error' => 'Unable to fetch weather data']));
73        return $response->withStatus(500)->withHeader('Content-Type', 'application/json');
74    }
75});
76
77$app->run();

2. Тестирование интеграции с внешним API

Теперь, когда все маршруты и шаблоны настроены, вы можете протестировать интеграцию с внешним API.

  • Откройте браузер и перейдите по адресу http://localhost:8080/weather/London, чтобы увидеть текущую погоду в Лондоне.
← Лаб. работа "Массивы в PHP" Лаб. работа 1 "Создание нового приложения … →