Fluxos como Recursos

Todos os fluxos são registrados como recursos quando são criados. Isso assegura que eles serão apropriadamente limpos mesmo que ocorra um erro fatal. Todas as funções que lidam com o sistema de arquivos no PHP operam com recuros de fluxos - o que significa que suas extensões podem aceitar ponteiros de arquivo PHP normais, como parâmetros para a função e como parâmetros de retorno também. A API de fluxos faz esse processo da maneira mais suave possível:

Exemplo 63-2. Como aceitar um fluxo como parâmetro

PHP_FUNCTION(example_write_hello)
{
    zval *zstream;
    php_stream *stream;
    
    if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream))
        return;
    
    php_stream_from_zval(stream, &zstream);

    /* Agora você pode usar o fluxo. No entanto, você não "possui" o 
        fluxo, mas sim o script. Isso quer dizer que você NÃO DEVE fechar o
        fluxo, porque isso causará que o PHP sofra um crash! */

    php_stream_write(stream, "hello\n");
        
    RETURN_TRUE();
}

Exemplo 63-3. Como retornar um fluxo de uma função

PHP_FUNCTION(example_open_php_home_page)
{
    php_stream *stream;
    
    stream = php_stream_open_wrapper("http://www.php.net", "rb", REPORT_ERRORS, NULL);
    
    php_stream_to_zval(stream, return_value);

    /* a partir desse ponto, o fluxo é do script. 
        Fechá-lo resultará no PHP sofrendo um crash! */
}

Uma vez que fluxos são limpados automaticamente, é tentador achar que podemos ser programadores descuidados e não nos preocupar em limpar os fluxos quando terminamos com eles. Embora essa abordagem possa funcionar, não é uma boa idéia por um número de razões: fluxos de dados travam recursos do sistema enquanto abertos, então deixa um arquivo aberto após ter terminado de usá-lo pode fazer com que outros processos não possam acessá-lo. Se um script lida com um número grande de arquivos, a acumulação de recursos usados, ambos em termos de memória e de arquivos abertos, pode causar que a requisição ao servidor web falhe. Parece ruim, não é? A API de fluxos inclui algumas mágicas que ajudam você a manter o código limpo - se um fluxo não for fechado pelo seu código quando deveria, você encontrará algumas informações úteis para depuração no log de erro do servidor web.

Nota: Sempre use um binário com símbolos de depuração quando estiver desenvolvendo uma extensão (--enable-debug quando executar configure), já que vários esforços foram feitos para avisá-lo sobre vazamentos de memória e de fluxos.

Em alguns casos, é útil para manter o fluxo aberto durante toda duração da requisição, para agir como um registro (log) por exemplo. Escrever o código para limpar de maneira segura esse fluxo não é difícil, mas são várias linhas de código que não são necessárias. Para poupar o trabalho de escrever o código, você pode marcar um fluxo para auto limpeza. Isso significa que a API de fluxos não emitirá um aviso quando chegar a hora de limpar automaticamente um fluxo. Para isso, você pode usar a função php_stream_auto_cleanup().