Skip to content

Repository files navigation

Constructo

O serializador e deserializador definitivo para PHP

Versão PHPLicençaComposer

Constructo é uma poderosa biblioteca PHP que fornece capacidades avançadas de serialização e deserialização para objetos PHP. Ela permite conversão perfeita entre objetos e arrays/JSON, com suporte para estruturas aninhadas complexas, conversão de tipos, validação e formatação personalizada.

🚀 Funcionalidades

  • Conversão Bidirecional: Serialize objetos para arrays/JSON e deserialize de volta para objetos tipados
  • Segurança de Tipos: Suporte completo ao sistema de tipos do PHP 8.3+ incluindo union types, backed enums e propriedades readonly
  • Mapeamento Inteligente: Mapeamento automático de propriedades com conversão de snake_case para camelCase
  • Formatadores Personalizados: Sistema de formatação extensível para transformações de dados customizadas
  • Objetos Aninhados: Manipule hierarquias de objetos complexas e coleções perfeitamente
  • Tratamento de Erros: Relatório de erros abrangente com contexto detalhado
  • Validação: Validação integrada com suporte a atributos personalizados
  • Manipulação de Data/Hora: Análise e formatação inteligente de DateTime
  • Coleções: Suporte de primeira classe para coleções tipadas
  • Injeção de Dependência: Resolução automática de dependência para construção de objetos

📦 Instalação

Instale o Constructo via Composer:

composer require devitools/constructo

Requisitos

  • PHP 8.3 ou superior
  • ext-json

🔧 Início Rápido

Serialização simples e rápida

<?php# ...useConstructo\Core\Serialize\Builder;
useConstructo\Support\Set;
useConstructo\Type\Timestamp;
// Defina sua entidade informando os valores das propriedades no construtorreadonlyclass User
{
publicfunction__construct(
publicint$id,
publicstring$name,
publicTimestamp$birthDate,
publicbool$isActive = true,
publicarray$tags = [],
) {}
}
// Monte um set com os dados (de JSON, banco de dados, etc.)$set = Set::createFrom([
'id' => 1,
'name' => 'João Silva',
'birth_date' => '1981-08-13',
'is_active' => true,
'tags' => ['nice', 'welcome'],
]);
// Crie um novo builder e use-o para construir o objeto$user = (newBuilder())->build(User::class, $set);
echo"Usuário: \n";
echosprintf(" ID: %s\n", $user->id);
echosprintf(" Nome: %s\n", $user->name);
echosprintf(" Ativo: %s\n", $user->isActive);
echosprintf(" Tags: %s\n", implode(', ', $user->tags));
echosprintf(" Data de Nascimento: %s\n", $user->birthDate->format('Y-m-d'));

Desserialização prática e direta

<?phpuseConstructo\Core\Deserialize\Demolisher;
// Crie uma instância$user = newUser(1, 'João Silva', 'joao@exemplo.com', true, ['admin', 'usuario']);
// Serialize para objeto/array$demolisher = newDemolisher();
$data = $demolisher->demolish($user);
echojson_encode($data);
// Saída: {"id":1,"name":"João Silva","email":"joao@exemplo.com","isActive":true,"tags":["admin","usuario"]}

📋 Uso Avançado do Builder

Formatadores Personalizados no Builder

Constructo suporta formatadores personalizados para transformação de dados durante a deserialização:

<?phpuseConstructo\Core\Serialize\Builder;
// Formatador personalizado para arraysclass ArrayFormatter
{
publicfunction__invoke($value)
{
returnis_string($value) ? json_decode($value, true) : $value;
}
}
// Use com Builder$builder = newBuilder(formatters: [
'array' => newArrayFormatter(),
]);
$data = [
'id' => 1,
'name' => 'Maria Santos',
'tags' => '["desenvolvedor", "php"]'// String JSON será convertida para array
];
$user = $builder->build(User::class, Set::createFrom($data));
echoimplode(', ', $user->tags); // "desenvolvedor, php"

Objetos Aninhados Complexos com Builder

<?phpclass Address extends Entity
{
publicfunction__construct(
publicreadonlystring$street,
publicreadonlystring$city,
publicreadonlystring$country
) {}
}
class User extends Entity
{
publicfunction__construct(
publicreadonlyint$id,
publicreadonlystring$name,
publicreadonlyAddress$address,
publicreadonly ?DateTime$createdAt = null
) {}
}
// Dados aninhados$data = [
'id' => 1,
'name' => 'João Silva',
'address' => [
'street' => 'Rua Principal, 123',
'city' => 'São Paulo',
'country' => 'Brasil'
],
'created_at' => '2023-01-15T10:30:00+00:00'
];
$builder = newBuilder();
$user = $builder->build(User::class, Set::createFrom($data));
echo$user->address->city; // "São Paulo"echo$user->createdAt->format('d/m/Y'); // "15/01/2023"

Suporte a Backed Enums com Builder

<?phpenum Status: string
{
caseACTIVE = 'ativo';
caseINACTIVE = 'inativo';
casePENDING = 'pendente';
}
class Order extends Entity
{
publicfunction__construct(
publicreadonlyint$id,
publicreadonlyStatus$status,
publicreadonlyfloat$amount
) {}
}
$data = [
'id' => 1,
'status' => 'ativo', // String será convertida para enum'amount' => 99.99
];
$builder = newBuilder();
$order = $builder->build(Order::class, Set::createFrom($data));
echo$order->status->value; // "ativo"

Tratamento de Erros com Datum

Quando a deserialização falha, o Constructo fornece informações detalhadas de erro:

