Apa gunanya simbol @ di PHP?

577

Saya telah melihat kegunaan @di depan fungsi-fungsi tertentu, seperti yang berikut:

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

Apa gunanya simbol ini?

sv_in
sumber
3
Baik RichieHindle dan Aiden Bell memberikan jawaban yang benar tetapi karena saya hanya dapat menetapkan satu jawaban sebagai diterima, saya akan memilih yang pertama. Maaf Aiden
sv_in
1
Menekan kesalahan (meskipun bagus) dapat menyebabkan kesalahan saat mempertahankan basis kode ... stackoverflow.com/a/7116175/282343
dennismonsewicz

Jawaban:

636

Ini menekan pesan kesalahan - lihat Operator Kontrol Kesalahan dalam manual PHP.

RichieHindle
sumber
46
Itu sedikit imbang cepat!
Aiden Bell
6
Ya; turun ke yang kedua! Aku harus memeriksa jawaban-id ini untuk melihat siapa yang datang pertama :)
Sampson
3
Saya punya waktu untuk memperbaiki ejaan penekan saya setelah memposting ... dan mengutuk Anda karena meningkatkan dengan link pada saat yang sama mengamuk : P
Aiden Bell
1
Fitur keren .. Itu membuat penggunaan yang isset()tidak perlu untuk menghindari undefined offsetkesalahan.
WM
470

Ini menekan kesalahan.

Lihat Operator Kontrol Kesalahan dalam manual:

PHP mendukung satu operator pengontrol kesalahan: tanda pada (@). Saat ditambahkan ke ekspresi dalam PHP, pesan kesalahan apa pun yang mungkin dihasilkan oleh ekspresi itu akan diabaikan.

Jika Anda telah menetapkan fungsi penangan kesalahan khusus dengan set_error_handler () maka masih akan dipanggil, tetapi penangan kesalahan khusus ini dapat (dan harus) memanggil error_reporting () yang akan mengembalikan 0 ketika panggilan yang memicu kesalahan didahului oleh @ ...

Aiden Bell
sumber
157
terangkat hanya karena jawaban yang lain adalah mendapatkan semua cinta.
ajacian81
10
19 di belakang ... ayo orang-orang mari kita kalahkan RichieHindle: P
Aiden Bell
Jawaban ini adalah yang pertama (Dalam konteks dengan siapa yang menjawabnya lebih dulu).
Mohd Abdul Mujib
227

The @simbol adalah kontrol kesalahan Operator (alias "diam" atau operator "shut-up"). Itu membuat PHP menekan semua pesan kesalahan (pemberitahuan, peringatan, fatal, dll) yang dihasilkan oleh ekspresi terkait. Ini berfungsi seperti operator unary, misalnya, ia memiliki prioritas dan asosiasi. Di bawah ini adalah beberapa contoh:

@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"

Apa yang sebenarnya terjadi jika Anda menggunakan penangan kesalahan khusus alih-alih penangan kesalahan PHP standar:

Jika Anda telah menetapkan fungsi penangan kesalahan khusus dengan set_error_handler () maka masih akan dipanggil, tetapi penangan kesalahan khusus ini dapat (dan harus) memanggil error_reporting () yang akan mengembalikan 0 ketika panggilan yang memicu kesalahan didahului oleh @ .

Ini diilustrasikan dalam contoh kode berikut:

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"

Penangan kesalahan tidak memeriksa apakah @simbol berlaku. Manual menyarankan yang berikut:

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

Perhatikan juga bahwa meskipun ada kesalahan yang disembunyikan, setiap penangan kesalahan kustom (diatur dengan set_error_handler) masih akan dieksekusi!

nickf
sumber
34

Seperti yang sudah dijawab sebelumnya: @Operator menekan semua kesalahan dalam PHP, termasuk pemberitahuan, peringatan, dan bahkan kesalahan kritis.

TAPI: Tolong, benar-benar tidak menggunakan @operator sama sekali.

Mengapa?

