Git Product home page Git Product logo

kingson-de / marshal-serializer Goto Github PK

View Code? Open in Web Editor NEW
2.0 1.0 3.0 244 KB

Marshal is serializing / marshalling data structures to the desired format. It is also deserializing / unmarshalling the format back to the data structures.

License: Apache License 2.0

PHP 100.00%
serializer marshalling serialization json webservice response mapping mappers marshal serialization-library xml json-serialization xml-serialization deserializer unmarshalling php

marshal-serializer's Introduction

Marshal Serializer

Marshal Serializer logo

License Build Status Code Coverage Scrutinizer Code Quality

Introduction

Marshal is serializing / marshalling data structures to the desired format. It is also deserializing / unmarshalling the format back to the data structures.

Especially useful for building the raw response for web services which then can be formatted to JSON for example.

If you need to serialize directly to a format, use the appropriate Marshal library:

Installation

Easiest way to install the library is via composer:

composer require kingson-de/marshal-serializer

The following PHP versions are supported:

  • PHP 7.0
  • PHP 7.1
  • PHP 7.2
  • PHP 7.3

Execute tests

Just run:

composer test

Or without code coverage:

composer quicktest

Usage

Mappers

The first thing to do is to create a mapper that takes care of mapping your entities / models to the correct format.

You always need to inherit from the abstract Mapper class and implement a map function with your type hinting.

There is also the option to use directly a callable to map data. This will be explained later.

It is always possible to use a callable in a mapper or vice versa.

<?php

use KingsonDe\Marshal\AbstractMapper;

class UserMapper extends AbstractMapper {

    public function map(User $user) {
        return [
            'username'  => $user->getUsername(),
            'email'     => $user->getEmail(),
            'birthday'  => $user->getBirthday()->format('Y-m-d'),
            'followers' => count($user->getFollowers()),
        ];
    }
}

Data Structures

Next step is to create the desired data structure either being an item/object or a collection.

Item/Object

<?php

use KingsonDe\Marshal\Data\Item;

$item = new Item(new UserMapper(), $user);

Collection

<?php

use KingsonDe\Marshal\Data\Collection;

$userCollection = [$user1, $user2, $user3];
$item           = new Collection(new UserMapper(), $userCollection);

Serializing / Marshalling

The final step is to map the data structures to the actual format.

<?php

use KingsonDe\Marshal\Marshal;

$data = Marshal::serialize($item);

You are also not forced to create data structures on your own, you can use the appropriate Marshal functions instead:

<?php

use KingsonDe\Marshal\Marshal;

$data = Marshal::serializeItem($mapper, $model);
// or
$data = Marshal::serializeCollection($mapper, $modelCollection);
// or 
$data = Marshal::serializeCollectionCallable(function (User $user) {
    return [
        'username'  => $user->getUsername(),
        'email'     => $user->getEmail(),
        'birthday'  => $user->getBirthday()->format('Y-m-d'),
        'followers' => count($user->getFollowers()),
    ];
}, $modelCollection);

Symfony Example

<?php

use KingsonDe\Marshal\Data\Item;
use KingsonDe\Marshal\Marshal;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;

class UserController extends Controller {

    public function indexAction(User $user) {
        $item = new Item(new UserMapper(), $user);
        $data = Marshal::serialize($item);
        
        return new JsonResponse($data);
    }
}

Advanced Mappers

Nested Data Structures

Mappers can even include other mappers with different data structures.

Therefore you can use item, itemCallable, collection or collectionCallable function from the AbstractMapper class.

<?php

use KingsonDe\Marshal\AbstractMapper;

class UserMapper extends AbstractMapper {

    public function map(User $user) {
        return [
            'username'  => $user->getUsername(),
            'email'     => $user->getEmail(),
            'birthday'  => $user->getBirthday()->format('Y-m-d'),
            'followers' => $this->collection(new FollowerMapper(), $user->getFollowers),
            'location'  => $this->item(new LocationMapper(), $user->getLocation()),
        ];
    }
}

Pass as many parameters as you like to the mappers

<?php

use KingsonDe\Marshal\Data\Item;
use KingsonDe\Marshal\Marshal;

$item = new Item(new UserMapper(), $user, $followers, $location);
$data = Marshal::serialize($item);
<?php

use KingsonDe\Marshal\AbstractMapper;

class UserMapper extends AbstractMapper {

    public function map(User $user, FollowerCollection $followers, Location $location) {
        return [
            'username'  => $user->getUsername(),
            'email'     => $user->getEmail(),
            'birthday'  => $user->getBirthday()->format('Y-m-d'),
            'followers' => $this->collection(new FollowerMapper(), $followers),
            'location'  => $this->item(new LocationMapper(), $location),
        ];
    }
}

For collections the first parameter passed is the one which Marshal will use for iterating.

All other parameters in a collection will stay as it is.

For items/objects all parameters retain.

Filter out single item's from the collection

Collection mappers can discard single item's by returning null.

<?php

use KingsonDe\Marshal\AbstractMapper;

class UserMapper extends AbstractMapper {

    public function map(User $user) {
        if ($user->isPrivate()) {
            return null;
        }
    
        return [
            'username' => $user->getUsername(),
        ];
    }
}

Deserializing / Unmarshalling

To transform the actual format back to your structure use Marshal's deserialize functions. You need a class extending the AbstractObjectMapper which will be passed to the deserialize function.

<?php

use KingsonDe\Marshal\AbstractObjectMapper;
use KingsonDe\Marshal\Data\FlexibleData;
use KingsonDe\Marshal\Example\Model\User;

class UserObjectMapper extends AbstractObjectMapper {

    /**
     * @inheritdoc
     *
     * @return User
     */
    public function map(FlexibleData $flexibleData, ...$additionalData) {
        return new User(
            $flexibleData['id'] ?? 0,
            $flexibleData['email'] ?? '',
            $flexibleData->find('username', '')
        );
    }
}
<?php

use KingsonDe\Marshal\Marshal;

$data = Marshal::serializeItem(new UserMapper(), $user);

$user = Marshal::deserialize(new UserObjectMapper(), $data);

Another option would be to use the deserializeCallable function.

<?php

use KingsonDe\Marshal\Marshal;

$data = Marshal::serializeItem(new UserMapper(), $user);

$user = Marshal::deserializeCallable(function (FlexibleData $flexibleData) {
    return new User(
        $flexibleData->get('id'),
        $flexibleData->get('email'),
        $flexibleData->get('username')
    );
}, $data);

License

This project is released under the terms of the Apache 2.0 license.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.