2016-10-14 6 views
1

は、私はそれぞれのuser_idためuser_tokenを更新し、この機能を持っている:この行ではデータベースを更新する前に変数のタイプをチェックしてください。 PHP

public function setUserToken($userId, $userToken) 
    { 
     $stmt = $this->conn->prepare("UPDATE $this->dbname.user SET user_token=:user_token WHERE user_id=:user_id;"); 

     try { 
      $stmt->bindParam(':user_token', $userToken, PDO::PARAM_STR, 70); 
      $stmt->bindValue(':user_id', "sdf", PDO::PARAM_INT); 
      $result['success'] = $stmt->execute(); 
      $result['message'] = "Successfully updated user_token for user_id " . $userId; 

     } catch (PDOException $e) { 
      $result['success'] = false; 
      $result['message'] = "Failed to update user_token with error: " . $e->getMessage(); 
     } 

     return $result; 
    } 

$stmt->bindValue(':user_id', "sdf", PDO::PARAM_INT);try-catch操作を、私はuser_idが整数でない場合は、エラーをスローするようにしようとしています。

ただし、失敗します。 PHPが自動的に "sdf" Stringを値0の整数に変換するからです。

ここでの解決策は何ですか?

+0

関数is_numericを使用して、user_idが数値であるかどうかをチェックして次の操作を実行します – Shibon

+0

PHPは文字列 "sdf"を値0のINTに変換するので失敗します。 'PDO :: PARAM_INT'を使ってINTにするuser_idがテーブルのプライマリキーである場合は、INTとなる可能性が高いため、常に文字列ではなくINTを渡す必要があります。 Shibonが述べるように、 'if(is_numeric($ userId)){//はい}'を使って変数をチェックしてから先に進むことができます。 – Blinkydamo

答えて

1

はい、正しいです。 PDOはバインディングで型キャストを強制しません。これはおそらく精度の可能性があるエラーによるものです。データベースがその問題によってソートされるようにするには、値を文字列として送る方が安全です。 PHP7で

あなたはそれがために持っているものの種類、PHPにヒントを持つ関数の引数を宣言することができます。あなたが望んでいたよう

function whatever (int $id) 
{ 
    echo $id; 
} 
whatever("sdf"); 

は例外をスローします。

PHPが古くなっている場合は、手動でチェックするコードを記述する必要があります。特定の関数を使用するには、変数のタイプまたはその内容をチェックするかどうかを決定する必要があります。前者については、is_int()関数を使用し、後者にはctype_digit()を使用できます。ほかに

if (!ctype_digit($user_id)) 
{ 
    throw new Exception("Whatever"); 
} 

、あなたのエラー処理が間違っている

注意。あなたは、here

を説明したように、クライアントに検証エラーを報告したい場合はエラー報告が、集中して安全に持っていながら

public function setUserToken($userId, $userToken) 
{ 
    $stmt = $this->conn->prepare("UPDATE $this->dbname.user SET user_token=:user_token WHERE user_id=:user_id;"); 

    $stmt->bindParam(':user_token', $userToken, PDO::PARAM_STR, 70); 
    $stmt->bindValue(':user_id', "sdf", PDO::PARAM_INT); 
    $result['success'] = true; 
    $result['message'] = "Successfully updated user_token for user_id " . $userId; 
    return $result; 
} 

ようなコードを残して、正しい場所にエラーをキャッチshoudn't私はそれに多くのポイントを参照してください、しかし、あなたはまだことをしたい場合は、どちらかの検証コードから直接このエラーメッセージを返す、

if (!ctype_digit($user_id)) 
{ 
    $result['success'] = false; 
    $result['message'] = "wrong data type"; 
} 

をまたは個別にValidationExceptionを作成し、それをスローし、これをキャッチし、送信しません。クライアントに報告する

+1

偉大な答え。 +1のphp7の参照とあなたに近づける111k! – padawanTony

+1

これを追加するだけで、PHPはデータを失わないときにも型変換を行います。例えば、5の代わりに$ userIdに "5"を使用した場合、PHPは自動的に文字列5を整数5に変換します。 これは特に問題ですが、自動変換を望まない場合スクリプトの最初の行に 'declare(strict_types = 1);'のような厳密な型指定をしなければなりません。 – padawanTony

+0

はい、まさにそのようです –

関連する問題