Nah, karena ketika Anda menggunakan @operator untuk penekanan kesalahan, Anda tidak memiliki petunjuk sama sekali dari mana harus memulai ketika kesalahan terjadi. Saya sudah bersenang-senang dengan kode lama di mana beberapa pengembang @cukup sering menggunakan operator. Terutama dalam kasus seperti operasi file, panggilan jaringan, dll. Itu semua adalah kasus di mana banyak pengembang merekomendasikan penggunaan @operator karena kadang-kadang di luar ruang lingkup ketika kesalahan terjadi di sini (misalnya API pihak ke-3 bisa dijangkau, dll. ).

Tapi apa gunanya masih tidak menggunakannya? Mari kita lihat dari dua perspektif:

Sebagai pengembang: Kapan@digunakan, saya sama sekali tidak tahu harus mulai dari mana. Jika ada ratusan atau bahkan ribuan panggilan fungsi dengan@kesalahan bisa seperti setiap tempat. Tidak ada debugging yang masuk akal dalam kasus ini. Dan bahkan jika itu hanya kesalahan pihak ke-3 - maka itu baik-baik saja dan Anda selesai dengan cepat. ;-) Selain itu, lebih baik untuk menambahkan rincian yang cukup ke log kesalahan, sehingga pengembang dapat memutuskan dengan mudah apakah entri log adalah sesuatu yang harus diperiksa lebih lanjut atau jika itu hanya kegagalan pihak ke-3 yang berada di luar ruang lingkup pengembang.

Sebagai pengguna: Pengguna tidak peduli sama sekali apa alasan kesalahan itu terjadi atau tidak. Software ada untuk mereka untuk bekerja, untuk menyelesaikan tugas tertentu, dll. Mereka tidak peduli apakah itu kesalahan pengembang atau masalah pihak ke-3. Khusus untuk pengguna, saya sangat menyarankan untuk mencatat semua kesalahan, meskipun mereka berada di luar jangkauan. Mungkin Anda akan melihat bahwa API tertentu sering offline. Apa yang bisa kau lakukan? Anda dapat berbicara dengan mitra API Anda dan jika mereka tidak dapat membuatnya stabil, Anda mungkin harus mencari mitra lain.

Singkatnya: Anda harus tahu bahwa ada sesuatu seperti @(pengetahuan selalu baik), tetapi jangan gunakan itu . Banyak pengembang (terutama kode debugging dari orang lain) akan sangat berterima kasih.

Andreas
sumber
1
Beberapa peringatan hanya dapat ditekan secara andal menggunakan @ (mis. Fopen (), di mana segala upaya untuk memprediksi hasilnya tunduk pada kondisi ras), jika Anda memiliki kode untuk menangani kondisi kesalahan dengan cara yang lebih rapi maka usuig @adalah hal yang benar dilakukan lakukan, ini sangat berguna terutama jika Anda tidak kembali text/html(atau serupa) ke klien. (mungkin kembali image/pngatau "json")
Jasen
1
Anda seharusnya tidak menekan peringatan - mereka menyatakan Anda telah melakukan kesalahan. Tidak ada kondisi balapan di mana Anda tidak dapat dengan benar memeriksa atau menangani keadaan.
Ryan Rentfro
1
Saya memiliki kode berikut di beberapa tempat. if( session_status() == PHP_SESSION_NONE ) session_start(); Ini adalah aplikasi lawas yang saya warisi, dan ada tempat di mana skrip penyiapan dipanggil beberapa kali, jadi saya harus mengujinya. Apa, jika ada, masalah apakah hanya dengan menggunakan @session_start();?
Stephen R
Jika Anda tahu apa yang Anda lakukan dan menggunakannya dengan hemat / strategis, layak digunakan. @$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;jauh lebih baik daripada alternatif memiliki menerbitkan cek di setiap tingkat dan mengisinya ketika tidak.
dtbarne
1
Berikan saya alasan yang bagus mengapa menambahkan 12+ baris kode dan menambahkan tidak ada nilai tetapi hanya mengurangi keterbacaan dan singkatnya kode ini layak dilakukan selain dari yang Anda baca di suatu waktu bahwa itu "sangat kotor" dan mungkin Anda dapat mengubah pikiran saya.
dtbarne
7

