[PHP] @でエラーを回避するのはやめよう
篠原 隆司
えと、今さら感のある記事になってしまいますが・・・
他の記事を書いていたら副産物としてできてしまったので、書いておこうと思います。
エラー対策として、@ を使いたくなるかもしれません。
if ($fp = fopen("hoge.txt", "r")){
if ($fp = @fopen("hoge.txt", "r")){
この例では、fopenで、hoge.txtを開こうとしています。
1行目では、hoge.txtが存在しなければエラーが発生し、処理が中断し、エラー内容がブラウザに表示されてしまいます。
そこで、2行目のように書くことで、エラーを抑制することが可能なのですが・・・
実は、この @ が曲者で、非常に重い処理なんです。
ということで、 @ を使用するのはやめましょう。
・・・で、何を根拠に?という方は、実際にテストすることをオススメします。
下記がテストコード。説明はコードの下に続きます。
<?php
error_reporting(E_NOTICE);
// この数字をPCのスペックに合わせて大きくしてください
$LoopCount = 10000;
// @でエラー制御
$Start = getMicrotime();
for ($i = 0; $i < $LoopCount; $i++){
$hoge = @$fuga["fuga"];
}
echo '@有: ' . ($End1 = (getMicrotime() - $Start)) . '秒<hr />';
// 事前チェック方式
$Start = getMicrotime();
for ($i = 0; $i < $LoopCount; $i++){
if ( isset( $fuga["fuga"] ) ){ // 変数がセットされているか確認
$hoge = $fuga["fuga"]; // ↑がfalseなのでここは通らない
}
}
echo '事前: ' . ($End2 = (getMicrotime() - $Start)) . '秒<hr />';
echo '事前チェック方式が ' . ($End1 / $End2) . ' 倍早い';
// 現在のマイクロ秒を取得
function getMicrotime(){
list($msec, $sec) = explode(" ", microtime());
return ((float)$sec + (float)$msec);
}
?>
このテストコードの意味としては、事前に何もセットされていない $fuga["fuga"]; が突然現れて、しかもその値を$hogeに代入させようとしてしまった時のエラーです。
isset() は、引数の変数がセットされていればtrueを返します。
このように事前に値をチェックすることで、エラーを回避することができます。
最初に書いた、@fopen の場合ですと、事前にファイルが存在するか確認し、存在する場合だけfopenするように書き換えることができます。
if (file_exists("hoge.txt")){ // ファイルの存在確認
if ($fp = fopen("hoge.txt", "r")){