Seules les variables doivent être transmises par référence

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'
);

Des idées? Après 2 jours encore coincé.

Frank Nwoko
la source
2
Une meilleure explication de la raison vijayasankarn.wordpress.com/2017/08/28/…
Anant

Réponses:

515

Attribuez le résultat de explodeà une variable et passez cette variable à end:

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

Le problème est que cela endnécessite une référence, car il modifie la représentation interne du tableau (c'est-à-dire qu'il fait pointer le pointeur de l'élément courant vers le dernier élément).

Le résultat de explode('.', $file_name)ne peut pas être transformé en référence. Il s'agit d'une restriction dans le langage PHP, qui existe probablement pour des raisons de simplicité.

Oswald
la source
12
Merci beaucoup. Résolu mon problème.
Frank Nwoko
1
@Oswald, nous pouvons désactiver l'avertissement à l'aide de error_reporting. Est-il sûr de le faire?
Pacerier
9
Il est sûr de désactiver error_reporting. Il n'est pas sûr d'ignorer aveuglément les erreurs. La désactivation error_reportingest une étape importante vers l'ignorance aveugle des erreurs. Dans l'environnement de production, désactivez-le à la display_errorsplace et écrivez les erreurs dans un fichier journal.
Oswald
Ca ne fonctionne pas. La réponse ci-dessous - double parenthèse - fonctionne.
bbe
Merci, sauvez-moi beaucoup de temps!
Simon
52

Utilisation correcte compatible Php 7:

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

echo $fileExtension;
// jpg
Sinan Eldem
la source
3
Bizarre. Ça marche mais comment? Supprime-t-il l'avertissement, semblable à ce que fait le @préfixe?
Nigel Alderton
6
Alors pourquoi l'ajout d'une parenthèse supplémentaire supprime l'erreur?
Nigel Alderton
8
J'ai fait des recherches sur cette bizarrerie et cela semble être un bug? avec l' analyseur php où la double parenthèse "(())" convertit la référence en une valeur simple. Plus sur ce lien .
Callistino
26
J'aime ça .. mais je ne l'aime pas en même temps. Merci d'avoir gâché ma journée :-)
billynoah
4
En php7, un avertissement sera toujours émis. php.net/manual/en/…
kosta
49

Tout le monde vous a déjà donné la raison pour laquelle vous obtenez une erreur, mais voici la meilleure façon de faire ce que vous voulez faire: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);

Ryeguy
la source
1
Je suis d'accord. Il est inutile d'utiliser la manipulation de chaînes pour analyser les chemins d'accès aux fichiers lorsque vous disposez des API appropriées pour le faire.
gd1
18

enregistrez le tableau d'explode () dans une variable, puis appelez end () sur cette variable:

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

btw: J'utilise ce code pour obtenir l'extension de fichier:

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

strrchrextrait la chaîne après la dernière .et substrcoupe le.

Floern
la source
9

Essaye ça:

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

La raison en est que l'argument de endest passé par référence, car endmodifie le tableau en avançant son pointeur interne vers l'élément final. Si vous ne transmettez pas de variable, il n'y a rien pour indiquer une référence.

Voir enddans le manuel PHP pour plus d'informations.

Will Vousden
la source
8

PHP se plaint car end()attend une référence à quelque chose qu'il veut changer (qui ne peut être qu'une variable). Vous passez cependant le résultat de explode()directement à end()sans l'enregistrer d'abord dans une variable. Au moment où explode()renvoie votre valeur, elle n'existe qu'en mémoire et aucune variable ne la pointe. Vous ne pouvez pas créer une référence à quelque chose (ou à quelque chose d'inconnu dans la mémoire), qui n'existe pas.

Ou en d'autres termes: PHP ne sait pas, si la valeur que vous lui donnez est la valeur directe ou juste un pointeur vers la valeur (un pointeur est également une variable (entier), qui stocke le décalage de la mémoire, où la valeur réelle réside). PHP attend donc toujours ici un pointeur (référence).

Mais comme il ne s'agit que d'une notification (même pas obsolète) en PHP 7, vous pouvez ignorer les notifications et utiliser l'opérateur ignore au lieu de désactiver complètement le rapport d'erreur pour les notifications:

$file_extension = @end(explode('.', $file_name));
sorcier
la source
3
@OskarCalvo C'est aussi ma philosophie. Mais ce n'est pas une erreur - PHP le traite comme un "avis". Et c'était une "solution" alternative aux autres réponses ici, dont personne ne l'a directement mentionnée. Une meilleure façon serait d'enregistrer la valeur de explodedans une variable temporaire, comme d'autres l'ont écrit ici. Mais encore une fois: ce n'est pas une erreur, il est donc correct d'utiliser cet opérateur. PHP est généralement mauvais dans la gestion des erreurs. Par conséquent, je suggère d'utiliser set_error_handleret set_exception_handlerpour la gestion des erreurs et comme solution la plus propre.
assistant
4

Tout comme vous ne pouvez pas indexer le tableau immédiatement, vous ne pouvez pas non plus l'appeler end. Attribuez-le d'abord à une variable, puis appelez end.

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

end(...[explode('.', $file_name)])fonctionne depuis PHP 5.6. Ceci est documenté dans le RFC mais pas dans les documents PHP eux-mêmes.

Tgr
la source
2

Puisqu'il soulève un drapeau depuis plus de 10 ans, mais fonctionne très bien et retourne la valeur attendue, un petit opérateur stfu est la meilleure mauvaise pratique que vous recherchez tous:

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

Manuel PHP officiel: end ()

Paramètres

array

Le tableau. Ce tableau est transmis par référence car il est modifié par la fonction. Cela signifie que vous devez lui passer une variable réelle et non une fonction renvoyant un tableau car seules les variables réelles peuvent être transmises par référence.

evenvi
la source
3
Faites un devis à partir du manuel officiel, ne réécrivez pas de vos propres mains. Pensez également à améliorer votre réponse par rapport à la réponse existante.
Victor Polevoy
-1

Tout d'abord, vous devrez stocker la valeur dans une variable comme celle-ci

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

Ensuite, vous pouvez utiliser la fonction de fin pour obtenir le dernier index d'un tableau comme celui-ci

echo end($value);

J'espère que cela fonctionnera pour vous.

Jailendra Rajawat
la source
-3

$ file_extension = end (explode ('.', $ file_name)); // ERREUR SUR CETTE LIGNE

changer cette ligne comme,

$ file_extension = end ( ( explode ('.', $ file_name)) ); // pas d'erreurs

La technique est simple, veuillez mettre un autre support pour exploser,

(explode ()) , alors seulement il peut fonctionner indépendamment.

Manu RS
la source