質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

エラー制御演算子(式への@追記)について(PHP)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 160
退会済みユーザー

退会済みユーザー

よろしくお願いいたします。

PHPバージョン: 7.4

phpリファレンスよりエラー制御演算子を調べておりましたが、

php式の前に@を記載した場合にその式は無視される

とあります。

こちらは、error_reporting(E_ALL)などで、エラー内容を表示させた際に、
@をつけた任意式にエラーが発生していても、エラー内容に反映されないということなのでしょうか。

例としてリファレンスより以下

<?php
/* 意図的なエラー */
$my_file = @file ('non_existent_file') or
    die ("Failed opening file: error was '$php_errormsg'");

?>

上記のケースであれば、
@file ('non_existent_file')die ("Failed opening file: error was '$php_errormsg'");がありますが、

最初のエラー処理
1.@file ('non_existent_file')ではファイルが存在しないためE_WARNINGを返す処理
2.die ("Failed opening file: error was '$php_errormsg'")にて直近エラー文を任意文字とともに表示

の2通りのエラー表示があるかと思われますが、最初の行には@がふられているため、
2の処理のみ表示されるという認識で良いのでしょうか。

助言などいただけますと幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2020/07/10 19:13

    実際に組んで動かしてみれば明白かと思いますが、如何でしょうか。

    キャンセル

  • m.ts10806

    2020/07/10 19:14

    あと、APCや排他制御は直接関係ないのでは?

    キャンセル

  • m.ts10806

    2020/07/10 19:15

    あと、エラー出力についてはバージョンによって違ってくることもあります。想定のバージョンも提示された方が良いかとは思います(PHPマニュアルにも記載はあることはあります)

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2020/07/10 19:16

    Larevel上にて確認していたため、デフォルトでLaravelによるエラー表示がされてしまっておりました。
    Laravelと無関係にブラウザで確認すれば良いのですが、なぜかphpファイルを作成してVSCODEよりブラウザ上で確認(ドラッグドロップで)しようとするとうまくいかなかったので質問させていただきました。

    CODEPENなどで確認できるかもしれません、
    ちょっと調べてみます。

    キャンセル

回答 2

checkベストアンサー

0

1つ目が実行されてエラーが回避されますがfalseになるため
orで次のdieが実行されます

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/10 20:06

    @の処理はエラーが見つけづらくなるので、あまり推奨はされません
    例外処理やアサーションで対応するのが普通です

    キャンセル

  • 2020/07/12 14:43

    ご回答ありがとうございます!

    なるほどです。このorを使用した記述方法は
    if(){
    } else {
    }
    を示しているのですね。

    ただ、@マークをつける意味がいまいち理解できていません....

    自分の解釈では”@以降の式が無視される”という認識だったので、てっきりif条件式は無視される。
    つまり、elseのdie()処理のみ実行される意味合いかと思っておりました

    キャンセル

0

書き直すとこんな感じになります。

※全く一緒ではないですがイメージ

if(@file ('non_existent_file')){
  $my_file = file ('non_existent_file');
}else{
  die ("Failed opening file: error was '$php_errormsg'");
}

そもそも論余程のことがない限り、使いません。
PHPマニュアルに警告が書いてありますね。

警告
現在、エラー制御演算子プレフィックス"@"は、スクリプトの実行を 終了するような致命的なエラーの出力さえ抑圧します。このため、ある関数の エラー出力を抑制するために "@" を使用した場合、その関数が 利用できなかったり、ミスタイプがあった場合でも、原因を示すことなく その場所でスクリプトは終了してしまいます。

ということもあり、エラー制御演算子の項から$php_errormsgを見ると、警告がありますね。

この機能は PHP 7.2.0 で 非推奨になります。この機能に頼らないことを強く推奨します。

つまり、質問者さんの環境であるPHPバージョン: 7.4では非推奨になっていることを指します。やがて削除される機能です。
5.2くらいからPHPを使ってる私ですが、@はともかく$php_errormsgについては自らの意思で使ったことは1度もないです。

制御しなければならないエラーは開発段階で極力洗い出して潰しておくべきですし、返却値がある関数はそれらを拾うとか別の機能で事前に担保しておくとか、Exceptionをthrowする機能であればtry-catchで拾うとか、むしろ積極的にエラーを拾って、問題解決に繋げる ことを覚えるべきかと思います。

今回で言えばfile()ファイルを配列に入れて返します。 配列の各要素はファイルの各行に対応します。改行記号はついたままとなります。 失敗すると file() は FALSE を返します。 ので、エラー制御演算子に頼らずともfalseが返ってきたら失敗と判断すれば良いのです。
ファイルが存在しない場合は E_WARNING レベルのエラーが発生します。 という説明書きがありますが、それならそもそもfile_existsで存在確認すれば「ファイルが存在しない場合は」という懸念を取り除いたうえで「ファイル読み込みの成功か否か」だけに注力したコードが書けるようになりますよね。

と言ったように、エラー制御演算子を使う必要性は、ないと言っても良いです。
ほとんどの機能において、安全に実行するための機能は十二分に整っています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/12 14:40

    ご回答ありがとうございました、非常に勉強になります。


    おっしゃる通り、非推奨とのことで確認不足でした。

    file()もあまり使用したことがないのいですが、特定ファイル情報を配列形式で格納するのですね。
    少し気になる点は、配列格納を行う際に単なる文字テキストが1行入ったファイルなどをfile()で格納すると、
    1つの要素だけの配列になるだけなのでしょうか。

    すみません、話が逸れてしまいましたが、アドバイスを参考に、こちらのエラー演算子よりtry-catchをしっかり学んでいきたいと思っております。

    修正いただいた以下

    if(@file ('non_existent_file')){
    $my_file = file ('non_existent_file');
    }else{
    die ("Failed opening file: error was '$php_errormsg'");
    }

    if(@file ('non_existent_file'))の箇所ですが、@マーク付きである場合は解釈としては
    non_existent_fileを読み込んだ場合という条件を@で否定しているということになるのでしょうか。
    つまりifでのtrue条件はないものとして扱われるのかなという印象なのですが....

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る