Misalkan kita belum menggunakan operator "@" maka kode kita akan terlihat seperti ini:

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

Dan bagaimana jika file yang kami coba buka tidak ditemukan? Ini akan menampilkan pesan kesalahan.

Untuk menekan pesan kesalahan, kami menggunakan operator "@" seperti:

$fileHandle = @fopen($fileName, $writeAttributes);
Sujeet Kumar
sumber
Ini adalah contoh sempurna mengapa PHP memiliki @solusi semacam ini sejak awal. Bahasa pemrograman lain memiliki penanganan pengecualian yang seragam untuk menangani skenario semacam ini stackoverflow.com/questions/1087365
dreftymac
@dreftymac Tepat!
Sujeet Kumar
5

Jika pembukaan gagal, kesalahan level E_WARNING dihasilkan. Anda dapat menggunakan @ untuk menekan peringatan ini.

Kishor Singh
sumber
5

@ menekan pesan kesalahan.

Ini digunakan dalam cuplikan kode seperti:

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

Jika domain " http://www.exaple.com " tidak dapat diakses, kesalahan akan ditampilkan, tetapi @tidak ada yang ditampilkan.

fico7489
sumber
1

PHP mendukung satu operator pengontrol kesalahan: tanda saat (@). Saat didahului dengan ekspresi dalam PHP, pesan kesalahan apa pun yang mungkin dihasilkan oleh ekspresi itu akan diabaikan.

Jika Anda telah menetapkan fungsi penangan kesalahan khusus dengan set_error_handler()maka masih akan dipanggil, tetapi penangan kesalahan kustom ini dapat (dan harus) memanggil error_reporting()yang akan kembali 0ketika panggilan yang memicu kesalahan didahului oleh @.

<?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.

?>

Catatan:-

1) @ -operator hanya berfungsi pada ekspresi.

2) Aturan praktis yang sederhana adalah: jika Anda dapat mengambil nilai sesuatu, Anda dapat menambahkan operator @ ke dalamnya. Misalnya, Anda bisa menambahkannya ke variabel, berfungsi dan menyertakan panggilan, konstanta, dan sebagainya. Anda tidak dapat menambahkannya ke definisi fungsi atau kelas, atau struktur bersyarat seperti jika dan foreach, dan sebagainya.

Peringatan:-

Saat ini awalan operator kontrol kesalahan "@" bahkan akan menonaktifkan pelaporan kesalahan untuk kesalahan kritis yang akan menghentikan eksekusi skrip. Antara lain, ini berarti bahwa jika Anda menggunakan "@" untuk menekan kesalahan dari fungsi tertentu dan entah itu tidak tersedia atau salah ketik, skrip akan mati di sana tanpa indikasi mengapa.

Ravi Hirani
sumber
1

Mungkin perlu menambahkan di sini ada beberapa petunjuk ketika menggunakan @ Anda harus menyadari, untuk menjalankan lengkap melihat posting ini: http://mstd.eu/index.php/2016/06/30/php- rapid-fire-what-is-the-symbol-used-for-in-php /

  1. Penangan kesalahan masih diaktifkan bahkan dengan simbol @ didahului, itu hanya berarti tingkat kesalahan 0 diatur, ini harus ditangani dengan tepat dalam penangan kesalahan kustom.

  2. Memertahankan sertakan dengan @ akan mengatur semua kesalahan dalam sertakan file ke tingkat kesalahan 0

ranting
sumber
1

@menekan pesan kesalahan yang dilemparkan oleh fungsi. fopenmelempar kesalahan saat file tidak keluar. @simbol membuat eksekusi untuk pindah ke baris berikutnya bahkan file tidak ada. Saran saya tidak akan menggunakan ini di lingkungan lokal Anda ketika Anda mengembangkan kode PHP.

Logamurugan Pilavadi Santhanam
sumber