0

配列をループしてtrue、配列の要素の1つで特定の部分文字列が見つかった場合にのみ返される単純な関数に苦労しています。

何らかの理由で、パラメータに有効なドメインの1つが含まれfalseている場合でも、常に...を取得しています。$email例:scoobydoo@domain1.com

function check_email($email) {
    $whitelist_domains = array(
        '@domain1.com',
        '@domain2.com',
        '@domain3.com'
    );
    $output = FALSE;
    foreach ($whitelist_domains as $domain) {   
        $pos = strpos( $email, $domain ); 
        if ( $pos ) {
            $output = TRUE;
        }
    }
    return $output;
}
4

6 に答える 6

2

ドメインが見つかった場合はループを中断していないため、実際に取得しているのは、チェックされたLAST文字列の結果のみです。break;後に追加する$output = TRUE;

于 2012-03-15T21:52:50.423 に答える
1

strposの公式ドキュメントから:

警告

この関数はブール値のFALSEを返す場合がありますが、FALSEと評価される非ブール値を返す場合もあります。詳細については、ブール値のセクションをお読みください。この関数の戻り値をテストするには、===演算子を使用します。

$outputまた、trueに設定した後は、必ずブレークを追加してください。

于 2012-03-15T21:54:19.380 に答える
0

これは===、値と型が等しいことを確認するため、演算子を使用するのに適した関数です(1==true、しかし1!==true

if (strpos( $email, $domain )!==false) {
    $output = TRUE;
}
于 2012-03-15T21:55:24.043 に答える
0

変化する

if ( $pos ) {

if ( $pos !== false) {

これは、strposが0を返すためです。これは、文字列が見つかった場合でもfalseに相当します。

于 2012-03-15T21:55:45.920 に答える
0

異なる利点を持つ2つの直接/一般的な方法を次に示します。

方法1:非正規表現アプローチ

function check_email1($email){
    $whitelist_domains=['@domain1.com','@domain2.com','@domain3.com'];
    foreach($whitelist_domains as $domain){
        if(strpos($email,$domain)!==false){
            return true;  // allow quick return (exit loop & function asap)
        }
    }
    return false;  // default response
}

方法2:正規表現アプローチ

function check_email2($email){
    $whitelist_pattern='/@(?:domain1\.com|domain2\.com|domain3\.com)$/';  // condense if possible /@domain[123]\.com$/
    return (bool)preg_match($whitelist_pattern,$email);  // convert 0 or 1 output to boolean (false/true)
}

デモリンク

入力/関数呼び出し

$emails=['user@domain1.com','bad@bad.com'];
foreach($emails as $email){
    echo "$email\n";
    var_export(check_email1($email));
    echo "\n";
    var_export(check_email2($email));
    echo "\n\n";
}

出力

user@domain1.com
true
true

bad@bad.com
false
false

長所/短所

  • ほとんどの状況でstrpos()は、正規表現関数よりもパフォーマンスが優れています。デフォルトの方法は、文字列関数を使用し、文字列関数の効率が低いか、コードが複雑すぎる場合にのみ正規表現に変更することです。関連ページ:PHPのPHP文字列関数と正規表現のどちらがより効率的ですか?

  • #1でループすると、#2と比較して見た目が不格好なコードブロックになります(パターンをpreg_match()$whitelist_domainsに直接書き込むと、ワンライナーに凝縮できます)。

  • を扱うときに、単純な/よくある間違いが発生することがありますstrpos()。これらの間違いには次のものが含まれます。

    • 状態をチェックしていませfalseif
    • haystackneedleを間違った順序で書く
  • #2には、経験の浅いコーダーの抑止力となる可能性のある正規表現(エスケープ、文字クラス、代替文字など)に関する知識が必要です。正規表現パターンの記述方法とホワイトリストに登録されるドメインの数によっては、#2は#1よりも維持が難しい可能性があります。

  • #2には、メタdomain.com文字を介して単語の最後に部分文字列が表示されることを確認できるという追加の利点があります。$このため、正規表現はより強力な検証を提供します。

于 2017-09-03T03:42:13.717 に答える
0

次のようにコードを変更する必要があります。

function check_email($email) {
    $whitelist_domains = array(
        '@domain1.com',
        '@domain2.com',
        '@domain3.com'
    );

    foreach ($whitelist_domains as $domain) {   
        if ( strpos( $email, $domain ) !== false ) {
            return true;
        }
    }
    return false;
}

のドキュメントstrpos

マニュアル(http://php.net/manual/en/function.strpos.php)からの引用:

!==演算子も使用できます。'a'の位置が0であるため、!=を使用しても期待どおりに機能しません。ステートメント(0!= false)はfalseと評価されます。

サンプルコード

<?php
$mystring = 'abc';
$findme   = 'a';
$pos = strpos($mystring, $findme);

// The !== operator can also be used.  Using != would not work as expected
// because the position of 'a' is 0. The statement (0 != false) evaluates 
// to false.
if ($pos !== false) {
     echo "The string '$findme' was found in the string '$mystring'";
         echo " and exists at position $pos";
} else {
     echo "The string '$findme' was not found in the string '$mystring'";
}
?>
于 2017-09-03T05:45:27.653 に答える