2009-06-23 40 views
469

Tôi đã thấy công dụng của @ trước chức năng nhất định, như sau:Việc sử dụng biểu tượng @ trong PHP là gì?

$fileHandle = @fopen($fileName, $writeAttributes); 

việc sử dụng các biểu tượng này là gì?

+3

Cả RichieHindle và Aiden Bell đã đưa ra câu trả lời đúng nhưng kể từ khi tôi chỉ có thể đặt một câu trả lời như chấp nhận, Tôi sẽ chọn cái đầu tiên. Xin lỗi Aiden –

+1

Lỗi triệt tiêu (mặc dù tốt đẹp) có thể gây ra lỗi trên đường khi duy trì codebase ... http://stackoverflow.com/a/7116175/282343 – dennismonsewicz

Trả lời

531

Nó chặn thông báo lỗi - xem Error Control Operators trong hướng dẫn sử dụng PHP.

+31

Đó là một chút rút ngắn! –

+4

Có; xuống thứ hai! Tôi đã phải kiểm tra câu trả lời của id để xem ai đến đầu tiên :) – Sampson

+6

@ Aiden: Cả hai đều chết trong bụi. 8-) – RichieHindle

383

Nó ngăn chặn lỗi.

Xem Error Control Operators trong cuốn hướng dẫn:

PHP hỗ trợ điều hành kiểm soát một lỗi: những lúc đăng nhập (@). Khi được thêm vào một biểu thức trong PHP, bất kỳ thông báo lỗi nào có thể được tạo bởi biểu thức đó sẽ bị bỏ qua.

Nếu bạn đã đặt chức năng xử lý lỗi tùy chỉnh với set_error_handler() thì nó sẽ vẫn được gọi, nhưng trình xử lý lỗi tùy chỉnh này có thể (và nên) gọi số error_reporting() sẽ trả về 0 khi cuộc gọi đã kích hoạt lỗi trước một @ ...

+126

chỉ được bình chọn vì câu trả lời khác là nhận được tất cả tình yêu. – ajacian81

+5

@ ajacian81 - Chúc mừng! –

+7

19 sau ... mọi người hãy đánh bại RichieHindle: P –

52

Cũng lưu ý rằng mặc dù lỗi bị ẩn, mọi trình xử lý lỗi tùy chỉnh (được đặt bằng set_error_handler) sẽ vẫn được thực hiện!

180

Biểu tượng @ là số error control operator (còn gọi là toán tử "im lặng" hoặc "shut-up"). Nó làm cho PHP ngăn chặn bất kỳ thông báo lỗi (thông báo, cảnh báo, gây tử vong, vv) được tạo ra bởi các biểu hiện liên quan. Nó hoạt động giống như một toán tử đơn nhất, ví dụ, nó có một ưu tiên và kết hợp. Dưới đây là một số ví dụ:

@echo 1/0; 
// generates "Parse error: syntax error, unexpected T_ECHO" since 
// echo is not an expression 

echo @(1/0); 
// suppressed "Warning: Division by zero" 

@$i/0; 
// suppressed "Notice: Undefined variable: i" 
// displayed "Warning: Division by zero" 

@($i/0); 
// suppressed "Notice: Undefined variable: i" 
// suppressed "Warning: Division by zero" 

$c = @$_POST["a"] + @$_POST["b"]; 
// suppressed "Notice: Undefined index: a" 
// suppressed "Notice: Undefined index: b" 

$c = @foobar(); 
echo "Script was not terminated"; 
// suppressed "Fatal error: Call to undefined function foobar()" 
// however, PHP did not "ignore" the error and terminated the 
// script because the error was "fatal" 

Chính xác những gì sẽ xảy ra nếu bạn sử dụng một lỗi xử lý tùy chỉnh thay vì xử lý lỗi PHP tiêu chuẩn:

Nếu bạn đã thiết lập một chức năng xử lý lỗi tùy chỉnh với set_error_handler() sau đó nó sẽ vẫn được gọi, nhưng trình xử lý lỗi tùy chỉnh này có thể (và nên) gọi error_reporting() sẽ trả lại 0 khi cuộc gọi đã kích hoạt lỗi được bắt đầu bởi @.

này được minh họa trong ví dụ mã sau:

