【问题标题】:How to return JSON from PHP in Swift?如何在 Swift 中从 PHP 返回 JSON?
【发布时间】:2017-07-11 23:59:11
【问题描述】:

我正在尝试从 PHP/PDO 返回 json,但在 Swift 中出现此错误。

错误域=NSCocoaErrorDomain 代码=3840 “垃圾结束。” UserInfo={NSDebugDescription=垃圾结束。}

这是 PHP 文件。

//*FUNCTION TO GET CARD FROM SEARCH WORD CALLED FROM GetCards.php   
public function getAllCards($word) {

//Connect to db using the PDO not PHP
$db = new PDO('mysql:host=localhost;dbname=xxxx', 'xxxx', 'xxxxx');

//Here we prepare the SELECT statement from the search word place holder :word
$sql = $db->prepare('SELECT * FROM carddbtable WHERE businessNameDB=:word OR lastNameDB=:word OR firstKeywordDB=:word OR    secondKeywordDB=:word OR thirdKeywordDB=:word OR fourthKeywordDB=:word OR fithKeywordDB=:word');

//We execute the $sql with the search word variable"$word"
$sql->execute([':word' => $word]);

//Looping through the results
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {

//Print to screen
 //  echo json_encode($row). "<br>"."<br>";

//Store all return rows in $returnArray
$returnArray[] = $row;
}

//Feedback results
return $returnArray;

}  

这是 Swift。

    //Search and retrieve card / users
func doSearch (word : String) {

    //Search word from searchKeyWordVar
    let word = "TODAY"

    // URL path to GetCards.php
    let url = NSURL(string: "http://www.xxxxxxx.com/xxx/xx/GetCards.php")

    //Create URL request
    let request = NSMutableURLRequest(url: url! as URL)

    //Method to pass info to GetCards.php
    request.httpMethod = "POST"

    //body that passing info to php
//        let body = "word=\(word)"
    let body = "TODAY" //This is hard coded for testing

    //convert string to utf8 for all languages
    request.httpBody = body.data(using: String.Encoding.utf8)


    //Launch session
    URLSession.shared.dataTask(with: request as URLRequest) { (Data, response, error) in


        //Get main Queue
        DispatchQueue.main.async(execute: {

            if error == nil {

                do {
                    // declare json var to store $returnArray inf we got from GetCards.php
                    let json = try JSONSerialization.jsonObject(with: Data!, options: .mutableContainers) as? NSDictionary


                    // delcare new secure var to store json
                    guard let parseJSON = json else {
                        print("Error while parsing")
                        return
                    }

                    // declare new secure var to store $returnArray["users"]
                    guard let parseUSERS = parseJSON["users"] else {
                        print(parseJSON["message"] ?? [NSDictionary]())
                        return
                    }

                } catch {
                    print(error)
                }


                } else {
                    print(error as Any)
                }


    })

}.resume()


}

快速错误是 错误域 = NSCocoaErrorDomain 代码 = 3840 “垃圾结束。” UserInfo={NSDebugDescription=垃圾结束。}

我只是没看到。当我从网页运行测试时,我得到的 json 看起来像这样。

{"users":[{"idDB":"383","addressNotsDB":"\n","alternateNameDB":"","alternateNumberDB":"","businessMainCategoryDB":"News"," businessNameDB":"TODAY"}]}

应用调用 GetCards.php 这调用 DBopperation.php 这有一个名为 getAllCards($word) 的 public_function

这是GetCards.php

//STEP: 1 Make connection to DB
//Including the db operation file for connection to DB
$cardConnect = require_once 'DbOperation.php';

//Checking if there is a connection to DB
if ($cardConnect) {
$returnArray1['Connected to DB'] = '200';
} else {
$returnArray1['Did not connect ot DB'] = '400';
}
//echo json_encode($returnArray1). "<br>"."<br>";


//STEP: 2 Connecting to Public Function
//Connecting the DbOperation.php file public fuction getAllCards to the       variable $card
$card = new DbOperation();

//If connected  
if ($card) {

//Checking connection to the DbOperation.php 
    $returnArray2['Connected to GetCards.php'] = '200';
} else {
    $returnArray2['Could not connect to GetCards'] = '400';
}
//echo json_encode($returnArray2). "<br>"."<br>";


//STEP: 3 Running the search
//Creating a varable to hold the search word and setting it to null
$word = null;

//Getting to search word from the app
if (!empty($_REQUEST["word"])) {
    $word = htmlentities($_REQUEST["word"]);
}
// STEP 4. Access searching func and retrieve data from server
$users = $card->getAllCards($word);

if (!empty($users)) {
    $returnArray3["users"] = $users;
} else {
    $returnArray3["message"] = 'Could not find records in GetCards';
}


// STEP 4. Close connection
$card->disconnect();

// STEP 5. Pass information back as json to user
echo json_encode($returnArray);

