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";

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.5.90.0270.00517.16
8.5.80.0230.00718.90
8.5.70.0190.00716.96
8.5.60.0180.00716.86
8.5.50.0160.00516.79
8.5.40.0190.00516.90
8.5.30.0180.00516.97
8.5.20.0250.00516.78
8.5.10.0250.00316.83
8.5.00.0060.00416.76
8.4.240.0030.00719.82
8.4.230.0230.00819.55
8.4.220.0270.00819.85
8.4.210.0130.00619.86
8.4.200.0150.00519.88
8.4.190.0130.00619.53
8.4.180.0140.00719.74
8.4.170.0150.00419.55
8.4.160.0130.00619.99
8.4.150.0180.00219.95
8.4.140.0100.01017.70
8.4.130.0160.00517.70
8.4.120.0180.00617.98
8.4.110.0210.00217.89
8.4.100.0190.00417.80
8.4.90.0180.00418.02
8.4.80.0170.00417.98
8.4.70.0150.00518.18
8.4.60.0170.00318.05
8.4.50.0150.00517.56
8.4.40.0160.00417.90
8.4.30.0130.00717.87
8.4.20.0180.00418.02
8.4.10.0150.00518.15
8.3.330.0160.00318.43
8.3.320.0140.00618.58
8.3.310.0170.00818.71
8.3.300.0220.00818.61
8.3.290.0170.00618.59
8.3.280.0140.00518.71
8.3.270.0140.00516.93
8.3.260.0160.00516.87
8.3.250.0150.00416.94
8.3.240.0140.00416.83
8.3.230.0210.00716.86
8.3.220.0170.00416.93
8.3.210.0170.00817.01
8.3.200.0150.00417.00
8.3.190.0240.00616.58
8.3.180.0180.00316.96
8.3.170.0220.00416.68
8.3.160.0160.00516.85
8.3.150.0210.00516.82
8.3.140.0160.00416.71
8.3.130.0140.00316.95
8.3.120.0120.00416.71
8.3.110.0110.00616.81
8.3.100.0130.00716.80
8.3.90.0160.00716.50
8.3.80.0170.00416.96
8.3.70.0180.00416.70
8.3.60.0170.00216.75
8.3.50.0160.00516.70
8.3.40.0140.00618.16
8.3.30.0140.00218.09
8.3.20.0120.00318.09
8.3.10.0140.00317.92
8.3.00.0120.00417.84
8.2.330.0120.00618.15
8.2.320.0130.00617.91
8.2.310.0140.00718.08

preferences:
51.71 ms | 832 KiB | 5 Q