function bad_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { 
    echo "[bad_error_handler]: $errstr"; 
    return true; 
} 
set_error_handler("bad_error_handler"); 
echo @(1/0); 
// prints "[bad_error_handler]: Division by zero" 

handler Các lỗi không kiểm tra xem @ biểu tượng đã có hiệu lực. Hướng dẫn sử dụng gợi ý những điều sau:

function better_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { 
    if(error_reporting() !== 0) { 
     echo "[better_error_handler]: $errstr"; 
    } 
    // take appropriate action 
    return true; 
} 
+28

Câu trả lời chi tiết và thông tin nhất tại đây. – rvighne

+3

Rất nhiều thông tin. – Mark

+0

Cho phép gửi câu hỏi này lên đầu:/câu trả lời chi tiết nhất. – rafamds

5

Nếu mở không thành công, lỗi E_WARNING sẽ được tạo. Bạn có thể sử dụng @ để chặn cảnh báo này.

5

Giả sử chúng ta đã không sử dụng "@" nhà điều hành sau đó mã của chúng ta sẽ trông như thế này:

$fileHandle = fopen($fileName, $writeAttributes); 

Và nếu các tập tin chúng tôi đang cố gắng mở không được tìm thấy? Nó sẽ hiển thị một thông báo lỗi.

Để ngăn chặn các thông báo lỗi, chúng tôi đang sử dụng "@" nhà điều hành như:

$fileHandle = @fopen($fileName, $writeAttributes); 
2

"@" ngăn chặn thông báo lỗi.

Nó được sử dụng trong đoạn mã như:

@file_get_contents('http://www.exaple.com'); 

Nếu miền "http://www.exaple.com" không thể truy cập, một lỗi sẽ được hiển thị, nhưng với '@' không có gì là không thấy.

1

PHP hỗ trợ một toán tử điều khiển lỗi: tại dấu hiệu (@). Khi được thêm vào một biểu thức trong PHP, bất kỳ thông báo lỗi nào có thể được tạo bởi biểu thức đó sẽ bị bỏ qua.

Nếu bạn đã thiết lập một chức năng xử lý lỗi tùy chỉnh với set_error_handler() sau đó nó vẫn sẽ được gọi, nhưng xử lý lỗi tùy chỉnh này có thể (và nên) gọi error_reporting() đó sẽ trở lại 0 khi cuộc gọi đã làm hiển thị các lỗi đã được đi trước bởi một @ .

<?php 
/* Intentional file error */ 
$my_file = @file ('non_existent_file') or 
    die ("Failed opening file: error was '$php_errormsg'"); 

// this works for any expression, not just functions: 
$value = @$cache[$key]; 
// will not issue a notice if the index $key doesn't exist. 

?> 

Lưu ý: -

1) Các @ -operator chỉ hoạt động trên các biểu thức.

2) Quy tắc chung đơn giản là: nếu bạn có thể lấy giá trị của thứ gì đó, bạn có thể thêm toán tử @ vào nó. Ví dụ, bạn có thể thêm nó vào các biến, hàm và bao gồm các cuộc gọi, các hằng số, v.v. Bạn không thể thêm nó vào chức năng hoặc các định nghĩa lớp, hoặc các cấu trúc có điều kiện như nếu và foreach, v.v.

Cảnh báo: -

Hiện nay "@" lỗi kiểm soát điều hành tiền tố thậm chí sẽ vô hiệu hóa báo cáo lỗi cho các lỗi quan trọng là sẽ chấm dứt kịch bản thực hiện. Trong số những thứ khác, điều này có nghĩa là nếu bạn sử dụng "@" để ngăn chặn lỗi từ một chức năng nhất định và không có sẵn hoặc đã bị nhập sai, tập lệnh sẽ chết ngay tại đó mà không có chỉ dẫn .

23

Như đã trả lời trước đây: Toán tử @ triệt tiêu tất cả các lỗi trong PHP, bao gồm thông báo, cảnh báo và thậm chí cả các lỗi nghiêm trọng.

NHƯNG:Xin vui lòng, thực sự không sử dụng toán tử @ ở tất cả.

Tại sao?

