PHP和MySQL的问题

我在Xcode中工作,并有一个iOS应用程序,您input的信息和应用程序通过PHP文件连接到数据库。 上传时,没有问题,名称或电子邮件地址。 但由于某种原因,当通过UITextView上传大量文本时,就会出现问题。 当没有标点符号时,它会成功。 但是,当有一段时间,或一个问号,它不会上传到服务器,它只是失败。 但是在电子邮件领域,当涉及到期限或甚至是@符号时,没有任何问题。 我不熟悉PHP或MySQL后端的东西,所以我很困惑。 这里是php文件的代码:

 if (isset ($_GET["firstName"]) && isset($_GET["lastName"]) && isset($_GET["emailAddress"]) && isset($_GET["deviceType"]) && isset($_GET["problemTextField"]) && isset($_GET["iosVersion"])){ $firstName = $_GET["firstName"]; $lastName = $_GET["lastName"]; $emailAddress = $_GET["emailAddress"]; $deviceType = $_GET["deviceType"]; $problemTextField = $_GET["problemTextField"]; $iosVersion = $_GET["iosVersion"]; } else { $firstName = "User first name"; $lastName = "User last name"; $emailAddress = "User email address"; $deviceType = "User device type"; $problemTextField = "User problem text field"; $iosVersion = "User ios version"; } $con = mysql_connect($DB_HostName,$DB_User,$DB_Pass) or die(mysql_error()); mysql_select_db($DB_Name,$con) or die(mysql_error()); $sql = "insert into $DB_Table (firstName, lastName, emailAddress, deviceType, problemTextField, iosVersion, Status, Second_Status) values('$firstName','$lastName', '$emailAddress','$deviceType','$problemTextField','$iosVersion', 'Unanswered', 'Answered')"; $res = mysql_query($sql,$con) or die(mysql_error()); mysql_close($con); if ($res) { echo "success"; }else{ echo "failed"; } 

就像我说的,我不熟悉PHP,所以请把我的PHP文件的语法分开。

编辑:经过一整天的debugging,我已经意识到,如果我从字之间带走空格,一切都很好。 是否有一个原因? 我不想把所有东西都加在一起,我知道这是不正确的。

这是我的Xcode代码:

 NSString *strURL = [NSString stringWithFormat:@"http://www.website.com/phpFile.php?firstName=%@&lastName=%@&emailAddress=%@&deviceType=%@&problemTextField=%@&iosVersion=%@", firstName.text, lastName.text, emailAddress.text, deviceType.text, self.problemTextBox.text, iosVersion.text]; // to execute php code NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]]; // to receive the returend value NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];` 

