Somente as variáveis ​​devem ser passadas por referência

246
// Other variables
$MAX_FILENAME_LENGTH = 260;
$file_name = $_FILES[$upload_name]['name'];
//echo "testing-".$file_name."<br>";
//$file_name = strtolower($file_name);
$file_extension = end(explode('.', $file_name)); //ERROR ON THIS LINE
$uploadErrors = array(
    0=>'There is no error, the file uploaded with success',
    1=>'The uploaded file exceeds the upload max filesize allowed.',
    2=>'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
    3=>'The uploaded file was only partially uploaded',
    4=>'No file was uploaded',
    6=>'Missing a temporary folder'
);

Alguma ideia? Após 2 dias ainda preso.

Frank Nwoko
fonte
2
Uma explicação melhor para o motivo vijayasankarn.wordpress.com/2017/08/28/…
Anant

Respostas:

515

Atribua o resultado de explodea uma variável e passe essa variável para end:

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

O problema é que isso endrequer uma referência, porque modifica a representação interna da matriz (ou seja, faz o ponteiro do elemento atual apontar para o último elemento).

O resultado de explode('.', $file_name)não pode ser transformado em uma referência. Essa é uma restrição na linguagem PHP, que provavelmente existe por motivos de simplicidade.

Oswald
fonte
12
Muito obrigado. Resolveu o meu problema.
precisa saber é o seguinte
1
@Oswald, podemos desativar o aviso usando error_reporting. É seguro fazer isso?
Pacerier
9
É seguro desligar error_reporting. Não é seguro ignorar cegamente os erros. Desativar error_reportingé um passo importante para ignorar cegamente os erros. No ambiente de produção, desligue display_errorse grave erros em um arquivo de log.
Oswald
Não está funcionando. A resposta abaixo - parêntese duplo - funciona.
bbe
Obrigado, economize muito tempo!
simon
52

Uso adequado compatível com Php 7:

$fileName      = 'long.file.name.jpg';
$tmp           = explode('.', $fileName);
$fileExtension = end($tmp);

echo $fileExtension;
// jpg
Sinan Eldem
fonte
3
Esquisito. Isso funciona, mas como? Suprime o aviso, semelhante ao que o @prefixo faz?
Nigel Alderton
6
Então, por que adicionar um parêntese extra remove o erro?
Nigel Alderton
8
Eu pesquisei essa peculiaridade e parece ser um bug? com o analisador php em que parênteses duplos "(())" fazem com que a referência seja convertida em um valor simples. Mais neste link .
Callistino #
26
Eu gosto disso .. mas não gosto ao mesmo tempo. Obrigado por arruinar o meu dia :-)
billynoah
4
No php7, o aviso ainda será emitido. php.net/manual/pt/…
kosta
49

Todo mundo já deu a você o motivo pelo qual você está recebendo um erro, mas aqui está a melhor maneira de fazer o que você deseja: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);

ryeguy
fonte
1
Concordo. Não faz sentido usar a manipulação de cadeias para analisar caminhos de arquivos quando você possui APIs apropriadas para isso.
Gd1
18

salve a matriz de explodir () em uma variável e, em seguida, chame end () nesta variável:

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

btw: Eu uso esse código para obter a extensão do arquivo:

$ext = substr( strrchr($file_name, '.'), 1);

onde strrchrextrai a sequência após a última .e substrcorta o.

Floern
fonte
9

Tente o seguinte:

$parts = explode('.', $file_name);
$file_extension = end($parts);

O motivo é que o argumento para endé passado por referência, pois endmodifica a matriz avançando seu ponteiro interno para o elemento final. Se você não está passando uma variável, não há nada a que se referir uma referência.

Veja endno manual do PHP para mais informações.

Will Vousden
fonte
8

O PHP reclama porque end()espera uma referência a algo que deseja alterar (que pode ser apenas uma variável). No entanto, você passa o resultado explode()diretamente para end()sem salvá-lo em uma variável primeiro. No momento em que explode()retorna seu valor, ele existe apenas na memória e nenhuma variável aponta para ele. Você não pode criar uma referência a algo (ou a algo desconhecido na memória) que não existe.

Ou, em outras palavras: PHP não sabe, se o valor que você atribui é o valor direto ou apenas um ponteiro para o valor (um ponteiro também é uma variável (número inteiro), que armazena o deslocamento da memória, onde o valor real reside). Então, o PHP espera aqui um ponteiro (referência) sempre.

Mas como esse ainda é apenas um aviso (nem mesmo obsoleto) no PHP 7, você pode ignorar avisos com facilidade e usar o operador ignore em vez de desativar completamente o relatório de erros para avisos:

$file_extension = @end(explode('.', $file_name));
bruxo
fonte
3
@OskarCalvo Essa também é a minha filosofia. Mas isso não é um erro - o PHP trata isso como um "aviso". E foi uma "solução" alternativa para outras respostas aqui, que ninguém a mencionou diretamente. Uma maneira melhor seria salvar o valor de explodeem uma variável temporária, como outros escreveram aqui. Mais uma vez: isso não é um erro, portanto, não há problema em usar este operador. O PHP geralmente é ruim no tratamento de erros. Portanto, sugiro usar set_error_handlere set_exception_handlerpara o tratamento de erros e como a solução mais limpa.
wizard
4

Assim como você não pode indexar a matriz imediatamente, também não pode chamar end. Atribua-o a uma variável primeiro e depois ligue para final.

$basenameAndExtension = explode('.', $file_name);
$ext = end($basenameAndExtension);
jon_darkstar
fonte
4

end(...[explode('.', $file_name)])trabalha desde o PHP 5.6. Isso está documentado na RFC, embora não nos próprios documentos do PHP.

Tgr
fonte
2

Como ele levanta uma bandeira há mais de 10 anos, mas funciona muito bem e retorna o valor esperado, um pequeno operador stfu é a melhor prática ruim que você está procurando:

$file_extension = @end(explode('.', $file_name));
NVRM
fonte
0

Manual oficial do PHP: end ()

Parâmetros

array

A matriz. Essa matriz é passada por referência porque é modificada pela função. Isso significa que você deve passar uma variável real e não uma função retornando uma matriz, porque somente variáveis ​​reais podem ser passadas por referência.

evenvi
fonte
3
Faça uma cotação do manual oficial, não reescreva com suas próprias mãos. Além disso, considere fazer sua resposta melhor que a existente.
Victor Polevoy 8/08/15
-1

Primeiro, você terá que armazenar o valor em uma variável como esta

$value = explode("/", $string);

Em seguida, você pode usar a função final para obter o último índice de uma matriz como esta

echo end($value);

Espero que funcione para você.

Jailendra Rajawat
fonte
-3

$ file_extension = end (explode ('.', $ file_name)); // ERRO NESTA LINHA

mude esta linha como,

$ file_extension = end ( (explodir ('.', $ file_name)) ); //Sem erros

A técnica é simples, por favor, coloque mais um parênteses para explodir,

(explodir ()) , somente ele pode executar de forma independente.

Manu RS
fonte