【问题讨论】:

  • 根据您的 PHP 代码,我认为您的 JSON 响应不可能看起来像您发布的内容。
  • 如果 JSON 解析失败,您应该打印数据的内容(例如 Swift 3 中的 print(String(data: data!, encoding: .utf8))),这样您就可以准确地看到它试图解析的内容。另请注意,Data 是 Swift 3 中类型的名称,因此我建议使用变量名称 data 而不是 Data
  • 什么叫getAllCards?服务器打印的响应在哪里?
  • 在您编辑答案后,您的 JSON 看起来更合理 - 至少显示的不仅仅是两个列字段。但为了获得 JSON“用户”数组,您至少必须将该行添加到数组对象中,例如 json_encode(array("users" =&gt; $returnArray));
  • DBOperation.php 没问题。我不得不编辑 GetCards.php 中的最后一行来回显 json_encode($returnArray3): 我离开了 3. 在 swift 中我必须更改 //body 将信息传递给 php // let body = "word=( word)" let body = "TODAY" //这是硬编码用于测试 "BACK TO" //将信息传递给 php 的 body let body = "word=(word)" // let body = "TODAY" //This被硬编码用于测试到处都有我必须更改为小写数据的数据。感谢大家的帮助。

标签: php mysql json swift pdo


【解决方案1】:

首先,您的问题在于服务器发送的数据:

echo json_encode($row). "<br>"."<br>";

为什么最后是垃圾?你应该发回 json,你为什么要添加错误的 html 标签?

echo json_encode($row);

其次,为什么要从函数中打印?

你定义你的函数,对于它获取的每一行,将打印一个 JSON 对象。在发布的示例中,您似乎只有一行,多于一行这将失败,因为{}{} 不是有效的 JSON 对象。

改成这样:

public function getAllCards($word) {

    ...

    //Looping through the results
    while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {

        //Store all return rows in $returnArray
        $returnArray[] = $row;
    }

    //Feedback results
    return $returnArray;
}  

那么你的调用者应该打印它:

$arrayOfResults = getAllCards();
echo json_encode( $arrayOfResults );

【讨论】:

  • 我编辑了返回的 json。这是我回声时得到的。
  • HTML 标记用于直接从网页测试 pdo。在 swift 应用程序中运行代码之前,我将回显排除在外。
【解决方案2】:

代码在每一行的末尾回显"&lt;br&gt;"."&lt;br&gt;",使 JSON 结构无效。你看不到这一点,因为这个 PHP 输出了一个 HTML 响应,在这种情况下,"&lt;br&gt;"."&lt;br&gt;" 只是添加了一些行......但是对于解析 JSON,它们是无效的。

我认为最正确的是将数组输出为 JSON 并告诉 HTTP 客户端这是一个 JSON 输出,如下所示:

//*FUNCTION TO GET CARD FROM SEARCH WORD CALLED FROM GetCards.php   
public function getAllCards($word) {

//Connect to db using the PDO not PHP
$db = new PDO('mysql:host=localhost;dbname=xxxx', 'xxxx', 'xxxxx');

//Here we prepare the SELECT statement from the search word place holder :word
$sql = $db->prepare('SELECT * FROM carddbtable WHERE businessNameDB=:word OR lastNameDB=:word OR firstKeywordDB=:word OR    secondKeywordDB=:word OR thirdKeywordDB=:word OR fourthKeywordDB=:word OR fithKeywordDB=:word');

//We execute the $sql with the search word variable"$word"
$sql->execute([':word' => $word]);

//Empty the returnArray
$returnArray = array();

//Looping through the results
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {

//Store all return rows in $returnArray
$returnArray[] = $row;
}

// Tell that is a JSON output
header('Content-Type: application/json');

//Feedback results
return json_encode($returnArray);

}  

【讨论】:

  • 错误域 = NSCocoaErrorDomain 代码 = 3840 “JSON 文本没有以数组或对象和允许未设置片段的选项开头。” UserInfo={NSDebugDescription=JSON 文本没有以数组或对象开头,并且允许未设置片段的选项。}
  • 我已经删除了所有的回声
  • 好吧,你可以使用类似的东西插入一个对象:return json_encode(array("users" =&gt; $returnArray));...试试看!这会输出一个带有标记为“用户”的集合的 JSON,我认为您的 Swift 代码需要...
【解决方案3】:

如果您的 JSON 输出是真正合法的 JSON,请尝试将您的 DispatchQueue 替换为:

    DispatchQueue.main.async(execute: {

        if error == nil {

            do {

                guard let jsonData = Data? else{
                    return
                }

                let json = try? JSONSerialization.jsonObject(with: jsonData)

                guard let parseJSONDict = json as? [String : Any] else{
                    print("Error while parsing")
                    return
                }

                guard let parseUSERS = parseJSONDict["users"] else{
                    return
                }


            } catch {
                print(error)
            }


            } else {
                print(error as Any)
            }


}) 

【讨论】:

  • 在构建它时出现错误。条件绑定的初始化程序必须具有可选类型,而不是 'Data.Type'
  • 可能需要保护让 jsonData = 数据?否则
  • 这是防备的 let jsonData = Data else{
  • 我现在开始工作了,我会发布所有的更改。感谢大家的帮助。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多