個人的には、コードが何をしているのかコメントしていないので、コードはまだかなり邪悪だと思います。また、入力の有効性をテストしていないため、非常に壊れやすくなっています。
また、evalの使用の95%(またはそれ以上)は積極的に危険であるため、他の場合に提供される可能性のあるわずかな時間の節約は、それを使用する悪い習慣にふける価値がないと感じています。さらに、後で、評価の使用が良い理由と悪い理由をミニオンに説明する必要があります。
そしてもちろん、PHPはPerlのように見えます;)
eval()には2つの重要な問題があります(「インジェクション攻撃」シナリオとして)。
1)害を及ぼす可能性があります2)単にクラッシュする可能性があります
そして、技術的というよりも社会的なもの:
3)他の場所へのショートカットとして不適切に使用するように人々を誘惑します
最初のケースでは、任意のコードが実行されるリスクがあります(明らかに、既知の文字列を評価しているときではありません)。ただし、入力は、思ったほど知られていないか、固定されていない可能性があります。
より可能性が高いのは(この場合)クラッシュするだけで、文字列は不当にあいまいなエラーメッセージで終了します。私見ですが、すべてのコードは可能な限りきちんと失敗し、失敗すると例外がスローされます(最も扱いやすい形式のエラーとして)。
この例では、動作に合わせてコーディングするのではなく、偶然にコーディングしていることをお勧めします。はい、SQL列挙型ステートメント(そして、そのフィールドの列挙型は確かですか?-データベースの適切なバージョンの適切なテーブルの適切なフィールドを呼び出しましたか?実際に答えましたか?)は、PHPの配列宣言構文のように見えます。しかし、あなたが本当にやりたいことは、入力から出力への最短パスを見つけることではなく、指定されたタスクに取り組むことです。
- 列挙型があることを確認します
- 内部リストを抽出する
- リスト値を解凍します
これはおおよそあなたのオプションの1つですが、わかりやすく安全にするために、ifとコメントをいくつかラップします(たとえば、最初の一致が一致しない場合は、例外をスローするか、nullの結果を設定します)。
エスケープされたコンマまたは引用符にはまだいくつかの問題が考えられます。おそらくデータを解凍してから引用符を外す必要がありますが、少なくともデータをコードではなくデータとして扱います。
preg_versionを使用すると、最悪の結果は$ result = nullになる可能性が高く、evalバージョンを使用すると、最悪の結果は不明ですが、少なくともクラッシュします。
$result = array(); preg_replace_callback('#^enum\s*\(\s*\'|\'\s*\)\s*$#', function($m) use($result) { $result[] = $m[1]; }, $type);