<MyRusakov.ru />

Создание игр на Unreal Engine 5

Создание игр на Unreal Engine 5

Данный курс научит Вас созданию игр на Unreal Engine 5. Курс состоит из 12 модулей, в которых Вы с нуля освоите этот движок и сможете создавать самые разные игры.

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

Помимо самого курса Вас ждёт ещё 8 бесплатных ценных Бонусов: «Chaos Destruction», «Разработка 2D-игры», «Динамическая смена дня и ночи», «Создание динамической погоды», «Создание искусственного интеллекта для NPC», «Создание игры под мобильные устройства», «Создание прототипа RPG с открытым миром» и и весь курс «Создание игр на Unreal Engine 4» (актуальный и в 5-й версии), включающий в себя ещё десятки часов видеоуроков.

Подробнее
Подписка

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

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

Автоматическое конвертирование JSON в PHP-объекты

Автоматическое конвертирование JSON в PHP-объекты

Доброго времени суток! В данной статье я покажу Вам один из способов автоматической конвертации JSON строки в объекты PHP. Т.е. представим следующую ситуацию - у нас есть некий API-сервис (в нашем примере Jsonplaceholder), запросы к которому отдают ответы в JSON-формате. Эти ответы потом нужно преобразовать в нечто такое, с чем мы дальнейшем можем работать в PHP. Но благодаря библиотеке square/pjson и аттрибутам PHP мы можем максимально автоматизировать этот процесс.

Итак, структура проекта следующая:


.
├── src
│   ├── Api
│   │   ├── Api.php
│   │   ├── Endpoint.php
│   │   ├── PhotosEndpoint.php
│   │   ├── PostEndpoint.php
│   │   └── UserEndpoint.php
│   ├── Objects
│   │   ├── Address.php
│   │   ├── Comment.php
│   │   ├── Company.php
│   │   ├── Geo.php
│   │   ├── Photo.php
│   │   ├── Post.php
│   │   └── User.php
│   └── index.php
├── composer.json
├── composer.lock


В папке src/Api у нас будут классы отвечающие за сетевое общение с разными сущностями, будь то статья (Post), пользователь (User) и т.д. В папке src/Objects - сами объекты, в которые мы будем конвертировать JSON-ответ.

Итак, разберем содержимое каждой папки по порядку.

src/Objects/Post.php


<?php

namespace Objects;

// импортируем классы из библиотеки
use Square\Pjson\Json;
use Square\Pjson\JsonSerialize;

class Post
{
    // добавляем методы из трейта в класс Post
    use JsonSerialize;

    // каждое свойство класса Post соответствует свойству из JSON ответа
    // аттрибут #[Json] обязателен 
    #[Json]
    public int $id;

    #[Json]
    public int $userId;

    #[Json]
    public string $title;

    #[Json]
    public string $body;
}

Класс выше описывает следующий JSON-ответ:


{
    "id": 1,
    "userId": 1,
    "title": "Post title",
    "body": "Post text"
}


Т.е. как видно из примера, когда мы получим ответ от сервера, значения полей этого JSON-ответа станут значениями полей класса автоматически. Причем, типы данных полей класса могут быть не только встроенными в PHP типами, но и пользовательскими типами - классами. Пример ниже:


// User.php

<?php

namespace Objects;


use Square\Pjson\Json;
use Square\Pjson\JsonSerialize;


class User
{
    use JsonSerialize;

    #[Json]
    public int $id;

    #[Json]
    public string $name;

    #[Json]
    public string $username;

    #[Json]
    public string $email;

    #[Json]
    public Address $address;

    #[Json]
    public string $phone;

    #[Json]
    public string $website;

    #[Json]
    public Company $company;
}


class Company
{
    use JsonSerialize;

    #[Json]
    public string $name;

    #[Json]
    public string $catchPhrase;

    #[Json]
    public string $bs;
}


class Address
{
    use JsonSerialize;

    #[Json]
    public string $street;

    #[Json]
    public string $suite;

    #[Json]
    public string $city;

    #[Json]
    public string $zipcode;

    #[Json]
    public Geo $geo;
}

class Geo
{
    use JsonSerialize;

    #[Json]
    public float $lat;

    #[Json]
    public float $lng;
}

Теперь рассмотрим классы, отвечающие за взаимодействие с сетью и преобразование JSON-ответов в соответствуюшие объекты. Базовый класс Api\Endpoint заключает в себе базовую логику работы с сетью. В его задачи входит обратиться к удаленному серверу и получить JSON-ответ.

src/Api/Endpoint.php


