22

これに対するいくつかの回答を見つけましたが、PHP (非常に弱い型付き言語) に関連するものはありません。

PHPに関して、通常は配列を返すメソッドで false、null、または空の配列を返すことは適切ですが、エラーが発生しますか?

言い換えれば、別の開発者が私のプロジェクトに参加した場合、彼らは何を期待するでしょうか?

4

8 に答える 8

39

配列は物の集まりです。空の配列は、「すべてがうまくいきました。そのコレクションには何もありません」というシグナルになります。実際にエラーを通知したい場合は、返さなければなりませんfalse。PHP は動的に型付けされるため、必要に応じて戻り値を厳密にまたは緩やかにチェックするのは簡単です。

$result = getCollection();

if (!$result)           // $result was false or empty, either way nothing useful
if ($result === false)  // an actual error occurred
if ($result)            // we have an array with content

例外的な場合のエラー報告にも例外があります。それは、関数の責任とエラーの重大度に大きく依存します。関数の役割が「空のコレクション」と「いいえ」を同等に応答できる場合は、上記で問題ないかもしれません。ただし、関数が定義により常にコレクションを返す必要があり (たとえそれが空であっても)、特定の状況ではそれができない場合は、例外をスローする方が を返すよりもはるかに適切な場合があります。false

于 2012-07-18T07:26:22.603 に答える
15

混合型の戻り値を返すことは強くお勧めしません。私はそれが非常に問題であると考えているので、混合型の値を返さないことについての小さな記事を書きました。

質問に答えるには、空の配列を返します。以下に、他の値を返すと問題が発生する理由の小さな例を示します。

// This kind of mixed-typed return value (boolean or string),
// can lead to unreliable code!
function precariousCheckEmail($input)
{
  if (filter_var($input, FILTER_VALIDATE_EMAIL))
    return true;
  else
    return 'E-Mail address is invalid.';
}

// All this checks will wrongly accept the email as valid!
$result = precariousCheckEmail('nonsense');
if ($result == true)
  print('OK'); // -> OK will be given out

if ($result)
  print('OK'); // -> OK will be given out

if ($result === false)
  print($result);
else
  print('OK'); // -> OK will be given out

if ($result == false)
  print($result);
else
  print('OK'); // -> OK will be given out

これがいくつかの誤解を防ぐのに役立つことを願っています。

于 2012-07-18T08:36:54.177 に答える
5

私自身について言えば、私は通常、空の配列を返すことを好みます。関数が常に配列を返す場合は、PHPの配列関数とforeach(空の配列を受け入れる)で安全に使用できるからです。nullまたはfalseを返す場合は、結果を配列関数に渡す前に、結果の型を確認する必要があります。

メソッドが正しく実行されたが結果が見つからなかった場合と、メソッドでエラーが発生した場合を区別する必要がある場合は、例外が発生します。前者の場合は、空の配列を返すのが安全です。 。後者では、単に空の配列を返すだけでは、エラーが発生したという事実を通知するには不十分です。ただし、配列以外のものを返す場合は、呼び出し元のコードでそれを処理する必要があります。例外をスローすると、適切なエラーハンドラーの他の場所でエラーを処理でき、エラーが発生した理由を説明するメッセージとコードを例外に添付できます。

以下の擬似コードは、関心のあるものが見つからない場合、単に空の配列を返します。ただし、返されたもののリストを処理するときに問題が発生した場合は、例外がスローされます。

method getThings () {
    $things = array ();
    if (get_things_we_are_interested_in ()) {
        $things [] = something_else ();
    } 
    if (!empty ($things)) {
        if (!process_things ($things)) {
            throw new RuntimeExcpetion ('Things went wrong when I tried to process your things for the things!');
        }
    }
    return $things;
}
于 2012-07-18T07:19:22.360 に答える
5

これは、おそらく1960年代から有効な現代の答えです。

PHP の初期のバージョン (PHP 4 より前) でのいくつかの不適切な設計選択により、多くの PHP 開発者は常に悪い慣習にさらされてきました。幸いなことに、PHP 5 が登場してはなくなりました。これは、多くの PHP 開発者を「正しい道」に導くのに役立ちました。

