【问题标题】:Getting JSON from PHP script从 PHP 脚本获取 JSON
【发布时间】:2017-06-26 20:58:15
【问题描述】:

我正在开发一个需要从远程服务器获取数据的 iOS 应用程序。

这是从 PHP 脚本获取 JSON 数组的 Swift 代码:

func doSearch(_ searchWord: String)
    {
        // Dismiss the keyboard


        // Create URL
        let myUrl = URL(string: "...getAsesores.php")

        // Create HTTP Request
        let request = NSMutableURLRequest(url:myUrl!);
        request.httpMethod = "POST";

        if let x = UserDefaults.standard.object(forKey:"miCodigoAgencia") as? String
        {
            print (x)
        }


        let postString = "searchWord=\(UserDefaults.standard.object(forKey:"miCodigoAgencia"))";
        print (postString)
        request.httpBody = postString.data(using: String.Encoding.utf8);

        // Execute HTTP Request
        URLSession.shared.dataTask(with: request as URLRequest,
                                   completionHandler: { (data, response,error) -> Void in

            // Run new async task to be able to interact with UI
            DispatchQueue.main.async {

                // Check if error took place
                if error != nil
                {
                    // display an alert message
                    self.displayAlertMessage(error!.localizedDescription)
                    return
                }


                do {

                    // Convert data returned from server to NSDictionary
                    let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary



                    // Cleare old search data and reload table
                    self.searchResults.removeAll(keepingCapacity: false)


                    // If friends array is not empty, populate searchResults array
                    if let parseJSON = json {

                        if let friends  = parseJSON["friends"] as? [AnyObject]
                        {
                            let primerName = ["Nombre": "Selecciona un asesor" ,"Apellidos": " ", "Id": " ", "Tel": " ", "Email": " " ]
                             self.searchResults.append(primerName)

                            for friendObj in friends
                            {
                                let fullName = ["Nombre": friendObj["nombre"] as! String, "Apellidos": friendObj["apellidos"] as! String, "Id": friendObj["id"] as! String, "Tel": friendObj["tel"] as! String, "Email": friendObj["email"] as! String]

                                self.searchResults.append(fullName)

                            }


                            self.pickerAsesores.reloadAllComponents()

                        } else if(parseJSON["message"] != nil)
                        {
                            // if no friends returned, display message returned from server side
                            let errorMessage = parseJSON["message"] as? String

                            if(errorMessage != nil)
                            {
                                // display an alert message
                                self.displayAlertMessage(errorMessage!)
                            }
                        }
                    }

                } catch {
                    print(error);
                }

            } // End of dispatch_async


        }) // End of data task


        .resume()

    } // end of doSearch() function

然后是两个文件上的PHP部分:

文件 1 getAsesores.php:

<?php
require("../db/MySQLDAO.php");


$config = parse_ini_file('../../../SwiftPhp.ini');
$dbhost = trim($config["dbhost"]);
$dbuser = trim($config["dbuser"]);
$dbpassword = trim($config["dbpassword"]);
$dbname = trim($config["dbname"]);


$dao = new MySQLDAO($dbhost, $dbuser, $dbpassword, $dbname);
$dao->openConnection();

$searchWord = null;

if(!empty($_REQUEST["searchWord"]))
{
   $searchWord = htmlentities($_REQUEST["searchWord"]);
}

$friends = $dao->buscarAsesores($searchWord);


if(!empty($friends))
{
    $returnValue["friends"] = $friends;
} else {
    $returnValue["message"] = "Could not find records";
}

$dao->closeConnection();

echo json_encode($returnValue);

?>

还有文件2:MySQLDAO.php:

public function buscarAsesores($searchWord)
{
    $returnValue = array();

    $sql = "select * from members LEFT JOIN tb_agencias ON members.agencia_usuario = tb_agencias.id_agencia where 1";

    if(!empty($searchWord))
    {
        $sql .= " and ( codigo_agencia like ?  )";
          $sql .= " ORDER BY nombre";

    }

    $statement = $this->conn->prepare($sql);

    if (!$statement)
        throw new Exception($statement->error);

    if(!empty($searchWord))
    {
      $searchWord = '%' ;
      $statement->bind_param("s",  $searchWord );
    }

    $statement->execute();

    $result = $statement->get_result();

     while ($myrow = $result->fetch_assoc()) 
     {
       $returnValue[] = $myrow;
     }

    return $returnValue;
} 

如果我直接从浏览器调用PHP,结果不正确,查询没有按照我的意愿过滤记录,iOS应用显示所有记录。

如果我删除该行:

  $searchWord = '%' ;

正如我在 SO Weird filter result in PHP function 上一个问题中所评论的那样

在 MySQLDAO.php 中,查询会根据需要过滤记录,但应用程序会显示消息:Could not find records

欢迎任何帮助。

从@Chris 的正确答案更新为 SWIFT 3 的编辑代码:

 if let x = UserDefaults.standard.object(forKey:"miCodigoAgencia") as? String {
            print (x)
            var postString = "searchWord=\(x)".addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed);
            print (postString)
            request.httpBody = postString?.data(using: String.Encoding.utf8)
            request.setValue("\(request.httpBody?.count)", forHTTPHeaderField:"Content-Length")
        }

【问题讨论】:

    标签: php ios mysql json swift


    【解决方案1】:

    我看到了一些东西。

    1. 您将$searchWord 的值覆盖为始终为“%”。
    2. 在 iOS 应用程序中,您可能需要在请求中将 set the Content-Type header 转为 Form-savvy value。您可能还需要设置 Content-Length。 编辑:默认值为application/x-www-form-urlencoded,您需要实际对您的值进行url-encode ;-)
    3. 您可能希望在您的 sql 中用 %'s 包围您的搜索词

    对于数字 1,此代码:

    if(!empty($searchWord))
        {
          $searchWord = '%' ;
          $statement->bind_param("s",  $searchWord );
        }
    

    应该是这样的

    if(!empty($searchWord)) {
      $statement->bind_param("s",  $searchWord );
    }
    

    对于 iOS 应用中的 2 号,添加如下代码(注意我删除了对 UserDefaults 的多余调用):

    let request = NSMutableURLRequest(url:myUrl!);
    request.httpMethod = "POST";
    
    if let x = UserDefaults.standard.object(forKey:"miCodigoAgencia") as? String {
      print (x)
      var postString = "searchWord=\(x))".addingPercentEncoding(withAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet());
      print (postString)
      request.httpBody = postString.data(using: String.Encoding.utf8)
      request.setValue("\(request.httpBody.length)", forHTTPHeaderField:"Content-Length")
    }
    

    对于数字 3,将 " and ( codigo_agencia like ? )" 更改为 " and ( codigo_agencia like %?% )"(或仅使用后一个以使您的搜索需要匹配数据的开头)。

    【讨论】:

    • 谢谢@Chris,正如我的问题所述,第 1 点解决了过滤问题。但我需要你的帮助解决第 2 点
    • @mvasco 使用示例更新并更新到 #2,我认为您需要对正文进行实际 URL 编码。
    • 谢谢@Chris,我收到一条错误消息: var postString = "searchWord=(x))".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet());静态成员init(字符串插值段不能用于String类型的实例
    • 看起来该方法在 Swift 3 中已更改。已更新。如果它仍然给您带来麻烦,请将 postString 的分配分成两行。一个用于简单插值,另一个用于 URLEncoding。这应该可以帮助您更轻松地调试它。
    • 我将在我的问题中添加 Swift 3 的更新代码
    猜你喜欢
    • 2017-04-10
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 2011-04-28
    相关资源
    最近更新 更多