查询通过phpMyAdmin工作,但不通过从viewController调用的php脚本工作

查询通过phpMyAdmin工作,但不通过从viewController调用的php脚本工作,php,mysql,ios,objective-c,json,Php,Mysql,Ios,Objective C,Json,我有一个tableViewController,它显示按名称排序的位置列表!此列表是使用查询从my MySQL数据库中检索的 按名称从Castle ORDER中选择IDUser 但我的目标是根据userLocation按位置对它们进行排序。因此,数据库中的任何位置都有纬度和经度字段 在我的tableViewController中,我执行以下操作: NSString *IDString = @"SELECT ID FROM Castle ORDER BY Name ASC"; NSMutable

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

按名称从Castle ORDER中选择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);
    }
    ?>
我在字符串中作为参数给出的纬度和经度分别是40.535568和16.503588 在phpMyAdmin中,如果运行sql命令:

按顺序从Castle中选择ID 经度-16.503588,2+纬度-40.535568,2

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

未处理的异常:SQL语法中有错误;检查 与右边的MySQL服务器版本相对应的手册 第1行“POWlatitude-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))
问题是StringByAddingPercentescapesusingEncode只会转义那些通常在URL中无效的字符。但是,URL中通常允许使用一些字符,例如&和+,但在URL参数中没有问题,例如&分隔参数,+转换为空格字符

因此,与StringByAddingPercentescapesusingEncode不同,您需要一种方法,该方法不仅能对URL中无效的字符进行百分比转义,还能对URL中通常具有特殊含义但在参数中有问题的字符进行百分比转义。在本例中,您希望对SQL中出现的+进行百分比转义

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

顺便说一下,您应该将参数转义到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本身。

无关,但在PHP中,您可能需要考虑使用MySQLI或PDO。看,如果你犯了POW错误,我面前没有电脑,但我在列表中没有看到该功能。我会尝试将其简化为一个基本的算术表达式。谢谢@Rob Rob,但是你知道一种将查询传递给脚本的方法吗?然后找到用php阅读的方法?@Pinturikkio我不理解你的问题。最好的解决方案是根本不传递查询,而是传递参数,例如lat和long,然后让PHP脚本自己构建SQL。
- (NSString *)percentEscapeURLParameter:(NSString *)string
{ 
    return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                     (CFStringRef)string,
                                                                     NULL,
                                                                     (CFStringRef)@":/?@!$&'()*+,;=",
                                                                     kCFStringEncodingUTF8));
}
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]];