ควรส่งผ่านตัวแปรโดยอ้างอิงเท่านั้น


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

ความคิดใด ๆ หลังจาก 2 วันก็ยังติดอยู่


2
คำอธิบายที่ดีกว่าสำหรับเหตุผลvijayasankarn.wordpress.com/2017/08/28/…
อนันต์

คำตอบ:


515

กำหนดผลลัพธ์ของexplodeให้กับตัวแปรแล้วส่งตัวแปรนั้นไปที่end:

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

ปัญหาคือว่าendต้องมีการอ้างอิงเพราะมันจะแก้ไขการเป็นตัวแทนภายในของอาร์เรย์ (เช่นมันทำให้ตัวชี้องค์ประกอบปัจจุบันไปที่องค์ประกอบสุดท้าย)

ผลลัพธ์ของการexplode('.', $file_name)ไม่สามารถกลายเป็นข้อมูลอ้างอิงได้ นี่เป็นข้อ จำกัด ในภาษา PHP ซึ่งอาจมีอยู่เนื่องจากเหตุผลด้านความเรียบง่าย


12
ขอบคุณมาก ๆ แก้ไขปัญหาของฉัน
แฟรงก์ Nwoko

1
@Oswald error_reportingเราสามารถเปิดเตือนออกใช้ ปลอดภัยไหมที่จะทำเช่นนั้น?
Pacerier

9
error_reportingมันมีความปลอดภัยที่จะปิด ไม่ปลอดภัยที่จะมองข้ามข้อผิดพลาด การปิดerror_reportingเป็นขั้นตอนสำคัญในการละเว้นข้อผิดพลาด ในสภาพแวดล้อมการผลิตให้ปิดdisplay_errorsแทนและเขียนข้อผิดพลาดไปยังไฟล์บันทึก
Oswald

ไม่ทำงาน. คำตอบด้านล่าง - วงเล็บคู่ - ทำงาน
bbe

ขอบคุณช่วยฉันมากเวลา!
simon

52

Php 7 ใช้งานได้เหมาะสม:

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

echo $fileExtension;
// jpg

3
แปลก. นั่นใช้ได้ แต่อย่างไร มันไม่แสดงคำเตือนคล้ายกับส่วน@นำหน้าทำอย่างไร
Nigel Alderton

6
เหตุใดการเพิ่มวงเล็บพิเศษจึงลบข้อผิดพลาดออก
Nigel Alderton

8
ฉันค้นคว้าความแปลกประหลาดนี้และดูเหมือนว่าจะเป็นจุดบกพร่องหรือไม่? กับphp parserโดยที่เครื่องหมายวงเล็บคู่ "(())" ทำให้การอ้างอิงถูกแปลงเป็นค่าธรรมดา เพิ่มเติมเกี่ยวกับลิงค์นี้
Callistino

26
ฉันชอบสิ่งนี้ แต่ฉันไม่ชอบมันในเวลาเดียวกัน ขอขอบคุณที่ทำลายวันของฉัน :-)
billynoah

4
ในคำเตือน php7 จะยังคงออก php.net/manual/en/…
kosta

49

คนอื่นได้ให้เหตุผลที่คุณได้รับข้อผิดพลาดแล้ว แต่นี่เป็นวิธีที่ดีที่สุดในการทำสิ่งที่คุณต้องการ: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);


1
ฉันเห็นด้วย. ไม่มีประโยชน์ในการใช้การจัดการสตริงเพื่อวิเคราะห์เส้นทางไฟล์เมื่อคุณมี API ที่เหมาะสมในการทำเช่นนั้น
gd1

18

บันทึก array จาก explode () ไปยังตัวแปรจากนั้น call end () บนตัวแปรนี้:

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

btw: ฉันใช้รหัสนี้เพื่อรับนามสกุลไฟล์:

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

โดยที่strrchrแยกสตริงหลังส่วนสุดท้าย.และsubstrตัดการ.


9

ลองสิ่งนี้:

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

เหตุผลก็คืออาร์กิวเมนต์สำหรับendถูกส่งผ่านโดยการอ้างอิงเนื่องจากendปรับเปลี่ยนอาร์เรย์โดยเลื่อนตัวชี้ภายในของมันไปยังองค์ประกอบสุดท้าย หากคุณไม่ได้ผ่านตัวแปรในไม่มีการอ้างอิงที่ชี้ไป

ดูendในคู่มือ PHP สำหรับข้อมูลเพิ่มเติม


8

PHP บ่นเพราะend()คาดว่าจะมีการอ้างอิงถึงสิ่งที่ต้องการเปลี่ยนแปลง (ซึ่งอาจเป็นตัวแปรเท่านั้น) อย่างไรก็ตามคุณส่งผลลัพธ์explode()โดยตรงไปที่end()โดยไม่บันทึกลงในตัวแปรก่อน ในขณะที่เมื่อexplode()ส่งคืนค่าของคุณจะมีอยู่ในหน่วยความจำเท่านั้นและไม่มีตัวแปรชี้ไปที่มัน คุณไม่สามารถสร้างการอ้างอิงถึงบางสิ่ง (หรือสิ่งที่ไม่รู้จักในหน่วยความจำ) ซึ่งไม่มีอยู่

