在AngularJS中捕获PDO异常

时间:2018-03-16 08:24:17

标签: php mysql angularjs pdo

所以我在AngularJS + PHP + MySQL中创建了一个SignUP表单,现在我想在我的角度中捕获PDO异常,所以我可以创建一个IF重复条目,例如'login'我可以在我的Angular中打印出来但是我不知道从哪里开始。我用谷歌搜索了一下但找不到任何真正有用的东西。

这是我的.controller

.controller('registerController', function($scope, $http) {
  $scope.registerData = {firstname : null, lastname : null, login: null, password : null, email : null, city : null, postalcode : null, adress: null, country: null};

  $scope.registerFunction = function() {
    $http({
        method: "post",
        url: './php/registration.php',
        data: {
            firstname: $scope.registerData.firstname,
            lastname: $scope.registerData.lastname,
            login: $scope.registerData.login,
            password: $scope.registerData.password,
            email: $scope.registerData.email,
            city: $scope.registerData.city,
            postalcode: $scope.registerData.postalcode,
            adress: $scope.registerData.adress,
            country: $scope.registerData.country,
        },
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    });
    swal("Good job!", "You have been registered!", "success");
  };
})

这是form中的html+bootstrap

  <div class="modal fade" id="registerModal">
    <div class="modal-dialog">
      <div class="modal-content" ng-controller="registerController">
        <div class="modal-header"><h4 class="modal-title">Sign Up</h4></br><button type="button" class="close" data-dismiss="modal">&times;</button></div>
        <div class="modal-body"><form>
            <div class="row">
                <div class="col-lg-6">
                  <label style="float: left;"><b>Firstname:</b></label>
                  <input type="text" ng-model="registerData.firstname" class="form-control">
                  <label style="float: left;"><b>Lastname:</b></label>
                  <input type="text" ng-model="registerData.lastname" class="form-control">
                  <label style="float: left;"><b><span class="redstar">*</span> Login:</b></label>
                  <input type="text" ng-model="registerData.login" class="form-control">
                  <label style="float: left;"><b><span class="redstar">*</span> Password:</b></label>
                  <input type="password" ng-model="registerData.password" class="form-control">
                  <label style="float: left;"><b><span class="redstar">*</span> Repeat Password:</b></label>
                  <input type="password" class="form-control">
                </div>
                <div class="col-lg-6">
                  <label style="float: left;"><b><span class="redstar">*</span> E-Mail:</b></label>
                  <input type="text" ng-model="registerData.email" class="form-control">
                  <label style="float: left;"><b>City:</b></label>
                  <input type="text" ng-model="registerData.city" class="form-control">
                  <label style="float: left;"><b>Postal Code:</b></label>
                  <input type="text" ng-model="registerData.postalcode" class="form-control">
                  <label style="float: left;"><b>Adress:</b></label>
                  <input type="text" ng-model="registerData.adress" class="form-control">
                  <label style="float: left;"><b>Country:</b></label>
                  <select class="form-control" ng-model="registerData.country" required>
                    <option ng-repeat="item in countries" value="{{item.id}}">
                      {{item.name}}
                    </option>
                  </select>
                </div>
                <div class="col-lg-12">
                  <p style="float:left;">Fields marked with <span class="redstar"><b>*</b></span> are required.</p></br>
                </div>
            </div>
        </form></div>
        <div class="modal-footer"><button type="button" class="btn btn-danger" data-dismiss="modal">Close</button><button type="button" class="btn btn-success" data-dismiss="modal" ng-click="registerFunction()">Sign Up</button></div>
        </div></div>
    </div>

这就是我执行它的方式:

<?php
include_once 'config.php';
$data = json_decode(file_get_contents("php://input"));

$firstname = $data->firstname;
$lastname = $data->lastname;
$login = $data->login;
$password = $data->password;
$email = $data->email;
$city = $data->city;
$postalcode = $data->postalcode;
$adress = $data->adress;
$country = $data->country;

$dbh->query("INSERT INTO `accounts` (`account_id`, `firstname`, `lastname`, `login`, `password`, `email`, `city`, `postalcode`, `adress`, `country`, `role`)
    VALUES (NULL,'".$firstname."','".$lastname."','".$login."',MD5('".$password."'),'".$email."','".$city."','".$postalcode."','".$adress."','".$country."', 0) ") or die(mysql_error());
$dbh = null;
?>

这是我的联系:

<?php
$hostname='localhost';
$username='root';
$password='';

try {
    $dbh = new PDO("mysql:host=$hostname;dbname=myshop",$username,$password);

    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // <== add this line
    echo 'Connected to Database';
}
catch(PDOException $e)
    {
    echo $e->getMessage();
    }
?>

我的问题是我怎么能在我的控制器中添加和If,就像有一个错误重复的“登录”条目我在我的角度做了一些事情。那么如何将错误记录到我的控制器中呢?

2 个答案:

答案 0 :(得分:2)

您无法在客户端代码中捕获服务器端异常,异常不会通过HTTP传播。您需要进一步抽象:客户端向服务器发出HTTP请求,服务器返回HTTP状态代码和响应内容。如果服务器上发生异常或其他任何错误,服务器会使用HTTP状态代码向客户端发出信号。因此,如果发生异常,您可以设置适当的代码:

try {
    ...
} catch (PDOException $e) {
    header('HTTP/1.0 500 Internal Server Error');
    // Maybe: echo json_encode(['error' => 'You fool!']);
    exit;
}

事实上,如果您只是 catch异常并让PHP死于未处理的异常错误,那么Web服务器将通过默认使用此类500状态代码进行回复。

在客户端,这将导致$http承诺拒绝,您可以处理:

$http(...)
    .catch(response => {
        console.error('Error fooing the bar', response.statusText);
        // do something constructive
    });

选择适当的状态代码进行回复以区分各种条件:https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

答案 1 :(得分:2)

除了@deceze的答案之外,还有一件事需要解释。

有两种例外:预期和意外的例外。他们应该区别对待。

你要求的是一个预期的。已经采用的用户名是常规用例,从应用程序的角度来看,我不会将其称为错误。因此,响应也应该是正常的。应该向Angular发送一条有意义的消息,后者应该采取相应的行动:提示用户尝试另一个用户名。

另一件事是意外错误。比如你的数据库服务器坏了。对于这种错误,不应该显示特定的错误消息,而是一个通用的借口和稍后尝试的建议。

现在执行:你应该捕获预期的错误,否则不应该

我的PDO tutorial中可以看到一个例子:

try {
    $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data);
} catch (PDOException $e) {
    $existingkey = "Integrity constraint violation: 1062 Duplicate entry";
    if (strpos($e->getMessage(), $existingkey) !== FALSE) {
        // Take some action if there is a key constraint violation, i.e. duplicate name
    } else {
        throw $e;
    }
}

在这里你可以看到一个被捕获的异常应该针对预期错误列表进行测试,并且重新抛出id没有匹配。