Nur Variablen sollten als Referenz übergeben werden

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

Irgendwelche Ideen? Nach 2 Tagen noch stecken.

Frank Nwoko
quelle
2
Eine bessere Erklärung für den Grund vijayasankarn.wordpress.com/2017/08/28/…
Anant

Antworten:

515

Weisen Sie das Ergebnis explodeeiner Variablen zu und übergeben Sie diese Variable an end:

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

Das Problem ist, dass endeine Referenz erforderlich ist, da dadurch die interne Darstellung des Arrays geändert wird (dh der aktuelle Elementzeiger erstellt wird) auf das letzte Element).

Das Ergebnis von explode('.', $file_name)kann nicht in eine Referenz umgewandelt werden. Dies ist eine Einschränkung in der PHP-Sprache, die wahrscheinlich aus Gründen der Einfachheit besteht.

Oswald
quelle
12
Vielen Dank. Mein Problem gelöst.
Frank Nwoko
1
@Oswald, Wir können die Warnung mit deaktivieren error_reporting. Ist das sicher?
Pacerier
9
Das Ausschalten ist sicher error_reporting. Es ist nicht sicher, Fehler blind zu ignorieren. Das Ausschalten error_reportingist ein wichtiger Schritt, um Fehler blind zu ignorieren. Deaktivieren Sie display_errorsstattdessen in der Produktionsumgebung und schreiben Sie Fehler in eine Protokolldatei.
Oswald
Funktioniert nicht. Die Antwort unten - doppelte Klammern - funktioniert.
bbe
Danke, spare mir viel Zeit!
Simon
52

Php 7 kompatibel ordnungsgemäße Verwendung:

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

echo $fileExtension;
// jpg
Sinan Eldem
quelle
3
Seltsam. Das funktioniert aber wie? Unterdrückt es die Warnung, ähnlich wie das @Präfix?
Nigel Alderton
6
Warum wird der Fehler durch Hinzufügen einer zusätzlichen Klammer behoben?
Nigel Alderton
8
Ich habe diese Eigenart untersucht und es scheint ein Fehler zu sein? mit dem PHP-Parser, bei dem doppelte Klammern "(())" bewirken, dass die Referenz in einen einfachen Wert konvertiert wird. Mehr zu diesem Link .
Callistino
26
Ich mag das .. aber ich mag es nicht gleichzeitig. Danke, dass du meinen Tag ruiniert
hast
4
In PHP7 wird weiterhin eine Warnung ausgegeben. php.net/manual/en/…
kosta
49

Alle anderen haben Ihnen bereits den Grund angegeben, warum Sie einen Fehler erhalten. Hier ist jedoch der beste Weg, um das zu tun, was Sie tun möchten: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);

Ryeguy
quelle
1
Genau. Es macht keinen Sinn, die Zeichenfolgenmanipulation zum Parsen von Dateipfaden zu verwenden, wenn Sie über geeignete APIs verfügen.
GD1
18

Speichern Sie das Array von explode () in einer Variablen und rufen Sie dann end () für diese Variable auf:

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

Übrigens: Ich benutze diesen Code, um die Dateierweiterung zu erhalten:

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

wo strrchrextrahiert die Zeichenfolge nach dem letzten .und substrschneidet die.

Floern
quelle
9

Versuche dies:

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

Der Grund ist, dass das Argument für endals Referenz übergeben wird, daend das Array geändert wird, indem der interne Zeiger auf das letzte Element verschoben wird. Wenn Sie keine Variable übergeben, gibt es nichts, auf das ein Verweis verweisen könnte.

endWeitere Informationen finden Sie im PHP-Handbuch.

Will Vousden
quelle
8

PHP beschwert sich, weil es end()einen Verweis auf etwas erwartet, das es ändern möchte (was nur eine Variable sein kann). Sie übergeben das Ergebnis jedoch explode()direkt an, end()ohne es zuerst in einer Variablen zu speichern. Im Moment alsexplode() in dem Ihr Wert zurückgegeben wird, existiert er nur im Speicher und keine Variable zeigt darauf. Sie können keinen Verweis auf etwas (oder auf etwas Unbekanntes im Speicher) erstellen, das nicht vorhanden ist.

Oder mit anderen Worten: PHP weiß nicht, ob der Wert, den Sie ihm geben, der direkte Wert oder nur ein Zeiger auf den Wert ist (ein Zeiger ist auch eine Variable (Ganzzahl), die den Offset des Speichers speichert, in dem sich der tatsächliche Wert befindet wohnt). PHP erwartet hier also immer einen Zeiger (Referenz).

Da dies in PHP 7 immer noch nur ein Hinweis ist (nicht einmal veraltet), können Sie Benachrichtigungen sicher ignorieren und den Ignorieroperator verwenden, anstatt die Fehlerberichterstattung für Benachrichtigungen vollständig zu deaktivieren:

$file_extension = @end(explode('.', $file_name));
Magier
quelle
3
@OskarCalvo Das ist auch meine Philosophie. Dies ist jedoch kein Fehler - PHP behandelt ihn als "Hinweis". Und es war eine alternative "Lösung" zu anderen Antworten hier, die niemand direkt erwähnte. Ein besserer Weg wäre, den Wert von explodein einer temporären Variablen zu speichern , wie andere hier geschrieben haben. Aber nochmal: Dies ist kein Fehler, daher ist es in Ordnung, diesen Operator zu verwenden. PHP ist im Allgemeinen schlecht in der Fehlerbehandlung. Daher würde ich vorschlagen, set_error_handlerund set_exception_handlerzur Fehlerbehandlung und als sauberste Lösung zu verwenden.
Zauberer
4

So wie Sie das Array nicht sofort indizieren können, können Sie auch nicht end aufrufen. Weisen Sie es zuerst einer Variablen zu und rufen Sie dann end auf.

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

end(...[explode('.', $file_name)])hat seit PHP 5.6 funktioniert. Dies ist im RFC dokumentiert, jedoch nicht in den PHP-Dokumenten selbst.

Tgr
quelle
2

Da es seit über 10 Jahren eine Flagge hisst, aber einwandfrei funktioniert und den erwarteten Wert zurückgibt, ist ein kleiner stfu-Operator die beste schlechte Praxis, die Sie alle suchen:

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

PHP offizielles Handbuch: end ()

Parameter

array

Das Array. Dieses Array wird als Referenz übergeben, da es von der Funktion geändert wird. Dies bedeutet, dass Sie eine echte Variable übergeben müssen und keine Funktion, die ein Array zurückgibt, da nur tatsächliche Variablen als Referenz übergeben werden dürfen.

Evenvi
quelle
3
Machen Sie ein Zitat aus dem offiziellen Handbuch, schreiben Sie es nicht selbst um. Denken Sie auch daran, Ihre Antwort besser als die vorhandene zu machen.
Victor Polevoy
-1

Zuerst müssen Sie den Wert in einer Variablen wie dieser speichern

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

Dann können Sie die End-Funktion verwenden, um den letzten Index aus einem Array wie diesem abzurufen

echo end($value);

Ich hoffe es wird für dich funktionieren.

Jailendra Rajawat
quelle
-3

$ file_extension = end (explode ('.', $ file_name)); // FEHLER IN DIESER LINIE

Ändern Sie diese Zeile als,

$ file_extension = end ( (explode ('.', $ file_name)) ); //keine Fehler

Die Technik ist einfach. Bitte setzen Sie noch eine Klammer für die Explosion.

(explode ()) , dann kann nur es unabhängig arbeiten ..

Manu RS
quelle