几点意见:

  1. 你说:

    但是,当有一段时间,或一个问号,它不会上传到服务器,它只是失败。

    你的问题假设问题在于PHP代码,但是听起来好像你在创build请求时可能无法正确地转义参数。 值得注意的是,许多人错误地使用stringByAddingPercentEscapesUsingEncoding (这将百分比转义一些字符,但不是别人)。 值得注意的是,在URL中有“合法”字符,但在POST / GET参数中无效,所以你需要指定那些也应该被百分比转义的“合法”字符(例如?&+等等)在一个参数内。

    简而言之,你真的想要使用CFURLCreateStringByAddingPercentEscapes ,它允许你指定应该按照RFC 3986转义的附加字符。 例如,我已经使用了下面的NSString类别。

     @implementation NSString (URLEncode) - (NSString *)stringForHTTPRequest { return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, (CFStringRef)@":/?@!$&'()*+,;=", kCFStringEncodingUTF8)); } @end 

    或者使用像AFNetworking这样的框架,它简化了创build请求的过程并为您处理。

  2. 请注意,这个PHP代码正在返回简单的string响应。 相反,我build议创buildJSON响应,这将使Objective-C代码更容易处理和解释响应(并报告/logging错误)。 例如,如果使用mysqli的程序演示:

     <?php // specify that this will return JSON header('Content-type: application/json'); // open database $con = mysqli_connect("localhost","user","password","database"); // Check connection if (mysqli_connect_errno()) { echo json_encode(array("success" => false, "message" => mysqli_connect_error(), "sqlerrno" => mysqli_connect_errno())); exit; } // get the parameters $field1 = mysqli_real_escape_string($con, $_REQUEST["field1"]); $field2 = mysqli_real_escape_string($con, $_REQUEST["field2"]); // perform the insert $sql = "INSERT INTO sometable (field1, field2) VALUES ('{$field1}', '{$field2}')"; if (!mysqli_query($con, $sql)) { $response = array("success" => false, "message" => mysqli_error($con), "sqlerrno" => mysqli_errno($con), "sqlstate" => mysqli_sqlstate($con)); } else { $response = array("success" => true); } echo json_encode($response); mysqli_close($con); ?> 

    或者,如果使用面向对象的风格:

     <?php header('Content-type: application/json'); $mysqli = new mysqli("localhost", "user", "password", "database"); // check connection if ($mysqli->connect_errno) { echo json_encode(array("success" => false, "message" => $mysqli->connect_error, "sqlerrno" => $mysqli->connect_errno)); exit(); } // perform the insert $sql = "INSERT INTO sometable (field1, field2) VALUES (?, ?)"; if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("ss", $_REQUEST["field1"], $_REQUEST["field2"]); if (!$stmt->execute()) $response = array("success" => false, "message" => $mysqli->error, "sqlerrno" => $mysqli->errno, "sqlstate" => $mysqli->sqlstate); else $response = array("success" => true); $stmt->close(); } else { $response = array("success" => false, "message" => $mysqli->error, "sqlerrno" => $mysqli->errno, "sqlstate" => $mysqli->sqlstate); } $mysqli->close(); echo json_encode($response); ?> 

    通过这种方式,Objective-C应用程序可以接收响应,parsingJSON并查看success以确定操作是否成功,如果错误消息不成功,则查看错误消息的消息。 这只是允许应用程序和服务器之间的更强大的对话。

  3. 顺便说一句,我build议你使用mysqli_real_escape_string或手动绑定参数到一个准备好的语句,以防止SQL注入攻击或SQL mysqli_real_escape_string转义string引起的意外错误。

  4. 我也build议你创build一个POST请求,而不是一个GET请求,允许更大的值。

首先,不要使用mysql_ *函数,它们将被弃用,并将很快从PHP中删除。 查看mysqli或PDO进行更换。

在与数据库交谈时,重要的是input被检查以便其不坏。
您可以使用转义函数或预先准备好的语句来执行此操作。
mysqli和pdo都准备了发言。
准备好的语句将帮助你逃脱,因为你让mysql包装器知道它应该期望什么types的数据,给它任何东西都会导致错误。

你的代码对于所谓的SQL Injections( http://en.wikipedia.org/wiki/SQL_injection )是非常开放的,这是一件坏事。
这可能是为什么你的查询在某些字符中断。
准备好的声明有助于防止这种情况!

请阅读mysqli文档,特别是mysqli准备的语句:
http://php.net/manual/en/book.mysqli.php
http://php.net/manual/en/mysqli.prepare.php

我推荐Mysqli,因为它比PDO更类似于mysql api。
但是,如果你不介意学习新东西,PDO可能会更好!

另外,正如ddelnado提到的,GET可能不是最优的,POST可能更适合。

使用mysql_real_escape_string就好

  $firstName = mysql_real_escape_string($_GET["firstName"]); 

在所有之前得到价值

谢谢

你不应该使用$ _GET superglobal。 Get方法对数据的大小有限制,因为$ _POST superglobal没有限制。 所以你的代码应该看起来像这样。

 if (isset ($_POST["firstName"]) && isset($_POST["lastName"]) && isset($_POST["emailAddress"]) && isset($_POST["deviceType"]) && isset($_POST["problemTextField"]) && isset($_POST["iosVersion"])){ $firstName = $_POST["firstName"]; $lastName = $_POST["lastName"]; $emailAddress = $_POST["emailAddress"]; $deviceType = $_POST["deviceType"]; $problemTextField = $_POST["problemTextField"]; $iosVersion = $_POST["iosVersion"]; 

我不知道你用什么表单来提交这个表单,但是这个表单的方法也需要发布。 另外,你应该总是在将你的variables插入数据库之前将其转义,以免发生sql注入。