Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
11
respostas

Dúvida sobre filtro personalizado

1)Quando fizemos:

public function filter($in, $out, &$consumed, bool $closing)
    {
        while($bucket = stream_bucket_make_writeable($in))
        {
            $linhas = explode("\n", $bucket->data);
        }
    }

Se o arquivo vier com strings tudo numa linha só, como o filtro ia entender onde ele tem que colocar a quebra de linha?

2) Quando fizemos:

public function onCreate()
    {
        $this->stream = fopen('php://temp', 'w+');

        return $this->stream !== false;
    }

Na linha do return, o que foi feito ali é como se fosse um if? Algo como "Se stream for diferente de false retorne stream?"

3) Na função:

 public function filter($in, $out, int &$consumed, bool $closing)
    {

        $saida = '';

        while($bucket = stream_bucket_make_writeable($in))
        {

            $linhas = explode("\n", $bucket->data);

            foreach ($linhas as  $linha) {

                if(stripos($linha, 'parte') !== false)
                {

                    $saida .= "$linha\n";

                }
            }
        }

        $bucketSaida = stream_bucket_new($this->stream, $saida);

        stream_bucket_append($out, $bucketSaida);

        return PSFS_PASS_ON;
    }

Estou tendo o seguinte erro:

Method 'MeuFiltro::filter()' is not compatible with method 'php_user_filter::filter()'

Já pesquisei e não entendo porque. Já tentei colocar o retorno como int mas nada resolve.

4) Na linha:

stream_filter_register('alura.partes', MeuFiltro::class);

O que significa esses :: que ainda não entendi

11 respostas
  1. Aí você vai ter que escrever outro filtro usando outra lógica. O nosso filtro é para remover linhas, então não faz sentido receber como entrada um arquivo com uma linha só
  2. Estamos retornando um booleano, se o stream for diferente de false. Se o stream for diferente de false, retorna verdadeiro. Se for false, retorna false. É como se estivéssemos convertendo o stream para booleano. Porque a função fopen pode retornar um recurso ou false, entende?
  3. Me manda o código completo e um print do erro, por favor, mostrando como você está tentando executar. Adicionar os tipos de retorno deveria resolver. Qual sua versão do PHP?
  4. É o operador de resolução de escopo. Basicamente ele permite acessar alguns detalhes da classe como constantes, métodos estáticos, etc. Nesse caso, é como se class fosse uma constante "mágica" que o PHP define pra gente com o nome completo da classe, entende?

1) O filtro que usamos não era para remover linha, mas para adicionar quebras de linhas. Minha dúvida é como ele entende em que posição ele tem que adicionar essa quebra de linha;

2) Entendi.

3) `<?php

class MeuFiltro extends php_user_filter { public $stream;

public function onCreate() : bool
{
    $this->stream = fopen('php://temp', 'w+');

    return $this->stream !== false;
}

public function filter($in, $out, int &$consumed, bool $closing) : int
{
    $saida = '';

    while($bucket = stream_bucket_make_writeable($in))
    {
        $linhas = explode("\n", $bucket->data);

        foreach ($linhas as  $linha) {

            if(stripos($linha, 'parte') !== false)
            {
                $saida .= "$linha\n";
            }
        }
    }

    $bucketSaida = stream_bucket_new($this->stream, $saida);

    stream_bucket_append($out, $bucketSaida);

    return PSFS_PASS_ON;
}

}`

Estou executando apertando F5 (tenho a extensão Debug no VSCode):

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

A versão do meu php é 8.1.3

Também aparece esse erro:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

4) Não entendi para que serve pra esse caso. Não poderia só colocar MeuFiltro direto?

1- Karolina, o filtro que nós escrevemos não foi para adicionar quebras de linha não. Foi para remover os cursos que não possuem "parte" no nome. Só isso

3- A definição que ele está mostrando não possui o int no parâmetro &$consumed. Removendo esse tipo tudo deve funcionar.

4- Você poderia colocar a string "MeuFiltro" sim, mas se a classe estiver em um namespace você vai precisar digitar o namespace completo (o use não vai te ajudar nessa string) e a IDE não vai te ajudar no autocomplete.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Parou de dar erro no filtro, mas começou a dar erro na função stream_filter_append porque pelo que entendi na documentação agora tem que colocar esse terceiro parametro (STREAM_FILTER_ALL - https://www.php.net/manual/pt_BR/function.stream-filter-append.php). Porém eu testei adicionar a palavra "parte" em apenas um curso e não venho só ele, na verdade venho todos.

Karolina, o terceiro parâmetro é sobre adicionar o filtro na cadeia de escrita ou leitura. Esse parâmetro é opcional. Pode omiti-lo. Sobre o funcionamento do seu filtro, me manda o projeto completo pra eu testar, por favor?

Karolina, após corrigir o erro nessa linha o código roda conforme esperado, retornando apenas os cursos com "parte" no nome:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Desculpe, não entendi como foi feita a correção do erro. Ele pede um número inteiro, mas que número é esse que tenho que colocar?

Depois que eu tirei esse string.toupper funcionou, porém lembrou que fiz isso para associar dois filtros porque você disse que era possível. Associar o filtro que criei com outro.

solução!

Karolina, para adicionar vários filtros você chama a função stream_filter_append várias vezes.

Ah entendi ok