proclnas Posted September 10, 2017 at 08:54 PM Share Posted September 10, 2017 at 08:54 PM 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 Link to comment Share on other sites More sharing options...
Fernando Mercês Posted October 4, 2017 at 05:58 AM Share Posted October 4, 2017 at 05:58 AM 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 to comment Share on other sites More sharing options...
proclnas Posted October 7, 2017 at 09:23 PM Author Share Posted October 7, 2017 at 09:23 PM @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 to comment Share on other sites More sharing options...
Supporter - Nibble Lucas Rodrigues Posted October 8, 2017 at 07:57 PM Supporter - Nibble Share Posted October 8, 2017 at 07:57 PM 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 to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.