<?phpuseConstructo\Support\Datum;
useConstructo\Exception\AdapterException;
try {
$result = $builder->build(User::class, Set::createFrom($invalidData));
} catch (AdapterException$e) {
// Crie um objeto Datum com detalhes do erro$datum = newDatum($e, $invalidData);
$errorData = $datum->export();
// Contém dados originais mais '@error' com detalhes da exceção
}

📋 Uso Avançado do Demolisher

Formatadores Personalizados no Demolisher

<?phpuseConstructo\Core\Deserialize\Demolisher;
// Formatador de string personalizado$stringFormatter = fn($value) => sprintf('[%s]', $value);
// Use com Demolisher$demolisher = newDemolisher(formatters: [
'string' => $stringFormatter,
]);
$user = newUser(1, 'Ana Costa', 'ana@exemplo.com');
$data = $demolisher->demolish($user);
echo$data->name; // "[Ana Costa]"

Trabalhando com Coleções

<?phpuseConstructo\Contract\Collectable;
useConstructo\Type\Collection;
class UserCollection extends Collection implements Collectable
{
protectedfunctiongetItemClass(): string
{
return User::class;
}
}
// Serialize coleção$collection = newUserCollection();
$collection->push($user1);
$collection->push($user2);
$demolisher = newDemolisher();
$arrayData = $demolisher->demolishCollection($collection);

🛠️ Funções Utilitárias

Constructo inclui várias funções utilitárias para operações comuns:

Helpers JSON

<?phpusefunctionConstructo\Json\decode;
usefunctionConstructo\Json\encode;
$array = decode('{"name":"João","age":30}');
$json = encode(['name' => 'João', 'age' => 30]);

Conversão de Tipos

<?phpusefunctionConstructo\Cast\arrayify;
usefunctionConstructo\Cast\stringify;
$array = arrayify($data); // Converte para array com segurança$string = stringify($value); // Converte para string com segurança

Extração de Dados

<?phpusefunctionConstructo\Util\extractString;
usefunctionConstructo\Util\extractInt;
usefunctionConstructo\Util\extractBool;
usefunctionConstructo\Util\extractArray;
$name = extractString($data, 'name', 'padrão');
$age = extractInt($data, 'age', 0);
$active = extractBool($data, 'is_active', false);
$tags = extractArray($data, 'tags', []);

🧪 Extensões de Teste

Constructo fornece utilitários de teste para facilitar os testes:

<?phpuseConstructo\Testing\BuilderExtension;
useConstructo\Testing\MakeExtension;
usePHPUnit\Framework\TestCase;
class MyTest extends TestCase
{
use BuilderExtension, MakeExtension;
publicfunctiontestSerialization(): void
{
$user = $this->builder()->build(User::class, Set::createFrom($data));
$this->assertInstanceOf(User::class, $user);
}
}

📚 Conceitos Centrais

Classe Base Entity

Estenda a classe Entity para obter suporte automático de serialização:

<?phpuseConstructo\Support\Entity;
class MyEntity extends Entity
{
// Automaticamente implementa Exportable e JsonSerializable// Fornece método export() que retorna objeto com todas as propriedades públicas
}

Classe Set

A classe Set é usada para gerenciar coleções de dados com segurança de tipos:

<?phpuseConstructo\Support\Set;
$set = Set::createFrom(['key' => 'valor']);
$set = newSet(['key' => 'valor']);
$value = $set->get('key', 'padrão');
$array = $set->toArray();

Classe Value

Para manipular valores individuais com validação e transformação:

<?phpuseConstructo\Support\Value;
$value = newValue('alguns dados');
// Fornece vários métodos para manipulação e validação de valores

🔍 Funcionalidades Avançadas

Geração de Schema

Constructo pode gerar schemas para seus objetos:

<?phpuseConstructo\Factory\SchemaFactory;
useConstructo\Factory\DefaultSpecsFactory;
$schemaFactory = newSchemaFactory(newDefaultSpecsFactory());
$schema = $schemaFactory->make();

Reflexão e Metadados

Capacidades avançadas de reflexão para introspecção de objetos:

<?phpuseConstructo\Support\Reflective\Engine;
useConstructo\Factory\ReflectorFactory;
$reflectorFactory = newReflectorFactory();
$reflector = $reflectorFactory->make();

Cache

Suporte integrado de cache para melhor performance:

<?phpuseConstructo\Support\Cache;
$cache = newCache();
// Fornece mecanismos de cache para dados de reflexão e schemas

🤝 Contribuindo

Contribuições são bem-vindas! Sinta-se à vontade para enviar um Pull Request. Para mudanças importantes, abra primeiro uma issue para discutir o que você gostaria de alterar.

Configuração de Desenvolvimento

  1. Clone o repositório
  2. Instale as dependências: composer install
  3. Execute os testes: composer test
  4. Execute o linting: composer lint:phpcs
  5. Execute análise estática: composer lint:phpstan

Ferramentas de Qualidade de Código

O projeto usa várias ferramentas de qualidade de código:

  • PHPUnit para testes
  • PHPStan para análise estática
  • PHP_CodeSniffer para estilo de código
  • PHPMD para detecção de bagunça
  • Psalm para análise estática adicional
  • Rector para modernização de código

📄 Licença

Este projeto está licenciado sob a Licença MIT - veja o arquivo LICENSE para detalhes.

🏢 Sobre a Devitools

Constructo é desenvolvido e mantido pela Devitools. Nós nos especializamos em criar ferramentas de desenvolvimento poderosas e bibliotecas para aplicações web modernas.


Para mais informações e exemplos de uso avançado, visite nossa documentação em devi.tools/constructo.

Releases

Packages

Contributors

Languages