<?php

namespace Api;

use Exception;
use Objects\Comment;
use Objects\Photo;
use Objects\Post;


class Endpoint
{
    /**
     * @throws Exception
     */
    protected function endpoint(string $part): bool|string
    {
        $url = sprintf('%s/%s', 'https://jsonplaceholder.typicode.com', $part);
        return $this->fetch($url);
    }

    /**
     * @throws Exception
     */
    private function fetch($uri): string
    {
        $handle = curl_init();

        curl_setopt($handle, CURLOPT_URL, $uri);
        curl_setopt($handle, CURLOPT_POST, false);
        curl_setopt($handle, CURLOPT_HEADER, true);
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 10);

        $response      = curl_exec($handle);
        $headerLength  = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
        $httpCode      = curl_getinfo($handle, CURLINFO_HTTP_CODE);
        $body          = substr($response, $headerLength);

        if ($httpCode != 200) {
            throw new Exception('Network problem', $httpCode);
        }

        return $body;
    }
}

Остальные классы из пространства Api наследуются от него:

Api\PhotosEndpoint


<?php

namespace Api;

use Exception;
use Objects\Photo;

class PhotosEndpoint extends Endpoint
{

    /**
     * @return array<Photo>
     * @throws Exception
     */
    public function getPhotos(int $limit = 10): array
    {
        return array_slice(Photo::listFromJsonString($this->endpoint('photos')), 0, $limit);
    }

}

Api\PostEndpoint


<?php

namespace Api;

use Exception;
use Objects\Comment;
use Objects\Post;

class PostEndpoint extends Endpoint
{
    /**
     * @return array<Post>
     * @throws Exception
     */
    public function getPosts(int $limit = 10): array
    {
        return array_slice(Post::listFromJsonString($this->endpoint('posts')), 0, $limit);
    }

    /**
     * @param int $id
     * @return Post
     * @throws Exception
     */
    public function getPost(int $id): Post
    {
        return Post::fromJsonString($this->endpoint(sprintf('posts/%d', $id)));
    }


    /**
     * @return array<Comment>
     * @throws Exception
     */
    public function getPostComments(int $id): array
    {
        return Comment::listFromJsonString($this->endpoint(sprintf('posts/%d/comments', $id)));
    }
}

Также есть класс Api\Api, который используется как центральное место для доступа ко всем API-endpoint:


<?php

namespace Api;


class Api
{
    public static function posts()
    {
        return new PostEndpoint();
    }

    public static function photos()
    {
        return new Endpoint();
    }

    public static function users()
    {
        return new UserEndpoint();
    }
}

Вызывается все это дело следующим образом:


<?php

require_once __DIR__ . '/../vendor/autoload.php';


function m_print(string ...$messages): void
{
    foreach ($messages as $message) {
        print $message;
        print PHP_EOL;
    }
    print PHP_EOL;
    print '++++++++++++++++++++++++++++++++' . PHP_EOL;
}


(function()
{
    try {

        $user = \Api\Api::users()->getUser(1);

        m_print($user->toJson(JSON_PRETTY_PRINT));

        m_print('Address', $user->address->toJson(JSON_PRETTY_PRINT));

        m_print('Address.Geo', $user->address->geo->toJson(JSON_PRETTY_PRINT));

        m_print('Company', $user->company->toJson(JSON_PRETTY_PRINT));
    }
    catch (Exception $e)
    {
        if(404 === $e->getCode()) print($e->getMessage());
    }


})();





Результат:


$ php src/index.php
{
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "[email protected]",
    "address": {
        "street": "Kulas Light",
        "suite": "Apt. 556",
        "city": "Gwenborough",
        "zipcode": "92998-3874",
        "geo": {
            "lat": -37.3159,
            "lng": 81.1496
        }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
        "name": "Romaguera-Crona",
        "catchPhrase": "Multi-layered client-server neural-net",
        "bs": "harness real-time e-markets"
    }
}

++++++++++++++++++++++++++++++++
Address
{
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
        "lat": -37.3159,
        "lng": 81.1496
    }
}

++++++++++++++++++++++++++++++++
Address.Geo
{
    "lat": -37.3159,
    "lng": 81.1496
}

++++++++++++++++++++++++++++++++
Company
{
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
}

++++++++++++++++++++++++++++++++


Таким образом, с помощью библиотеки square/pjson можно сделать автоматическое преобразование JSONPHP Objects, при этом заметьте, что в Api реализованы только GET-методы, тогда как там же можно добавить еще методы POST, DELETE и другие.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

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

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.