PHP @ operatörü ile hatayı bastırmak [kapalı]

16 Cevap php

Sizce, bu işleme hatası olabilir oysa PHP bir hata / uyarı bastırmak için @ operatörü kullanmak hiç geçerlidir?

Eğer öyleyse, hangi koşullarda bu kullanmak istiyorsunuz?

Kod örnekleri bekliyoruz.

Düzenleme: repliers not. Ben kapalı raporlama hata açmak isteyen, ama değilim, örneğin, yaygın bir uygulama kullanmak için

@fopen($file);

ve daha sonra daha sonra kontrol ... ama sen yaparak @ kurtulabilirsiniz

if (file_exists($file))
{
    fopen($file);
}
else
{
    die('File not found');
}

veya benzeri.

Herhangi başka bir şekilde ele alınması OLAMAYACAĞINI, @ bir hata bastırmak için kullanılacak HAS her yerde yoktur - Ben soru sanırım?

16 Cevap

Ben hatayı bastırmak istiyorum and handle it. Aksi takdirde bir TOCTOU sorunu (Time-of-kontrol, zaman kullanım. Örneğin bir dosya File_exists true döndürür sonra silinir, ancak fopen önce alabilirsiniz) sahip olabilir.

Ama sadece onları uzağa gitmek için hatalarını bastırmak olmaz. Bunlar daha iyi görülebilir.

=================================================
Note: Firstly, I realise 99% of PHP developers use the error suppression operator (I used to be one of them), so I'm expecting any PHP dev who sees this to down vote me, but please bookmark this so that you can come back and change it to an up vote in a couple of years when you realise I was right. =================================================

Sizce, bu işleme hatası olabilir oysa PHP bir hata / uyarı bastırmak için @ operatörü kullanmak hiç geçerlidir?

Short answer:
NO!!!!!!!!!!!!!!!!!!!!

Longer more correct answer:
I don't know as I don't know everything, but so far I haven't come across a situation where it was a good solution.

Why it's bad:
In what I think is about 7 years using PHP now I've seen endless debugging agony caused by the error suppression operator and have never come across a situation where it was unavoidable.

Sorun hatalarını bastırmak olan kod parçası, şu anda sadece gördüğünüz hata neden olabilir olduğunu; Eğer çalışan hangi bastırılmış hat dayanır kodunu veya ortamı değiştirmek ancak, daha sonra hat çıkışına görmezden çalıştığınız birinden tamamen farklı bir hata dener her olasılığı vardır. Sonra nasıl çıkışı olmayan bir hata aşağı izlerim? Cehenneme ayıklama hoşgeldiniz!

Ben çünkü bastırılmış hataları her iki ayda israf ne kadar zaman gerçekleştirmek için birçok yılımı aldı. Çoğu zaman (ama tamamen değil) bu, çünkü hemen normal çıktı bir hata olurdu bir php veya sunucu yapılandırma farkı veya eksik bağımlılık benim değil geliştiriciler ortamda hatasız bir üçüncü taraf script / app / kitaplığı yükledikten sonra oldu, ama dev sihirli @ eklediğinde sorun neydi için uyaran, ama değil.

The alternatives (depending on situation and desired result):
Handle the actual error that you are aware of, so that if a piece of code is going to cause a certain error then it isn't run in that particular situation. But I think you get this part and you were just worried about end users seeing errors, which is what I will now address.

Onlar bu sayfayı görüntülerken ne zaman istediğiniz şekilde çıktı, ancak son kullanıcıların gizli ve kullanıcıların tetikleyen ne hataları biliyorum böylece açmış, böylece düzenli hataları için bir hata işleyicisi kurabilirsiniz.

Ölümcül hataları kapalı olarak display_errors ayarlamak için php ini de (hata işleyicisi hala tetiklenen alır) ve hata günlüğünü etkinleştirebilirsiniz. Eğer bir geliştirme sunucusu gibi o zaman bu adımı geliştirme sunucuda gerekli değildir, bu yüzden hala hata günlük dosyasına bakarak başvurmak zorunda kalmadan bu ölümcül hataları ayıklamak (I) tavsiye canlı sunucusu varsa. Hatta bir trick using the shutdown function hata işleyicisi için ölümcül hatalar büyük bir göndermek var.

In summary:
Please avoid it. There may be a good reason for it, but I'm yet to see one, so until that day it's my opinion that the (@) Error suppression operator is evil.

Eğer daha fazla bilgi istiyorsanız eğer PHP kılavuzdaki my comment on the Error Control Operators page okuyabilirsiniz.

