【问题标题】:Query works through phpMyAdmin but doesn't work through php script called from viewController查询通过 phpMyAdmin 工作,但不能通过从 viewController 调用的 php 脚本工作
【发布时间】:2013-11-30 17:32:41
【问题描述】:

我有一个 tableViewController,它显示按名称排序的地点列表!此列表是使用查询从我的 MySQL 数据库中检索到的

从城堡中选择 IDUser 按名称排序

但我的目标是根据 userLocation 按位置对它们进行排序。因此,数据库中的任何地方都有“纬度”和“经度”字段。

在我的 tableViewController 我这样做:

NSString *IDString = @"SELECT ID FROM Castle ORDER BY Name ASC";

NSMutableString *strURL = [NSMutableString stringWithFormat:@"http://localhost/myApp/fieldsRequest.php?query=%@",query];

[strURL setString:[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];

NSError* error;

NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:dataURL
                          options:kNilOptions
                          error:&error];

NSMutableArray *results = [[NSMutableArray alloc] init];

int numRow = 0;

for (NSArray *arrow in json) {
        [results addObjectsFromArray:arrow];
        numRow++;
}

return results;

被调用的脚本 php:

<?php
require 'mycredentials.php';
$resultCredentials = sdbmyCredentials();

if ($resultCredentials == YES) {
       $arr = array();

        $query = $_GET[query];
        $results = mysql_query($query) or die ("Unhandled exception: " . mysql_error());

       // Add the rows to the array 
       while($obj = mysql_fetch_row($results)) {
       $arr[] = $obj;
       }
       echo json_encode($arr);
    }
    ?>

它运行良好,我按名称检索地点列表。 相反,当我这样做时:

_IDString = [NSString stringWithFormat:@"SELECT ID FROM Castle ORDER BY (POW((longitude-%f),2) + POW((latitude-%f),2))", longitude,latitude];

NSMutableString *strURL = [NSMutableString stringWithFormat:@"http://localhost/myApp/fieldsRequest.php?query=%@",query];

[strURL setString:[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];

NSError* error;

NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:dataURL
                          options:kNilOptions
                          error:&error];

NSMutableArray *results = [[NSMutableArray alloc] init];

int numRow = 0;

for (NSArray *arrow in json) {
        [results addObjectsFromArray:arrow];
        numRow++;
}

return results;

我在字符串中作为参数给出的纬度和经度分别是 40.535568 和 16.503588 如果我在 phpMyAdmin 中运行 sql 命令:

从 Castle ORDER BY 中选择 ID (POW((longitude-16.503588),2)+POW((latitude-40.535568),2))

它工作得很好,它给了我结果。但是如果我按照我之前写的代码执行它,它不会产生结果,而是会出错:

未处理的异常:您的 SQL 语法有错误;检查 与您的 MySQL 服务器版本相对应的手册 在第 1 行的 'POW((latitude-40.535568),2))' 附近使用的语法

这是字符串地址:

http://localhost/myApp/fieldsRequest.php?query=SELECT%20ID%20FROM%20Castle%20ORDER%20BY%20(POW((longitude-16.503588),2)+POW((latitude-40.535568),2))

【问题讨论】:

  • 不相关,但在您的 PHP 中,您可能需要考虑使用 mysqli 或 PDO。见PHP: Choosing a MySQL API
  • 您的POW 错误,我面前没有电脑,但我在SQLite Core Functions 列表中看不到该功能。我会尝试将其简化为基本的算术表达式。

标签: php mysql ios objective-c json


【解决方案1】:

问题在于stringByAddingPercentEscapesUsingEncoding 通常只会转义那些在 URL 中无效的字符。但是通常在 URL 中允许使用某些字符(例如 &amp;+),但在 URL 参数中没有问题(例如 &amp; 分隔参数,+ 转换为空格字符)。

因此,您需要一种方法,而不是stringByAddingPercentEscapesUsingEncoding,它不仅可以百分比转义那些在 URL 中无效的字符,而且还可以转义那些通常在 URL 中可能具有特殊含义但在 URL 中存在问题的字符一个参数。在这种情况下,您希望对出现在 SQL 中的+ 进行百分比转义。

最简单的方法是使用CFURLCreateStringByAddingPercentEscapes,而不是stringByAddingPercentEscapesUsingEncoding

- (NSString *)percentEscapeURLParameter:(NSString *)string
{ 
    return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                     (CFStringRef)string,
                                                                     NULL,
                                                                     (CFStringRef)@":/?@!$&'()*+,;=",
                                                                     kCFStringEncodingUTF8));
}

顺便说一句,您应该将参数转义到 URL,而不是 URL 本身。

NSString *sql = [NSString stringWithFormat:@"SELECT ID FROM Castle ORDER BY (POW((longitude-%f),2) + POW((latitude-%f),2))", longitude, latitude];

NSString *percentEscapedSQL = [self percentEscapeURLParameter:sql];

NSString *strURL = [NSString stringWithFormat:@"http://localhost/myApp/fieldsRequest.php?query=%@", percentEscapedSQL];

// don't percent-escape the full URL
//
// [strURL setString:[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

顺便说一句,我非常不鼓励您在 URL 中传递 SQL 字符串。这是一个严重的安全风险。您应该只传递参数(例如纬度和经度),并让 PHP 验证这些参数,然后自行构建 SQL。

【讨论】:

  • 感谢@Rob Rob,但您知道将查询传递给脚本 php 保护它的方法吗?然后想办法在 php 中读取它?
  • @Pinturikkio 我不明白你的问题。最好的解决方案是根本不传递查询,而是传递参数(例如 lat 和 long),然后让 PHP 脚本自己构建 SQL。
猜你喜欢
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多