หรือในคำอื่น ๆ : PHP ไม่ทราบว่าถ้าค่าที่คุณให้เขาเป็นค่าโดยตรงหรือเพียงแค่ตัวชี้ไปที่ค่า (ตัวชี้ยังเป็นตัวแปร (จำนวนเต็ม) ซึ่งเก็บออฟเซ็ตหน่วยความจำที่ค่าจริง อยู่) ดังนั้น PHP จึงคาดหวังว่าจะมีตัวชี้ (อ้างอิง) อยู่เสมอ

แต่เนื่องจากนี่เป็นเพียงการแจ้งเตือน (ไม่ใช่เลิกใช้แล้ว) ใน PHP 7 คุณสามารถละเว้นการแจ้งเตือนและใช้ตัวดำเนินการเพิกเฉยแทนการรายงานข้อผิดพลาดอย่างสมบูรณ์เพื่อปิดการใช้งาน:

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

3
@OskarCalvo นั่นคือปรัชญาของฉันด้วย แต่นี่ไม่ใช่ข้อผิดพลาด - PHP ถือว่าเป็น "การแจ้งเตือน" และมันก็เป็น "ทางเลือก" สำหรับคำตอบอื่น ๆ ที่นี่ซึ่งไม่มีใครพูดถึงมันโดยตรง วิธีที่ดีกว่าคือการบันทึกค่าของexplodeตัวแปรชั่วคราวเช่นเดียวกับที่คนอื่นเขียนไว้ที่นี่ แต่อีกครั้ง: นี่ไม่ใช่ข้อผิดพลาดดังนั้นจึงสามารถใช้โอเปอเรเตอร์นี้ได้ โดยทั่วไปแล้ว PHP ไม่ดีในการจัดการข้อผิดพลาด ดังนั้นฉันขอแนะนำให้ใช้set_error_handlerและset_exception_handlerสำหรับการจัดการข้อผิดพลาดและเป็นวิธีที่สะอาดที่สุด
ตัวช่วยสร้าง

4

เช่นเดียวกับที่คุณไม่สามารถจัดทำดัชนีอาร์เรย์ได้ทันทีคุณไม่สามารถเรียกวางสายได้ กำหนดให้กับตัวแปรก่อนจากนั้นจึงวางสาย

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

4

end(...[explode('.', $file_name)])ได้ทำงานตั้งแต่ PHP 5.6 นี่เป็นเอกสารในRFCแม้ว่าจะไม่ใช่เอกสาร PHP เอง


2

เนื่องจากมันยกธงมานานกว่า 10 ปี แต่ใช้งานได้ดีและคืนค่าที่คาดไว้ตัวดำเนินการ stfuเล็ก ๆ น้อย ๆคือวิธีปฏิบัติที่ไม่ดีที่สุดที่คุณกำลังมองหา:

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

0

คู่มืออย่างเป็นทางการของ PHP: end ()

พารามิเตอร์

array

อาเรย์ อาร์เรย์นี้ถูกส่งผ่านโดยการอ้างอิงเนื่องจากถูกปรับเปลี่ยนโดยฟังก์ชัน ซึ่งหมายความว่าคุณจะต้องผ่านมันเป็นตัวแปรจริงและไม่ใช่ฟังก์ชั่นที่ส่งกลับอาร์เรย์เพราะตัวแปรที่แท้จริงเท่านั้นที่อาจถูกส่งผ่านโดยการอ้างอิง


3
อ้างจากคู่มืออย่างเป็นทางการอย่าเขียนด้วยมือของคุณเอง ลองพิจารณาคำตอบของคุณให้ดีกว่าคำตอบเดิม
Victor Polevoy

-1

ก่อนอื่นคุณจะต้องเก็บค่าไว้ในตัวแปรเช่นนี้

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

จากนั้นคุณสามารถใช้ฟังก์ชั่นสิ้นสุดเพื่อรับดัชนีสุดท้ายจากอาร์เรย์เช่นนี้

echo end($value);

ฉันหวังว่ามันจะทำงานให้คุณ


-3

$ file_extension = end (explode ('.', $ file_name)); // ข้อผิดพลาดบนบรรทัดนี้

เปลี่ยนบรรทัดนี้เป็น

$ file_extension = end ( (explode ('.', $ file_name)) ); // ไม่มีข้อผิดพลาด

เทคนิคง่ายมากโปรดใส่วงเล็บอีกหนึ่งอันไว้สำหรับระเบิด

(explode ())จากนั้นจะสามารถทำงานได้อย่างอิสระเท่านั้น ..

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.