3v4l.org

run code in 500+ PHP versions simultaneously
<?php declare(strict_types=1); /** * ========================================================================== * SISTEMA BANCÁRIO FUNCIONAL COM DTOs IMUTÁVEIS E TYPE-SAFETY * ========================================================================== */ /** * -------------------------------------------------------------------------- * 1. IMUTABILIDADE & VALUE OBJECTS (Readonly DTOs) * -------------------------------------------------------------------------- */ readonly class Conta { public function __construct( public string $id, public float $saldo ) {} } readonly class Transacao { public function __construct( public string $idempotencyKey, public string $tipo, // 'DEPOSITO' ou 'SAQUE' public float $valor, public string $contaId ) {} } /** * NOVO: Objeto Tipado e Imutável de Estado do Processamento * Substitui o array associativo ['contas' => ..., 'chaves' => ...] * por uma estrutura totalmente segura quanto aos tipos. */ readonly class ResultadoProcessamento { /** * @param array<string, Conta> $contas * @param array<string> $chavesProcessadas */ public function __construct( public array $contas, public array $chavesProcessadas ) {} // Método auxiliar puramente funcional para gerar um novo estado atualizado public function comTransacao(Conta $novaConta, string $novaChave): self { return new self( contas: array_merge($this->contas, [$novaConta->id => $novaConta]), chavesProcessadas: array_merge($this->chavesProcessadas, [$novaChave]) ); } public function possuiChave(string $chave): bool { return in_array($chave, $this->chavesProcessadas, true); } } /** * -------------------------------------------------------------------------- * 2. PURE FUNCTIONS * -------------------------------------------------------------------------- */ function depositar(Conta $conta, float $valor): Conta { return new Conta($conta->id, $conta->saldo + $valor); } function sacar(Conta $conta, float $valor): Conta { if ($valor > $conta->saldo) { throw new InvalidArgumentException("Saldo insuficiente na conta {$conta->id}!"); } return new Conta($conta->id, $conta->saldo - $valor); } /** * -------------------------------------------------------------------------- * 3. PATTERN MATCHING (PHP 8 `match`) * -------------------------------------------------------------------------- */ function aplicarTransacao(Conta $conta, Transacao $tx): Conta { return match ($tx->tipo) { 'DEPOSITO' => depositar($conta, $tx->valor), 'SAQUE' => sacar($conta, $tx->valor), default => throw new InvalidArgumentException("Tipo de transação desconhecido: {$tx->tipo}") }; } /** * -------------------------------------------------------------------------- * 4. CURRYING * -------------------------------------------------------------------------- */ function criarValidadorValorMinimo(float $valorMinimo): callable { return fn(float $valor) => fn(callable $operacao) => $valor < $valorMinimo ? throw new InvalidArgumentException("Valor mínimo deve ser R$ {$valorMinimo}") : $operacao(); } /** * -------------------------------------------------------------------------- * 5. HIGHER-ORDER FUNCTIONS & REDUCE TIPADO * -------------------------------------------------------------------------- * Agora retorna a classe ResultadoProcessamento em vez de um array genérico. */ function processarComIdempotencia(array $contasIniciais, iterable $transacoes): ResultadoProcessamento { $listaTransacoes = is_array($transacoes) ? $transacoes : iterator_to_array($transacoes); $estadoInicial = new ResultadoProcessamento( contas: $contasIniciais, chavesProcessadas: [] ); return array_reduce( $listaTransacoes, function (ResultadoProcessamento $estado, Transacao $tx): ResultadoProcessamento { // Garantia de Idempotência via método do Objeto if ($estado->possuiChave($tx->idempotencyKey)) { echo "⚠️ [IDEMPOTÊNCIA] Transação {$tx->idempotencyKey} ignorada (já processada).\n"; return $estado; } $contaAtual = $estado->contas[$tx->contaId] ?? new Conta($tx->contaId, 0.0); $novaConta = aplicarTransacao($contaAtual, $tx); echo "✅ Transação {$tx->tipo} de R$ {$tx->valor} na conta {$tx->contaId} concluída. Saldo atual: R$ {$novaConta->saldo}\n"; // Retorna um novo DTO imutável return $estado->comTransacao($novaConta, $tx->idempotencyKey); }, $estadoInicial ); } /** * -------------------------------------------------------------------------- * 6. LAZY EVALUATION WITH GENERATORS * -------------------------------------------------------------------------- */ function gerarStreamTransacoes(): Generator { yield new Transacao('tx_key_001', 'DEPOSITO', 500.0, 'conta_A'); yield new Transacao('tx_key_002', 'SAQUE', 150.0, 'conta_A'); yield new Transacao('tx_key_001', 'DEPOSITO', 500.0, 'conta_A'); // Duplicada yield new Transacao('tx_key_003', 'DEPOSITO', 1000.0, 'conta_B'); yield new Transacao('tx_key_002', 'SAQUE', 150.0, 'conta_A'); // Duplicada } // ========================================================================== // EXECUÇÃO DO SCRIPT // ========================================================================== echo "=== INICIANDO SISTEMA BANCÁRIO FUNCIONAL ===\n\n"; $contas = [ 'conta_A' => new Conta('conta_A', 0.0), 'conta_B' => new Conta('conta_B', 100.0), ]; // Processamento com retorno totalmente tipado! echo "--- Processando Stream com DTO Tipado (ResultadoProcessamento) ---\n"; $resultadoFinal = processarComIdempotencia($contas, gerarStreamTransacoes()); // Exibição usando o DTO tipado echo "\n--- SALDO FINAL DAS CONTAS ---\n"; array_walk($resultadoFinal->contas, function (Conta $conta) { echo "Conta: {$conta->id} | Saldo Final: R$ {$conta->saldo}\n"; }); echo "\n--- HISTÓRICO DE CHAVES IDEMPOTENTES REGISTRADAS ---\n"; echo implode(", ", $resultadoFinal->chavesProcessadas) . "\n";
Output for git.master, git.master_jit
=== INICIANDO SISTEMA BANCÁRIO FUNCIONAL === --- Processando Stream com DTO Tipado (ResultadoProcessamento) --- ✅ Transação DEPOSITO de R$ 500 na conta conta_A concluída. Saldo atual: R$ 500 ✅ Transação SAQUE de R$ 150 na conta conta_A concluída. Saldo atual: R$ 350 ⚠️ [IDEMPOTÊNCIA] Transação tx_key_001 ignorada (já processada). ✅ Transação DEPOSITO de R$ 1000 na conta conta_B concluída. Saldo atual: R$ 1100 ⚠️ [IDEMPOTÊNCIA] Transação tx_key_002 ignorada (já processada). --- SALDO FINAL DAS CONTAS --- Fatal error: Uncaught Error: Cannot indirectly modify readonly property ResultadoProcessamento::$contas in /in/SYLmi:177 Stack trace: #0 {main} thrown in /in/SYLmi on line 177
Process exited with code 255.

This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.

Active branches

Archived branches

Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page


preferences:
44.84 ms | 832 KiB | 4 Q