如何在Swift中从PHP返回JSON?

时间:2022-10-18 14:16:18

I am trying to return json from PHP / PDO but I get this error in Swift.

我试图从PHP / PDO返回json但我在Swift中收到此错误。

Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.}

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

Here is the PHP file.

这是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;

}  

Here is the 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()


}

Agin the swift error is Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.}

Agin swift错误是Error Domain = NSCocoaErrorDomain Code = 3840“垃圾结束时”。 UserInfo = {NSDebugDescription =结尾处的垃圾。}

I just don't see it. when I run the test from a web page I get json that looks like this.

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

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

{ “用户”:[{ “IDDB”: “383”, “addressNotsDB”: “\ n”, “alternateNameDB”: “”, “alternateNumberDB”: “”, “businessMainCategoryDB”: “新闻报”, “businessNameDB”: “今天”}]}

The app calls GetCards.php This calls the DBopperation.php This has a public_function named getAllCards($word)

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

This is the GetCards.php

这是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);

3 个解决方案

#1


1  

Your issue is with the data being sent by the server it seems, firstly:

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

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

Why the garbage at the end? You are supposed to be sending back json, why are you adding erroneous html tags?

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

echo json_encode($row);

Secondly, why are you printing from the function?

其次,为什么要从功能打印?

You define your function, that for each row it fetches, will print a JSON Object. In the posted example, you seem to only have a singe row, with more then one row this will fail as {}{} is not a valid JSON Object.

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

Change it to this:

把它改成这个:

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;
}  

Then your caller should print it:

然后你的来电者应该打印出来:

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

#2


0  

The code echoes an "<br>"."<br>" at the end of each row, witch invalidate the JSON structure. You cannot see this because this PHP output a HTML response and in this case the "<br>"."<br>" just add some lines... but for parsing the JSON they are invalid.

代码在每行的末尾回应“
”。“
”,使JSON结构无效。你不能看到这个,因为这个PHP输出一个HTML响应,在这种情况下是“
”。“
”只是添加一些行......但是为了解析JSON它们是无效的。

I think the most correct is to output the array as JSON and tell the HTTP client that is a JSON output, like this:

我认为最正确的是将数组输出为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);

}  

#3


0  

If your JSON output is truly legitimate JSON than try replacing your DispatchQueue with this:

如果您的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)
            }


}) 

#1


1  

Your issue is with the data being sent by the server it seems, firstly:

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

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

Why the garbage at the end? You are supposed to be sending back json, why are you adding erroneous html tags?

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

echo json_encode($row);

Secondly, why are you printing from the function?

其次,为什么要从功能打印?

You define your function, that for each row it fetches, will print a JSON Object. In the posted example, you seem to only have a singe row, with more then one row this will fail as {}{} is not a valid JSON Object.

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

Change it to this:

把它改成这个:

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;
}  

Then your caller should print it:

然后你的来电者应该打印出来:

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

#2


0  

The code echoes an "<br>"."<br>" at the end of each row, witch invalidate the JSON structure. You cannot see this because this PHP output a HTML response and in this case the "<br>"."<br>" just add some lines... but for parsing the JSON they are invalid.

代码在每行的末尾回应“
”。“
”,使JSON结构无效。你不能看到这个,因为这个PHP输出一个HTML响应,在这种情况下是“
”。“
”只是添加一些行......但是为了解析JSON它们是无效的。

I think the most correct is to output the array as JSON and tell the HTTP client that is a JSON output, like this:

我认为最正确的是将数组输出为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);

}  

#3


0  

If your JSON output is truly legitimate JSON than try replacing your DispatchQueue with this:

如果您的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)
            }


})