Edit: Bir yorum yaptı varsa Btw 2 seçmenlerin şimdiye kadar (şaşırtıcıdır kadar 3) aşağı, bu harika olurdu. Ben bu konuda yanlış düşünüyorsam, o zaman ben neden duymak isteriz. Öte yandan, ben yeterince adil ardından, kibirli değilim çünkü sadece aşağı bana oy eğer. Bu adil bir çağrı var, ama sebebi olarak lütfen bunu belirtiniz.

Evet bastırma mantıklı.

Örneğin, fopen() komut verir FALSE dosya açılamaz eğer. Bu iyi, ama also PHP uyarı mesajı üretir. Genellikle uyarı istemiyorum - Eğer FALSE kendiniz için kontrol edeceğiz.

Aslında PHP manual, özellikle bu durumda @ kullanarak önerir!

(Fopen gibi fonksiyonları kullanırken atılan bir uyarı istemiyorsanız), hatayı bastırmak ama istisnaları kullanabilirsiniz:

try {
    if (($fp = @fopen($filename, "r")) == false) {
        throw new Exception;
    } else {
        do_file_stuff();
    }
} catch (Exception $e) {
    handle_exception();
}

Eğer know tüm şartları işleyebilir sürece hata bastırma kaçınılmalıdır.

Bu ilk bakışta göründüğünden çok daha zor olabilir.

Ne gerçekten yapmalıyım hataları bildirmek için sayfaları görüntülerken kullanıcılar güvenemez gibi, raporlama yöntemi olarak php "error_log" güvenmek olduğunu. (Ve aynı zamanda bu hataları görüntülemesini php devre dışı bırakmanız gerekir)

Sonra en azından sistemdeki yanlış gidiyor her şeyin kapsamlı bir rapor olacak.

Eğer gerçekten hataları işlemek gerekir, bir özel hata işleyicisi oluşturabilirsiniz

http://php.net/set-error-handler

Sonra muhtemelen (işlenebilir) istisnaları göndermek ve yönetimi için garip hataları bildirmek için gereken her şeyi yapabilirdi.

Kendimi kullanmak için izin ASLA '@' ... dönemi.

Ben kodu '@' kullanımını keşfetmek, ben kullanım noktasında, ve kullanıldığı fonksiyon etrafında bilgilendirme kısmı, hem de ışıl ışıl görünür kılmak için yorum eklemek. Ben de hatası nedeniyle bastırma bu tür hata ayıklama "bir hayalet peşinde", ve ben onu bulduğunuz zaman kullanımını vurgulayarak bir sonraki kişiye kolaylaştırmak için umut tarafından ısırıldı.

Ben bir doğal PHP işlevi bir hata ile karşılaştığında, ve '@' gitmek için kolay bir yol gibi görünüyor eğer bir Exception atmak için kendi kod isteyen kulüpler durumlarda, yerine aynı sonucu alır ama başka bir şey yapmak için tercih kodu (tekrar) ışıl ışıl görünür:

$orig = error_reporting(); // capture original error level
error_reporting(0);        // suppress all errors
$result = native_func();   // native_func() is expected to return FALSE when it errors
error_reporting($orig);    // restore error reporting to its original level
if (false === $result) { throw new Exception('native_func() failed'); }

Bu sadece yazı daha bir çok kod:

$result = @native_func();

ama bana şu zavallı ayıklama ruhun uğruna, benim bastırma çok bariz bir ihtiyaç yapmayı tercih.

@ Kullanmak bazen sayaç üretken. Benim durumumda, her zaman php.ini veya çağrı kapalı raporlama hatası açmalısınız

error_reporting(0);

bir üretim sitede. Eğer geliştirme Bu şekilde sadece satırı yorum ve hata ayıklama için görünür hataları tutabilirsiniz.

php.ini uyarıları ve hataları bastırmak için bir yol yok mu? bu durumda sadece bir bayrak değiştirerek ve sorunu gizleme hangi @ keşfetmek için çalışıyor değil hata.

Bu sizin komut yavaşlatır beri, her şeyi bastırmak istemiyorum.

Ve evet hataları kaldırmak (ama sadece bunu canlı bir ortamda zaman ve php sizin hataları log) php.ini ve komut dosyası içinde hem de bir yolu var

<?php
    error_reporting(0);
?>

Ve this kapatılmasını php.ini sürümü için okuyabilirsiniz.

Ben gerçekten bunu kullanmak için gereken tek yer eval fonksiyonudur. Eval ile sorun dize nedeniyle sözdizimi hata ayrıştırılamaz zaman, eval return false, ancak yerine bir hata atar, sadece normal komut içinde ayrıştırma hatası olması gibi değil, yani. Eğer gibi bir şey kullanabilirsiniz parseable dize depolanan komut olup olmadığını kontrol etmek için:

$script_ok = @eval('return true; '.$script);

AFAIK, bu bunu yapmak için en şık yoludur.

Most people do not understand the meaning of error message.
No kidding. Most of them.

