2015-06-02 103 views
1

我想知道从MySQL存储过程返回验证错误到PHP应用程序的最佳做法是什么。我见过Signals和正在使用的字符串,但我正在寻找一种自动处理错误的方法,以便将它们映射到“表单”字段。MySQL存储过程参数验证

例如,如果我有注册表单,我需要确保电子邮件不存在于系统中。所以我需要存储过程返回一个key => value ex。 "email" => "Duplicate entry for email"

我也想过在数据库中存储消息(将发送到客户端)可能没有意义。通过上面的电子邮件示例,"email" => "1062",然后在PHP应用程序中,有一个地图,1062 => "$key already exists."

我很高兴能够保持键=>(值/错误消息)关联,因此AJAX响应对象可以包含类似

// Http Status 400
{ "email": "Email already exists", "name": "Name is required" }

这样的电子邮件和名字的钥匙,并直接与他们的“名”和“电子邮件”的输入相关联。

<form> 
    <input name="name"/> 
    <input name="email"/> 
    <input type="submit" value="Submit"/> 
</form> 


<?php 
    $sanitizedInput = $_POST; //Pretend this data is actually sanitized. 
    $pdo = new PDO($dsn, $username, $password); 
    $stmt = $pdo->prepare("CALL registerUser(?, ?)"); 
    $stmt->bindParam(1, $sanitizedInput["name"]); 
    $stmt->bindParam(2, $sanitizedInput["email"]); 

    #Whats the best method for processing? 
    try{ 
     if($stmt->execute()){ 

     }else{ 

     } 
    }catch(PDOException $e){ 
    //I want to prevent doing string comparisons if possible 
    //Signal example 
    //It seems like this step could be automated and reused. 
    //For example, if we allow a user to update their email address, 
    //we could have the string 'Duplicate entry for email' in the 
    //codebase twice, and it seems like the process could be easily broken. 
    if($stmt->errorInfo[2] == 'Duplicate entry for email'){ 
     return array('email' => 'Email already exists'); 
    } 
    } 
?> 

#SQL 
signal sqlstate = '45000' set message_text = 'Duplicate entry for email' 

create procedure registerUser(
    name varchar(50), 
    email varchar(50) 
) 
begin 
declare emailExists int(0); 

select count(*) into emailExists from users where email = email; 

if emailExists = 0 then 
    insert into users values(default, name, email); 
else 
    //Return {email: 'Duplicate entry for email'} 
end 

回答

1

为什么你会运行在存储过程中的验证?为什么不使用PHP首先验证格式。然后第二次检查将这个查询

SELECT 1从电子邮件,其中电子邮件=“[email protected]” LIMIT 1

如果该查询返回1,这意味着记录是否存在?

如果你想使用存储过程这是一个过度杀死在这里。

您可以使用SQLEXCEPTION HANDLER

像这样

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
    BEGIN 
     GET DIAGNOSTICS CONDITION 1 
     @err_sqlstate = RETURNED_SQLSTATE, 
     @err_message = MESSAGE_TEXT, 
     @err_num = MYSQL_ERRNO; 

     SET @hasError = TRUE; 
    END; 

运行查询后,你可以做这样的事情

IF(@hasError) 

SELECT CONCAT("[", 
     GROUP_CONCAT(
      CONCAT("{message:'", @err_message,"'"), 
      CONCAT(",sqlState:'",@err_sqlstate),"'}") 
    ) 
,"]") AS jSON 
END IF; 
+0

也许验证是错误的用语,字符串格式检查在PHP中,但其他因素,如执行单个条目必须用SQL来完成。我会更新存储过程示例来解决我的问题。 –