Estava desenvolvendo uma class que abstrai algumas ações do file system do php, e fui tendo ideias durante a implementação de tal, no fim, esse foi o resultado:
<?php
declare(strict_types=1);classFile{private $file;private $type;function __construct(string $filePath){if(!file_exists($filePath)){thrownewInvalidArgumentException("Arquivo não localizado :(");}
$this->type = substr($filePath,-3);
$this->file = fopen($filePath,"a+");}function __destruct(){
fclose($this->file);}function write(string|array $data):int{return(match ($this->type){"txt"=>function()use($data){
$bytesWritten =0;if(is_string($data)){
$result = fwrite($this->file, $data . PHP_EOL);if($result ===false){thrownewRuntimeException("Erro ao tentar escrever no arquivo");}
$bytesWritten += $result;}else{foreach($data as $line){
$result = fwrite($this->file, $line . PHP_EOL);if($result ===false){thrownewRuntimeException("Erro ao tentar escrever no arquivo");}
$bytesWritten += $result;}}return $bytesWritten;},"csv"=>function()use($data){if(!is_array($data)){thrownewInvalidArgumentException("Para aquivos .csv, espera-se uma estrutura de array bidimensional");}
$bytesWritten =0;foreach($data as $line){if(!is_array($line)){thrownewInvalidArgumentException("Para aquivos .csv, espera-se uma estrutura de array bidimensional");}
$result = fwrite($this->file, implode(",", $line). PHP_EOL);if($result ===false){thrownewRuntimeException("Erro ao tentar escrever no arquivo");}
$bytesWritten += $result;}return $bytesWritten;},})();}function read():Generator{
rewind($this->file);return(match ($this->type){"txt"=>function():Generator{while(!feof($this->file)){
$line = fgets($this->file);if($line ===falseand!feof($this->file)){thrownewRuntimeException("Erro ao tentar ler o arquivo");}yield $line;}},"csv"=>function():Generator{while(!feof($this->file)){
$line = fgetcsv($this->file);if($line ===falseand!feof($this->file)){thrownewRuntimeException("Erro ao tentar ler o arquivo");}yield $line;}}})();}}
Utilizei o conceito de funções geradoras, aliado ao de funções auto-executáveis. E ao se observar bem, acabou por bagunçar um pouco o conceito fundamental de coroutines, que em cenários normais acontecem entre 2 funções. Na minha implementação, a função read() está no meio das ditas "2 funções":
function read():Generator{
rewind($this->file);return(match ($this->type){"txt"=>function():Generator{while(!feof($this->file)){
$line = fgets($this->file);if($line ===falseand!feof($this->file)){thrownewRuntimeException("Erro ao tentar ler o arquivo");}yield $line;}},"csv"=>function():Generator{while(!feof($this->file)){
$line = fgetcsv($this->file);if($line ===falseand!feof($this->file)){thrownewRuntimeException("Erro ao tentar ler o arquivo");}yield $line;}}})();}}
o forEach, implicitamente executa métodos da classe **Generator**, que permitem devolver a execução para a **função geradora read()**, mas nesse caso, a função geradora não é explicitamente a read(), mas sim a closure interna a ela. Daí acabei me confundindo um pouco, será que o php repassa a execução para a **função geradora read()**, que por sua vez devolve para sua closure internamente?
Pergunta
iNosuKe 么
Estava desenvolvendo uma class que abstrai algumas ações do file system do php, e fui tendo ideias durante a implementação de tal, no fim, esse foi o resultado:
Utilizei o conceito de funções geradoras, aliado ao de funções auto-executáveis. E ao se observar bem, acabou por bagunçar um pouco o conceito fundamental de coroutines, que em cenários normais acontecem entre 2 funções. Na minha implementação, a função read() está no meio das ditas "2 funções":
se executado:
o forEach, implicitamente executa métodos da classe **Generator**, que permitem devolver a execução para a **função geradora read()**, mas nesse caso, a função geradora não é explicitamente a read(), mas sim a closure interna a ela. Daí acabei me confundindo um pouco, será que o php repassa a execução para a **função geradora read()**, que por sua vez devolve para sua closure internamente?
Editado por iNosuKe 么Link para o comentário
Compartilhar em outros sites
5 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.