You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Isso acontece porque se você passa uma função de stream como parâmetro de outra, o PHP automaticamente aplica a função `stream_copy_to_stream`. Você poderia fazer isso manualmente também:
Isso permite que você mexa com arquivos de 2GB tendo apenas 28MB de limite de memória no PHP, porque ele nunca terá o arquivo inteiro na memória, só um pequeno buffer que ele usa pra passar a corrente entre duas streams!
@@ -97,7 +107,10 @@ Além do `fpassthru`, é possível usar uma stream explícita:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A palavra _stream_ significa _corrente_. Em geral, qualquer conexão de rede é uma stream, e existem vários tipos de protocolos para streams. Esses protocolos definem como os dados fluem na corrente.
No PHP, [vários protocolos](http://www.php.net/manual/en/wrappers.php) são suportados de forma transparente:
No exemplo acima usamos a mesma função do PHP, a `file_get_contents` para obter o conteúdo de três arquivos em lugares diferentes suportados por protocolos diferentes. O PHP decide qual protocolo de stream usar pelo identificador de esquema `algo://`, se ele for omitido, cai para o padrão `file://`.
O mais legal disso é que **todas** as funções de arquivos e streams do PHP funcionam com todos os protocolos. Vejamos um exemplo mais legal:
A função `scandir` é uma das funções de arquivo, portanto ela é capaz de abstrair streams e varrer diretórios tanto locais quanto de um FTP remoto ou arquivo zipado.
Alguns protocolos suportam contextos. Eles são necessários pra trafegar mais informação sobre uma stream. O contexto pra HTTP por exemplo, entre os [diversos recursos que ele suporta](http://www.php.net/manual/en/context.http.php), permite definir cabeçalhos:
O exemplo acima obtém um arquivo de um HTTP mas identifica a conexão com um cabeçalho `User-Agent`. É possível enviar cabeçalhos de autenticação, cache, mudar o método para POST, DELETE ou qualquer outro e definir proxies.
Além disso, o PHP permite que você [crie seus próprios protocolos e os registre](http://php.net/stream_wrapper). Pessoas já criaram vários como esses pra mexer com arquivos no [Amazon S3](https://github.com/punkave/aS3StreamWrapper) e [repositórios Git](https://github.com/teqneers/PHP-Stream-Wrapper-for-Git) com funções simples como `file_get_contents` e `scandir`.
Outra coisa bastante surpreendente no suporte a streams é a auto-cópia. No exemplo abaixo, o `$arquivoHttp` é baixado inteiro para a memória antes de ser salvo:
Isso acontece porque se você passa uma função de stream como parâmetro de outra, o PHP automaticamente aplica a função `stream_copy_to_stream`. Você poderia fazer isso manualmente também:
Isso permite que você mexa com arquivos de 2GB tendo apenas 28MB de limite de memória no PHP, porque ele nunca terá o arquivo inteiro na memória, só um pequeno buffer que ele usa pra passar a corrente entre duas streams!
E se você quiser, é possível ir ainda mais longe com os filtros de stream. No exemplo acima nós copiamos um arquivo do HTTP direto pro disco, mas não é possível ver seu conteúdo. Com filtros de stream isso é possível. O exemplo abaixo baixa um arquivo de um FTP, converte tudo para maiúsculas e salva em um disco local:
Usei o filtro `string.toupper`, que é um dos padrões, mas você pode [registrar os seus próprios](http://www.php.net/manual/en/function.stream-filter-register.php).
Além de tudo, existem algumas streams específicas do PHP. O exemplo abaixo lê uma imagem gigante do disco e exibe ela no navegador sem carregá-la inteira na memória:
Além do `php://output` também existem outras [streams mágicas](http://www.php.net/manual/en/wrappers.php.php) do php.
E finalmente, streams são a única forma de fazer o PHP trabalhar de forma assíncrona! Isso é feito com a função `stream_select`, que se for usada em conexões não-bloqueantes, permite que as [streams sejam coletadas de forma assíncrona](http://wezfurlong.org/blog/2005/may/guru-multiplexing/).