Vâng, bởi vì khi bạn sử dụng toán tử @ để điều chỉnh lỗi, bạn không có đầu mối nào bắt đầu khi xảy ra lỗi. Tôi đã có một số "vui vẻ" với mã kế thừa, nơi một số nhà phát triển đã sử dụng toán tử @ khá thường xuyên. Đặc biệt trong các trường hợp như hoạt động tệp, cuộc gọi mạng, v.v.Đó là tất cả các trường hợp mà nhiều nhà phát triển khuyên bạn nên sử dụng toán tử @ vì điều này đôi khi nằm ngoài phạm vi khi có lỗi xảy ra ở đây (ví dụ: API của bên thứ ba có thể không truy cập được, v.v.).

Nhưng điểm nào vẫn không sử dụng? Chúng ta hãy có một cái nhìn từ hai quan điểm:

Là một nhà phát triển: Khi @ được sử dụng, tôi đã hoàn toàn không biết bắt đầu từ đâu. Nếu có hàng trăm hoặc thậm chí hàng ngàn cuộc gọi chức năng với @ lỗi có thể giống như mọi thứ. Không thể gỡ lỗi hợp lý trong trường hợp này. Và ngay cả khi đó chỉ là lỗi của bên thứ ba - thì nó vẫn ổn và bạn đã hoàn thành nhanh. ;-) Hơn nữa, tốt hơn là bổ sung đủ chi tiết vào nhật ký lỗi, vì vậy các nhà phát triển có thể quyết định dễ dàng nếu mục nhập nhật ký là thứ phải được kiểm tra thêm hoặc nếu đó chỉ là lỗi của bên thứ ba nằm ngoài phạm vi của nhà phát triển.

Là người dùng: Người dùng không quan tâm đến tất cả lý do lỗi là gì hay không. Phần mềm là có cho họ để làm việc, để hoàn thành một nhiệm vụ cụ thể, vv Họ không quan tâm nếu đó là lỗi của nhà phát triển hoặc một vấn đề bên thứ ba. Đặc biệt đối với người dùng, tôi khuyên bạn nên ghi lại tất cả các lỗi, ngay cả khi chúng nằm ngoài phạm vi. Có thể bạn sẽ nhận thấy rằng một API cụ thể đang ngoại tuyến thường xuyên. Bạn có thể làm gì? Bạn có thể nói chuyện với đối tác API của mình và nếu họ không thể giữ ổn định, bạn có thể nên tìm một đối tác khác.

Nói tóm lại: Bạn nên biết rằng có tồn tại một cái gì đó giống như @ (kiến thức luôn luôn là tốt), nhưng chỉ không sử dụng nó. Nhiều nhà phát triển (đặc biệt là những mã gỡ lỗi từ những người khác) sẽ rất biết ơn.

+1

Một số cảnh báo chỉ có thể bị chặn một cách đáng tin cậy bằng cách sử dụng @ (ví dụ: fopen(), nếu có bất kỳ nỗ lực nào để dự đoán kết quả là điều kiện chủng tộc), nếu bạn có mã để xử lý tình trạng lỗi theo cách gọn gàng hơn thì sử dụng '@' điều đúng đắn làm, điều này đặc biệt hữu ích đặc biệt là nếu bạn không trả về 'text/html' (hoặc tương tự) cho khách hàng. (có thể trả về 'hình ảnh/png' hoặc 'json') – Jasen

+0

Bạn không nên kìm nén cảnh báo - họ nói rằng bạn đã làm điều gì sai trái. Không có điều kiện chủng tộc nào mà bạn không thể kiểm tra hoặc xử lý trạng thái đúng cách. –

1

Nó có thể là giá trị thêm ở đây có một vài gợi ý khi sử dụng @ bạn nên biết, đối với một hoạt động hoàn toàn xuống xem bài này: http://mstd.eu/index.php/2016/06/30/php-rapid-fire-what-is-the-symbol-used-for-in-php/

  1. Việc xử lý lỗi vẫn bị sa thải ngay cả với biểu tượng @ được thêm vào trước, nó chỉ có nghĩa là mức lỗi 0 được thiết lập, điều này sẽ phải được xử lý một cách thích hợp trong trình xử lý lỗi tùy chỉnh.

  2. prepending một bao gồm với @ sẽ đặt tất cả các sai sót trong các tập tin bao gồm một mức độ lỗi của 0

Các vấn đề liên quan