Solucionado (ver solução)
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