Chỉ các biến phải được truyền bằng tham chiếu


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

Có ý kiến ​​gì không? Sau 2 ngày vẫn bế tắc.


2
Giải thích rõ hơn cho lý do vijayasankarn.wordpress.com/2017/08/28/ Khăn
Anant

Câu trả lời:


515

Gán kết quả của explodemột biến và truyền biến đó cho end:

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

Vấn đề là, điều đó endđòi hỏi một tham chiếu, bởi vì nó sửa đổi biểu diễn bên trong của mảng (tức là nó tạo ra con trỏ phần tử hiện tại đến phần tử cuối cùng).

Kết quả của explode('.', $file_name)không thể được biến thành một tài liệu tham khảo. Đây là một hạn chế trong ngôn ngữ PHP, có lẽ tồn tại vì lý do đơn giản.


12
Cảm ơn rất nhiều. Giải quyết vấn đề của tôi.
Frank Nwoko

1
@Oswald, Chúng tôi có thể tắt cảnh báo bằng cách sử dụng error_reporting. Có an toàn để làm như vậy?
Pacerier

9
Nó là an toàn để tắt error_reporting. Nó không an toàn để mù quáng bỏ qua lỗi. Tắt error_reportinglà một bước quan trọng đối với việc bỏ qua các lỗi một cách mù quáng. Trong môi trường sản xuất, display_errorsthay vào đó hãy tắt và ghi lỗi vào tệp nhật ký.
Oswald

Không làm việc. Câu trả lời dưới đây - dấu ngoặc kép - hoạt động.
bbe

Cảm ơn bạn, tiết kiệm cho tôi rất nhiều thời gian!
simon

52

Cách sử dụng phù hợp Php 7:

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

echo $fileExtension;
// jpg

3
Kỳ dị. Điều đó hoạt động nhưng làm thế nào? Liệu nó có ngăn chặn cảnh báo, tương tự như những gì @tiền tố làm?
Nigel Alderton

6
Vậy tại sao việc thêm dấu ngoặc đơn loại bỏ lỗi?
Nigel Alderton

8
Tôi đã nghiên cứu vấn đề này và nó có vẻ là một lỗi? với trình phân tích cú pháp php trong đó dấu ngoặc kép "(())" làm cho tham chiếu được chuyển đổi thành giá trị đơn giản. Thêm về liên kết này .
Callistino

26
Tôi thích điều này .. nhưng tôi không thích nó cùng một lúc. Cảm ơn vì đã hủy hoại ngày của tôi :-)
billynoah

4
Trong cảnh báo php7 sẽ vẫn được ban hành. php.net/manual/en/ từ
kosta

49

Mọi người khác đã cho bạn biết lý do bạn gặp lỗi, nhưng đây là cách tốt nhất để làm những gì bạn muốn làm: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);


1
Tôi đồng ý. Không có điểm nào trong việc sử dụng thao tác chuỗi để phân tích đường dẫn tệp khi bạn có API phù hợp để làm như vậy.
gd1

18

lưu mảng từ explode () vào một biến và sau đó gọi end () trên biến này:

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

btw: Tôi sử dụng mã này để có được phần mở rộng tập tin:

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

nơi strrchrtrích xuất chuỗi sau lần cuối .substrcắt đứt.


9

Thử cái này:

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

Lý do là đối số cho endđược truyền bằng tham chiếu, vì endsửa đổi mảng bằng cách tiến con trỏ bên trong của nó đến phần tử cuối cùng. Nếu bạn không chuyển một biến vào, không có gì để tham chiếu đến.

Xem endtrong hướng dẫn PHP để biết thêm.


8

PHP phàn nàn vì end()mong đợi một tham chiếu đến một cái gì đó mà nó muốn thay đổi (có thể chỉ là một biến). Tuy nhiên, bạn chuyển kết quả explode()trực tiếp đến end()mà không lưu nó vào một biến trước. Tại thời điểmexplode() trả về giá trị của bạn, nó chỉ tồn tại trong bộ nhớ và không có điểm nào thay đổi. Bạn không thể tạo một tham chiếu đến một cái gì đó (hoặc một cái gì đó không xác định trong bộ nhớ), điều đó không tồn tại.

Hay nói cách khác: PHP không biết, nếu giá trị bạn đưa cho anh ta là giá trị trực tiếp hoặc chỉ là một con trỏ tới giá trị (một con trỏ cũng là một biến (số nguyên), lưu trữ phần bù của bộ nhớ, trong đó giá trị thực cư trú). Vì vậy, PHP mong đợi ở đây một con trỏ (tham khảo) luôn.

Nhưng vì đây vẫn chỉ là một thông báo (thậm chí không được phản đối) trong PHP 7, bạn có thể bỏ qua các thông báo và sử dụng toán tử bỏ qua thay vì tắt hoàn toàn báo cáo lỗi cho các thông báo:

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

3
@OskarCalvo Đó cũng là triết lý của tôi. Nhưng đây không phải là một lỗi - PHP coi nó như một "thông báo". Và nó là một "giải pháp" thay thế cho các câu trả lời khác ở đây, mà không ai đề cập trực tiếp đến nó. Một cách tốt hơn sẽ là lưu giá trị của explodemột biến tạm thời, như những người khác đã viết ở đây. Nhưng một lần nữa: Đây không phải là một lỗi, vì vậy sử dụng toán tử này là ổn. PHP nói chung là xấu khi xử lý lỗi. Vì vậy, tôi sẽ đề nghị sử dụng set_error_handlerset_exception_handlerxử lý lỗi và là giải pháp sạch nhất.
thuật sĩ

4

Giống như bạn không thể lập chỉ mục cho mảng ngay lập tức, bạn cũng không thể gọi kết thúc trên đó. Gán nó cho một biến đầu tiên, sau đó gọi kết thúc.

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

4

end(...[explode('.', $file_name)])đã làm việc kể từ PHP 5.6. Điều này được ghi lại trong RFC mặc dù không phải trong tài liệu PHP.


2

Vì nó giương cờ trong hơn 10 năm, nhưng hoạt động tốt và trả về giá trị mong đợi, một toán tử stfu nhỏ là cách thực hành xấu tốt nhất mà bạn đang tìm kiếm:

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

0

Hướng dẫn chính thức về PHP: end ()

Thông số

array

Các mảng. Mảng này được truyền bằng tham chiếu vì nó được sửa đổi bởi hàm. Điều này có nghĩa là bạn phải truyền cho nó một biến thực và không phải là hàm trả về một mảng vì chỉ các biến thực tế mới có thể được truyền bằng tham chiếu.


3
Đặt một trích dẫn từ hướng dẫn chính thức, đừng viết lại bằng tay của chính bạn. Ngoài ra, xem xét để làm cho câu trả lời của bạn tốt hơn câu trả lời hiện có.
Victor Polevoy

-1

Đầu tiên, bạn sẽ phải lưu trữ giá trị trong một biến như thế này

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

Sau đó, bạn có thể sử dụng hàm kết thúc để lấy chỉ mục cuối cùng từ một mảng như thế này

echo end($value);

Tôi hy vọng nó sẽ làm việc cho bạn.


-3

$ file_extension = end (explode ('.', $ file_name)); // LRI TRÊN LINE NÀY

thay đổi dòng này là

$ file_extension = end ( (explode ('.', $ file_name)) ); //không có lỗi

Kỹ thuật đơn giản, vui lòng đặt thêm một dấu ngoặc để phát nổ,

(explode ()) , sau đó chỉ có nó có thể hoạt động độc lập ..

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.