Ir para conteúdo

[PHP] Splat Operator


proclnas

Posts Recomendados

Olá guys, tudo em ordem?
Meu primeiro post aqui no mente binária, que inclusive foca em php e que provavelmente irá ajudar aqueles que se aventuram
na linguagem. Boa leitura! ;)

Em alguns momentos pode surgir a necessidade de se criar um método/função com argumentos variáveis. O próprio php possui funções que aceitam “n” argumentos, como por ex:

Entre outros. A partir da versão 5.6 do PHP é possível utilizar o “splat operator (…)” que nos da a capacidade de criar método/funções com argumentos variáveis, entre outras coisas. Ex:

<?php

function evaluateString($callback, ...$strings) {
    $myStr = 'INITIAL: ';
    foreach ($strings as $stringPiece) {
        $myStr .= $stringPiece;
    }
    return call_user_func($callback, $myStr);
}

$strAllUp = evaluateString(
    'strtoupper',
    'rodrigo',
    ' nascimento'
);

var_dump($strAllUp);
// Saída: string(27) "INITIAL: RODRIGO NASCIMENTO"

 

Ex de utilização:

<?php 

function soma(...$numbers) { 
    var_dump($numbers, count($numbers)); 
} 

soma(1, 2, 3, 4); // Saída
array(4) { 
    [0]=> int(1) 
    [1]=> int(2) 
    [2]=> int(3) 
    [3]=> int(4) 
} 

int(4) // Quantidade de parâmetros recebidos pela função

 

A partir dai podemos fazer algumas operações. Uma soma por exemplo utilizando o mesmo código acima:

<?php 

function soma(...$numberss) { 
    return array_sum($numbers); 
} 

var_dump(soma(5, 5, 5, 5)); 

// Saída
int(20)

 

E em alguns casos mais complexos podemos até fazer operações mais distintas:

Consulta de arquivos:

<?php 

function checkFiles(...$files) { 
    return array_map(function($file){ 
        return [$file => file_exists($file) ? 'Found' : 'Not found']; 
    }, $files); 
} 

$busca = checkFiles(
    '1.txt', 
    'about.md', 
    'ex.php', 
    'foo.php'
); 

foreach ($busca as $arquivos) { 
    foreach ($arquivos as $nomeArquivo => $status) 
        echo sprintf('%s => %s' . PHP_EOL, $nomeArquivo, $status); 
} 

// Saída
1.txt => Not found 
about.md => Found 
ex.php => Found 
foo.php => Not found

 

OBS: O exemplo acima é somente um exemplo e não visa substituir as capacidades nativas do php! (Não me diga…)
(Nativamente o php trabalha mto bem com arquivos: GlobIterator entre outros…)

Requisições http, gerar logs, etc:

<?php 

function gerarLogs(...$urls) { 
    array_walk($urls, function($url) { 
        // lógica aqui... Requisições http, etc
        echo sprintf('[+] Gerando logs para: %s' . PHP_EOL, $url); 
    }); 
} 

gerarLogs(
    'http://www.google.com', 
    'http://php.net', 
    'http://theuselessweb.com'
); 

// Output
[+] Gerando logs para: http://www.google.com 
[+] Gerando logs para: http://php.net 
[+] Gerando logs para: http://theuselessweb.com

 

Utilizando type hinting com splat operator

É possível especificar os tipos de argumentos esperados pela função utilizando type hiting normalmente:

<?php 

function expectCarObject(Car ...$cars) { 
    foreach ($cars as $car) { 
        var_dump($car); 
    } 
} 

class Car {} 
expectCarObject(new Car, new Car, new Car); 

// Saida
object(Car)#1 (0) {
} 
object(Car)#2 (0) {
} 
object(Car)#3 (0) {
}

 

Caso seja passado parâmetros diferentes do tipo “Car” um fatal error será emitido pelo php.

Unpacking de argumentos

Com splat operator é possível também fazer unpacking de argumentos, o que significa que é possível escrever algo como:

<?php 

function soma($numA, $numB) { 
    return $numA + $numB; 
} 

$nums = [1, 2]; 
var_dump(soma(...$nums)); 

// Saída:
int(3)

 

Os exemplos estão longe de serem algo definitivo. Da próxima vez que for criar uma classe útil que possui métodos flexíveis, de uma chance ao splat operator.
Dúvidas, sugestões, tomar uma breja? Deixe seu comentário!
Forte abraço!

Referências:

Link para o comentário
Compartilhar em outros sites

  • 4 semanas depois...

Bem-vindo, @proclnas!

Incrível esse post. Não sabia que dava pra fazer isso em PHP. Em C sei que é possível (a própria printf() é um exemplo), no entanto.

Agora, consegue pensar em uma situação onde isso seria mais vantajoso que receber um array diretamente, na função?

Abraço.

Link para o comentário
Compartilhar em outros sites

@Fernando Mercês, obrigado pelas boas vindas!

A utilização do splat operator ajuda mto na portabilidade do código, o que significa que tiramos a responsabilidade do "caller" e deixamos
por conta da função/método o tratamento dos dados.
Lembrando sempre que cada caso uma necessidade, então vale a pena dar uma rabiscada antes pra ver se vale realmente a pena.
Ahh... É muito comum vermos em frameworks esse tipo de prática. ;)
 

<?php

function validateMail(...$hosts) {
    return array_filter($hosts, 'isValidMail');    
}

// Chamadas
validateMail('foo@mentebinaria.com.br');
validateMail(['foo@mentebinaria.com.br'. 'bar@mentebinaria.com.br']);


Abraço

Link para o comentário
Compartilhar em outros sites

  • Apoiador Nibble

Isso é extremamente útil para funções como o mysqli_stmt_bind_param, nativo do PHP.

$array = ['Um', 'Dois', 'Tres', 4];

$stmt = mysqli_prepare($link, "INSERT INTO Tabela VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', ...$array);

mysqli_stmt_execute($stmt);

 

Assim você pode usar um array direto no mysqli_stms_bind_param, devido ao uso do ...$array. ;)

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...