如何在Swift中处理PHP错误

我正在使用PHP& JSON从数据库提取一些数据.

这是我的PHP文件

<?PHP
error_reporting(0);
ini_set('error_reporting', E_ALL);
ini_set('display_errors','Off');
$MysqLi = new MysqLi("localhost", "root", $_REQUEST['password'], "");
if ($MysqLi->connect_errno) {
echo "Failed to connect to DB.";
die();
} else {
$dbs = array();
$res = $MysqLi->query("SHOW DATABASES");
$res->data_seek(0);
if ($res->num_rows > 0) {
    while($row = $res->fetch_assoc()) {
        $dbs[] = $row;
    }
    echo json_encode($dbs);
} else {
    echo "Failed to get list of databases from server.";
    die();
}} ?>

如果密码错误,则系统输出“无法连接到数据库

在我的程序中,我有一些可以处理错误的东西,但是我只能停留在一部分.

let urlString = "http://\(hostTextField.text):\(portTextField.text)/dblist.PHP?    &password=\(passtextField.text)"
    let url: NSURL  = NSURL(string: urlString)!
    let urlSession = NSURLSession.sharedSession()

        println(url)
        println(urlSession)

    //2
    let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in

        println(response)
        println(data)

        if (error != nil) {

            println("Can't connect using credentials")

                dispatch_async(dispatch_get_main_queue(), {

                    HUDController.sharedController.hide(afterDelay: 0.1)

                })

            sleep(1)
                var refreshAlert = UIAlertController(title: "Camaleon Reports", message: "Can't connect to the database", preferredStyle: UIAlertControllerStyle.Alert)
                refreshAlert.addAction(UIAlertAction(title: "Retry", style: .Default, handler: { (action: UIAlertAction!) in
                    println("Yes Logic")

                }))
                self.presentViewController(refreshAlert, animated: true, completion: nil)
                return }
        var err: NSError?
                            var jsonResult: [Dictionary<String, String>] = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as [Dictionary<String, String>]
        // 3
        if (err != nil) {

            println("Still cant connect....")
            println("JSON Error \(err!.localizedDescription)")
        }

        var jsonDB : [Dictionary<String, String>] = jsonResult
        for currentDictionary in jsonDB{
            var currentEntry = currentDictionary["Database"] as String!

如果我没有正确的密码,但是拥有正确的IP地址和MysqL数据库的端口/用户,我的程序将崩溃.

它崩溃与此:

Fatal error: unexpectedly found nil while unwrapping an Optional value

并指向jsonResult.这是有道理的,因为我没有检索两个字符串.

我的问题是,如果密码关闭,那么我的PHP文件将回显一个字符串.如何搜索该字符串,以便可以使用if语句并阻止应用程序崩溃?

解决方法:

您的问题可能在此行中(为清楚起见而包装):

var jsonResult: [Dictionary<String, String>] = 
    NSJSONSerialization.JSONObjectWithData(data, 
        options: NSJSONReadingOptions.MutableContainers, 
        error: &err) as [Dictionary<String, String>]

当您的PHP脚本仅通过返回字符串报告错误时,它返回了无效的JSON.当您使用NSJSONSerialization.JSONObjectWithData对其进行解析时,如果JSON无效,则该方法将返回nil,就像您一样.

然后,您可以将该值赋给您声明不是可选的Swift变量.试图将nil赋给未用任何一个声明的变量?要么 !是Swift中的运行时错误. (在编译时不会出现错误,因为您使用as来转换值.)

解决此问题的一种方法是更改​​您的PHP,以使错误是正确的JSON:

echo "{ \"error\": \"Failed to connect to DB.\" }"; # or something, my PHP is rusty

但这仍然使您的Swift程序处于脆弱状态.从服务器获取除正确JSON之外的任何内容都会使其崩溃.

更好的方法是将jsonResult变量声明为可选变量:

var jsonResult: [Dictionary<String, String>]? = 
    NSJSONSerialization.JSONObjectWithData(data, 
        options: NSJSONReadingOptions.MutableContainers, 
        error: &err) as [Dictionary<String, String>]?

然后,在代码中,您可以显式检查jsonResult是否为nil,如果是,则表明发生了错误,可以返回并查看数据对象以查看其含义.

即使这样,也会给您带来麻烦. JSON文档的根不必是字典.它可能是一个数组.即使它是字典,值也可能不是全部是字符串.它们可以是数字,布尔值,嵌套数组或字典!

Objective-C相对松散的类型检查使其易于处理,但是Swift更严格.最好是使用特定于Swift的JSONlibraries.这将使您的代码更加健壮.

祝好运!

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...