Hanya variabel yang harus dilewatkan dengan referensi

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

Ada ide? Setelah 2 hari masih macet.

Frank Nwoko
sumber
2
Penjelasan yang lebih baik untuk alasan vijayasankarn.wordpress.com/2017/08/28/…
Anant

Jawaban:

515

Tetapkan hasil dari explodeke variabel dan meneruskan variabel itu ke end:

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

Masalahnya adalah, yang endmemerlukan referensi, karena memodifikasi representasi internal array (yaitu membuat pointer point elemen saat ini ke elemen terakhir).

Hasil dari explode('.', $file_name)tidak dapat diubah menjadi referensi. Ini adalah batasan dalam bahasa PHP, yang mungkin ada karena alasan kesederhanaan.

Oswald
sumber
12
Terima kasih banyak Memecahkan masalah saya.
Frank Nwoko
1
@ Oswald, Kita bisa mematikan peringatan menggunakan error_reporting. Apakah aman untuk melakukannya?
Pacerier
9
Aman untuk dimatikan error_reporting. Tidak aman untuk mengabaikan kesalahan secara membabi buta. Mematikan error_reportingadalah langkah besar menuju mengabaikan kesalahan secara membabi buta. Di lingkungan produksi, matikan display_errorssaja, dan tulis kesalahan ke file log.
Oswald
Tidak bekerja Jawaban di bawah ini - kurung ganda - berfungsi.
menjadi
Terima kasih, hemat saya banyak waktu!
simon
52

Php 7 penggunaan yang tepat dan kompatibel:

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

echo $fileExtension;
// jpg
Sinan Eldem
sumber
3
Aneh. Itu berhasil tetapi bagaimana? Apakah itu menekan peringatan, mirip dengan apa yang @awalan lakukan?
Nigel Alderton
6
Jadi mengapa menambahkan tanda kurung tambahan menghapus kesalahan?
Nigel Alderton
8
Saya meneliti kekhasan ini dan sepertinya ini bug? dengan parser php di mana tanda kurung ganda "(())" menyebabkan referensi dikonversi ke nilai biasa. Lebih lanjut tentang tautan ini .
Callistino
26
Saya suka ini .. tapi saya tidak suka pada saat yang sama. Terima kasih telah merusak hari saya :-)
billynoah
4
Dalam php7 peringatan akan tetap dikeluarkan. php.net/manual/en/…
kosta
49

Semua orang telah memberi Anda alasan Anda mendapatkan kesalahan, tetapi inilah cara terbaik untuk melakukan apa yang ingin Anda lakukan: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);

ryeguy
sumber
1
Saya setuju. Tidak ada gunanya menggunakan manipulasi string untuk mem-parsing path file ketika Anda memiliki API yang tepat untuk melakukannya.
gd1
18

simpan array dari explode () ke variabel, lalu panggil end () pada variabel ini:

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

btw: Saya menggunakan kode ini untuk mendapatkan ekstensi file:

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

di mana strrchrmengekstraksi string setelah yang terakhir .dan substrmemotong.

Floern
sumber
9

Coba ini:

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

Alasannya adalah bahwa argumen untuk enddilewatkan dengan referensi, karena endmemodifikasi array dengan memajukan pointer internal ke elemen terakhir. Jika Anda tidak meneruskan variabel, tidak ada referensi untuk menunjuk ke.

Lihat enddi manual PHP untuk info lebih lanjut.

Will Vousden
sumber
8

PHP mengeluh karena end()mengharapkan referensi ke sesuatu yang ingin diubah (yang bisa menjadi variabel saja). Namun Anda meneruskan hasil explode()langsung ke end()tanpa menyimpannya ke variabel terlebih dahulu. Saat explode()mengembalikan nilai Anda, nilai itu hanya ada di memori dan tidak ada titik variabel yang menunjukkannya. Anda tidak dapat membuat referensi ke sesuatu (atau ke sesuatu yang tidak dikenal dalam memori), yang tidak ada.

Atau dengan kata lain: PHP tidak tahu, apakah nilai yang Anda berikan kepadanya adalah nilai langsung atau hanya sebuah penunjuk ke nilai (sebuah penunjuk juga merupakan variabel (integer), yang menyimpan offset memori, di mana nilai aktualnya berada). Jadi PHP selalu mengharapkan pointer (referensi) di sini.

Tetapi karena ini masih hanya pemberitahuan (bahkan tidak ditinggalkan) di PHP 7, Anda dapat mengabaikan pemberitahuan dan menggunakan operator pengabaian alih-alih menonaktifkan pelaporan kesalahan untuk pemberitahuan:

$file_extension = @end(explode('.', $file_name));
Penyihir
sumber
3
@OskarCalvo Itu juga filosofi saya. Tapi ini bukan kesalahan - PHP memperlakukannya sebagai "pemberitahuan". Dan itu adalah "solusi" alternatif untuk jawaban lain di sini, yang tidak ada yang langsung menyebutkannya. Cara yang lebih baik adalah menyimpan nilai explodeke variabel sementara, seperti yang lain-lain tulis di sini. Tetapi sekali lagi: Ini bukan kesalahan, jadi tidak apa-apa menggunakan operator ini. PHP umumnya buruk dalam penanganan kesalahan. Karena itu saya akan menyarankan untuk menggunakan set_error_handlerdan set_exception_handleruntuk penanganan kesalahan dan sebagai solusi terbersih.
penyihir
4

Sama seperti Anda tidak dapat segera mengindeks array, Anda juga tidak dapat memanggilnya. Tetapkan itu ke variabel terlebih dahulu, lalu panggil akhir.

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

end(...[explode('.', $file_name)])telah bekerja sejak PHP 5.6. Ini didokumentasikan dalam RFC meskipun tidak dalam dokumen PHP sendiri.

Tgr
sumber
2

Karena mengibarkan bendera selama lebih dari 10 tahun, tetapi berfungsi dengan baik dan mengembalikan nilai yang diharapkan, operator stfu kecil adalah praktik buruk terbaik yang Anda semua cari:

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

Manual resmi PHP: end ()

Parameter

array

Array. Array ini dilewatkan oleh referensi karena dimodifikasi oleh fungsi. Ini berarti Anda harus memberikannya variabel nyata dan bukan fungsi yang mengembalikan array karena hanya variabel aktual yang dapat dilewatkan oleh referensi.

evenvi
sumber
3
Buat penawaran dari manual resmi, jangan menulis ulang dengan tangan Anda sendiri. Juga, pertimbangkan untuk membuat jawaban Anda lebih baik dari yang sudah ada.
Victor Polevoy
-1

Pertama, Anda harus menyimpan nilai dalam variabel seperti ini

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

Kemudian Anda bisa menggunakan fungsi akhir untuk mendapatkan indeks terakhir dari array seperti ini

echo end($value);

Saya harap ini akan berhasil untuk Anda.

Jailendra Rajawat
sumber
-3

$ file_extension = end (explode ('.', $ file_name)); // KESALAHAN PADA GARIS INI

ubah baris ini sebagai,

$ file_extension = end ( (explode ('.', $ file_name)) )); // tidak ada kesalahan

Tekniknya sederhana, silakan letakkan satu tanda kurung lagi untuk meledak,

(meledak ()) , maka hanya itu yang dapat melakukan secara independen ..

Manu RS
sumber