They think that error messages are all the same, says "Something goes wrong!"
They don't bother to read it.
While it's most important part of error message - not just the fact it has been raised, but it's meaning. It can tell you what is going wrong. Error messages are for help, not for bothering you with "how to hide it?" problem. That's one of the biggest misunderstandings in the newbie web-programming world.

Böylece, yerine hata mesajı gagging arasında biri olmalıdır read ne diyor. Bu sadece bir değer "dosya bulunamadı" oldu. permission denied, save mode restriction, open_basedir restriction etc.etc: binlerce farklı hatalar olabilir. Her biri uygun eylem gerektirir. But if you gag it you'll never know what happened!

The OP is messing up error reporting with error handling, while it's very big difference!
Error handling is for user. "something happened" is enough here.
While error reporting is for programmer, who desperately need to know what certainly happened.

Böylece, hata mesajları hiçbir zaman gag. Her iki log it programcı için, ve handle it kullanıcı için.

Ben bunu bir paket almak değil, geçerli olsa bile, sen @ dahil yoksa bu konuda bir uyarı alırsınız ayarlanmış bir zaman aşımı varsa, bu, örneğin, soket kodu kullanmak tek yer.

$data_len = @socket_recvfrom( $sock, $buffer, 512, 0, $remote_host, $remote_port )

Bir özel hata işleme işlevini kullanıyorsanız ve istiyorum, bir hata (muhtemelen bilinen hata) bastırmak, bu yöntemi kullanın. Hata işleyicisi ayarlanırsa bu hatayı bastırmak olmayacak gibi '@' kullanılması, bu bağlamda iyi bir fikir değildir.

3 fonksiyonları yazmak ve böyle diyoruz.

# supress error for this statement
supress_error_start();  
$mail_sent = mail($EmailTo, $Subject, $message,$headers);
supress_error_end(); #Don't forgot to call this to restore error.  

function supress_error_start(){
    set_error_handler('nothing');
    error_reporting(0);
}

function supress_error_end(){
    set_error_handler('my_err_handler');
    error_reporting('Set this to a value of your choice');
}

function nothing(){ #Empty function
}

function my_err_handler('arguments will come here'){
      //Your own error handling routines will come here
}

DOMDocument nesne olarak işlenmesi için bir HTML dosyası yüklemeye çalışırken bunu kullanabilirsiniz. Orada HTML herhangi sorunlar ... ve ne et at least one yoksa sen @ ile bastırmak yoksa ... DOMDocument-> loadHTMLFile () bir hata atmak olacaktır. Bu şimdiye kadar PHP HTML kazıyıcı yaratmada başarılı oldum tek yolu (belki de daha iyi olanlar vardır).

Hatta "isset" "@" daha hızlı, ben hala kullanmayı tercih "@":

$_LOG_TYPES=array('request', 'done', 'click');

$t1=time().substr(microtime(),2,6);
for ($i=0;$i<10000;++$i)
    {$log_type=in_array(@$_GET['log_type'], $_LOG_TYPES)?$_GET['log_type']:'unknown';
    }
$t2=time().substr(microtime(),2,6);
echo 'time_length:'.((float)$t2-(float)$t1);

$t1=time().substr(microtime(),2,6);
for ($i=0;$i<10000;++$i)
    {$log_type=in_array(isset($_GET['log_type'])?$_GET['log_type']:null, $_LOG_TYPES)?$log_type:'unknown';
    }
$t2=time().substr(microtime(),2,6);
echo 'time_length:'.((float)$t2-(float)$t1);

output: time_length:15707time_length:6711

Ben genellikle (i saat önce sadece bir çift yazdı) bu gibi yapıları ile gelip php hataları ve uyarıları cehennem gibi rahatsız edici olduğunu düşünüyorum:

public function Load( $path, $options )
{
    if( @parent::Load( $path, $options ) )
    {
        $this->XInclude();
        $this->ResetXPath();
        $this->ResetHtml();
        $this->ApplyControls();
    }
    else
    {
        throw new WebPageTemplateLoadException( 'The template is not well-formed.' );
    }
}

Uzanan zaman WebPage sınıftadır hangi DOMDocument. İstisnalar imho hataları ile uğraşmak için temizleyici bir yolu vardır, o ölümcül olmayan veya ölümcül olabilir. Ve @ bastırılmasını, sizin günlükleri ya da daha kötüsü, komut kullanıcı görünür çıkışını uzak bırakırsanız will bunu gösteriyor.

Ben onun uygulanması c içinde ve php yabancı, sadece biraz daha fazla olduğu için (uzanan DOMDocument özel durum durumun bir tür olduğunu kabul ediyorum, ama evet, kullanan olacak @ bastırmak için tam olarak geçerlidir.