proclnas Posted September 10, 2017 Posted September 10, 2017 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: var_dump isset 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: splat operator - php.net func_num_args - php.net func_get_args - php.net StackOverflow - question1 StackOverflow - question2
Administrators Fernando Mercês Posted October 4, 2017 Administrators Posted October 4, 2017 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.
proclnas Posted October 7, 2017 Author Posted October 7, 2017 @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
Supporter - Nibble Lucas Rodrigues Posted October 8, 2017 Supporter - Nibble Posted October 8, 2017 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.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.