PHP 7 は、PHP 5 フェーズを通過したことによる利点を実感しています。PHP 7 は、現存するスクリプト言語の中で最も高速に動作する言語の 1 つです。

  • これにより、PHP 7 は現存する最も高速で強力なスクリプト言語の 1 つになりました。

PHP バージョン 4 以降、PHP コア開発者は、PHP 言語を徐々に改善するために多大な努力を払ってきました。下位互換性を維持したいので、多くのものが残っています。

エラー時にfalseを返さないでください

エラーの場合に FALSE を返すことができるのは、関数の名前がisEverythingFine().

falseエラーに対して返される値は常に間違っていました。PHP ドキュメントにまだ表示されている理由は、下位互換性のためです。

  1. それは一貫性がないでしょう。true関数がブール値またはを返すはずの場合、エラーで何を返しますかfalse?

  2. 関数がブール値以外のものを返すことになっている場合は、型チェックを処理するコードを書く必要があります。多くの人は型チェックを行わないため、PHP オペコード コンパイラも型チェックを行うオペコードを作成する必要があります。ダブルタイプチェックができます!

null を返すことができます

ほとんどのスクリプト言語はnull、データ型の値を効率的に規定しています。理想的には、その値の型を使用することさえありませんが、例外をスローできない場合は、null. これは、PC の内部で有効な値でなくても、PHP のすべてのデータ型に対して有効な「値」です。

コンピュータ/CPU にとって最適なのは、値全体が単一の 1、2、4、または 8 バイトのメモリ「セル」にあることです。これらの値のサイズは、すべてのネイティブ値の型に共通です。

値が許可されている場合null、これは別のメモリ セルにエンコードする必要があり、コンピューターが値を関数に渡したり返したりする必要がある場合は常に、2 つの値を返す必要があります。1 つは値を含みisNull、もう 1 つは値を表します。

タイプによっては特別な値を返す場合があります

これは理想的ではありません。

  • 関数が整数を返すことになっている場合は、-1 を返します。
  • 関数が文字列を返すことになっている場合

例外をスローする必要があります

例外は、ほとんどの CPU の内部動作と一致します。例外的なイベントが発生したことを宣言するための専用の内部フラグがあります。

これは非常に効率的であり、そうでなかったとしても、エラーのない通常の状況では多くの余分な作業が必要ないという大きなメリットがあります。

于 2020-01-07T15:31:23.303 に答える
3

状況とエラーの程度によって異なりますが、例外をスローするのが適切な(そして見過ごされがちな)オプションです。

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    else return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

これにより、関数がサイレントに失敗したり、エラーが見えなくなったりすることがなくなります。

于 2012-07-18T07:19:54.987 に答える
2

メソッドの戻り値の型は配列であると想定しているため、実行は成功したが結果が見つからなかった場合にのみ、空の配列を返す必要があります。

エラーが発生した場合は、例外をスローする必要があります。これは、エラーを処理するための推奨される方法です。

于 2013-09-13T12:43:02.967 に答える
0

どちらをお好みでも、正当な理由で空の配列をお勧めします。最初にタイプを確認する必要はありません!

<?php
function return_empty_array() {
    return array();
}

$array = return_empty_array();

// there are no values, thus code within doesn't get executed
foreach($array as $key => $value) {
    echo $key . ' => ' . $value . PHP_EOL;
}
?>

それ以外の場合、falseまたはnullを返すと、foreachループでエラーが発生します。

私の意見では大きな違いですが、それは小さな違いです。取得した値のタイプを確認したくありません。配列であると想定します。結果がない場合は、空の配列です。

とにかく、私に関する限り、空の値を返すための「デフォルト」はありません。ネイティブPHP関数は、それが返す非常に異なる値で私を驚かせます。場合によってはfalse、場合によってはnull、場合によっては空のオブジェクト。

于 2012-07-18T07:19:34.533 に答える