I am facing a problem with fill (text field) with result which requested from MySql via a PHP file. I did change the PHP file to a different ways but I still have the same problem.
Her is my PHP file:
<?php
$host="localhost"; // Host name
$username="UserName"; // Mysql username
$password="PassWord"; // Mysql password
$db_name="DataBase"; // Database name
$tbl_name="Table"; // Table name
// Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
mysql_set_charset('utf8');
// To protect MySQL injection (more detail about MySQL injection)
$userName = $_REQUEST['userName'];
$userName = stripslashes($userName);
$userName = mysql_real_escape_string($userName);
$userName = html_entity_decode($_REQUEST['userName'], ENT_QUOTES, "UTF-8");
$sql="SELECT * FROM $tbl_name WHERE userName = '$userName'";
mysql_query("SET NAMES 'utf8'"); //5
$result = mysql_query($sql);
// Mysql_num_row is counting table row
$count = mysql_num_rows($result);
$count = 1;
$items;
while($row = mysql_fetch_array($result)) {
$item['userName'] = $row['userName'];
$item['emailAddress'] = $row['emailAddress'];
$items[$count] = $item;
}
//echo json_encode($items);
echo json_encode($items, JSON_UNESCAPED_UNICODE);
?>
Her is the Objective-c code (in Xcode):
- (id)makeURLRequestWithString:(NSString *)url {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:10];
NSURLResponse *response;
NSError *error;
// Make synchronous request
NSData *urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if (urlData) {
NSDictionary *dict = [NSJSONSerialization
JSONObjectWithData:urlData
options:kNilOptions
error:&error];
return dict;
} else return error;
}
Her is the code when I press the button:
- (IBAction)callJson:(id)sender {
dispatch_queue_t jsonParsingQueue = dispatch_queue_create("jsonParsingQueue", NULL);
dispatch_async(jsonParsingQueue, ^{ //Do request on another queue to prevent it from blocking UI
id result = [self makeURLRequestWithString:#"http:/MyWebSite.com/PHPFile.php?userName=123"];
NSLog(#"%#", result);
// Her where I need to fill my text with info from the above url
// self.emailAddress.text = ...............What to do her?
});
}
Her is the result from Xcode:
{
1 = {
emailAddress = "123#hotmail.com";
userName = "123";
};
}
The request shows the data, but I don't no how to fill the text with it.
I hope my question is clear.
Thanks
You can parse the results into an NSDictionary/NSArray with NSJSONSerialization. If your result is a data object, you could call
NSError *err;
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:data options:0 error:&err];
NSString *email = [[results objectForKey:#"1"] objectForKey:#"emailAddress"];
Then to stick it in the textbox you would just use the normal code
textbox.text = email;
EDIT:
Ok, I see now you have already thrown in the Parsing JSON in the above method. So when you are calling self.emailAddress.text You are still in a background thread with your dispatch_async() call. So in order to make it actually update the text box you would do the following right after you get id result =...
dispatch_async(dispatch_get_main_queue(), $^{
self.emailAddress.text = [[result objectForKey:#"1"] objectForKey:#"emailAddress"];
});
Another tip, it's a little weird that your JSON data starts at index 1, if it is going to be an ordered list (eg. 1, 2, 3, 4..) you should format it like an array. I think I see the problem in your PHP, it should look more like this (assuming I understand what you are trying to do):
...
while($row = mysql_fetch_array($result)) {
var $tmp = [];
$tmp['userName'] = $row['userName'];
$tmp['emailAddress'] = $row['emailAddress'];
$items[] = $tmp;
}
...
That will output an array of Items from the database with dictionaries containing the emails and usernames like so
[
{'email1', 'user1'},
{'email2', 'user2'}
]
But if you do it that way, you'd have to change your code above in the makeUrlrequestwithstring method to return an array like this:
if (urlData) {
NSArray *arr = [NSJSONSerialization
JSONObjectWithData:urlData
options:kNilOptions
error:&error];
return arr;
} else return error;
Then your output code would look like this (assuming you wanted the first item in the query result)
dispatch_async(dispatch_get_main_queue(), $^{
self.emailAddress.text = [result[0] objectForKey:#"emailAddress"];
});
Related
I have had quite the night trying to solve problems after "Upgrading" to OS X Yosemite 10.6.6. After re-installing MySQL / phpMyAdmin / Apache / php5 I am still having problems with code that worked before the upgrade. The following function sends a URL request to a locally hosted php file to obtain data from a MySQL data base in a JSON parable format:
-(NSArray*) GetJSONArrayForURL:(NSString*)url
{
// Download the json file
NSURL *jsonFileUrl = [NSURL URLWithString:url];
// Create the request
//NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
NSURLRequest* request = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
NSURLResponse* response = nil;
NSData *rawdata = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSMutableData *downloaded = [[NSMutableData alloc] init];
[downloaded appendData:rawdata];
// Parse the JSON that came in
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:downloaded options:NSJSONReadingAllowFragments error:&error];
return jsonArray;
}
However, the raw data returned is the source code of the PHP file it is requesting:
<?php
$serverName = "localhost";
$databaseName = "GUESTLISTER";
$userName = $_GET['username'];
$password = $_GET['password'];
$POST = "POST";
$GET = "GET";
// Create connection
$con=mysqli_connect($serverName,$userName,$password,$databaseName);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// This SQL statement selects ALL from the table 'Locations'
//$sql = "SELECT * FROM users";
$sql = $_GET['query'];
$action = $_GET['action'];
// Check if there are results
if ($result = mysqli_query($con, $sql))
{
$id = mysqli_insert_id($con);
if($action == $GET)
{
// If so, then create a results array and a temporary one
// to hold the data
$resultArray = array();
$tempArray = array();
// Loop through each row in the result set
while($row = $result->fetch_object())
{
// Add each row into our results array
$tempArray = $row;
array_push($resultArray, $tempArray);
}
// Finally, encode the array to JSON and output the results
echo json_encode($resultArray);
}
else if ($action == $POST)
{
echo $id;
}
}
// Close connections
mysqli_close($con);
?>
The request which is:
http://localhost/webservice.php?&username=admin&password=guestlister123&query=SELECT%20*%20FROM%20users&action=GET
Runs fine when pinged from a web browser, but for some bizarre reason the source code is returned as data when requested from Xcode.
Please advise,
Ryan
Usually when the same source code is returned instead of its output, it points to the issue that Php is not getting parsed as Php. That means there is an issue with the setup for your webserver - Apache since its unable to process Php. There can be many different reasons for this, a few of them can be
Apache is off and may need to be turned on, which since outside the xcode it works then that may not be the case
Apache configuration for Php is not set up correctly
The website is not in the folder where Apache expects it to be. htdocs is usually the default where Apache looks for php scripts depending on the php.ini configuration. A quickest way is to run the phpinfo(); in a php file between the starting and ending php tags to determine if all is well with your setup.
phpinfo();
If its set up correctly you would see an output page with all the information about your php and apache setup else it will just give you back the phpinfo() line as output. Finally it could just be that Xcode is not working properly with your Apache setup thus it can be beneficial to directly run scripts through the browser instead of within Xcode which I have never tried.
I'm having an issue sending data to my online database. Nothing seems to post when I check the database. I performed an NSLog on the received response, and it's blank.
Here is the .php:
<?php
$db_host="someurl.com";
$db_username="some_user";
$db_pass="some_passwd";
$db_name="some_db";
$conn = mysql_connect($db_host, $db_username, $db_pass) or die ("Could not connect to
MySQL");
mysql_select_db("$db_name") or die ("No database");
// array for JSON response
$json = $_SERVER['HTTP_JSON'];
$data = json_decode($json);
$some1_id = $data->some1_id;
$imei = $data->imei;
//does the imei exist?
$result = mysql_query("SELECT * FROM usr_go WHERE imei = '".$imei."'");
if (mysql_num_rows($result) == 0){
if(isset($some1_id))
$result = mysql_query("INSERT INTO usr_go(some1_id, imei) VALUES('".$some1_id."','".$imei."')");
}
else{
if(isset($some1_id))
$result = mysql_query("UPDATE usr_go SET some1_id = '".$some1_id."' WHERE imei = '". $imei ." AND some1_id IS NULL ");
}
mysql_close($conn);
header('Content-type: application/json');
$response = $result;
echo json_encode($response);
?>
However, if I hard-code the $response to be some string value, and NSLog the received response, it receives the appropriate string value.
Here is my code:
NSDictionary *dict = #{#"some1_id" : [NSNumber numberWithInt:self.cellIndex]};
NSError *error = nil;
NSData *json = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
if (json)
{
NSURL *url = [NSURL URLWithString:#"someurl.com"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:#"POST"];
[req setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[req setHTTPBody:json];
NSURLResponse *res = nil;
NSData *ret = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&error];
NSString *resString = [[NSString alloc] initWithData:ret encoding:NSUTF8StringEncoding];
NSLog(#"response String: %#",resString);
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"JSON Output: %#", jsonString);
}
else
{
NSLog(#"Unable to serialize the data %#: %#", dictionary, error);
}
Is it the fact that it's not possible to insert the IMEI, which is why it's not posting, or some other issue?
Thanks for your assistance.
A couple of observations:
You should use msqli interface rather than the deprecated mysql interface.
You should never take input and just use it in SQL statement. Either use mysqli_real_escape_string or bind values (as shown below). This is critical to ensure you aren't susceptible to SQL injection attacks. It also protects you against innocent errors that can arise if the inserted value just happens to contain a reserved character.
Rather than trying to just json_encode the result of mysqli_query result, you should build a more meaningful associative array. For example, you might check the result of the mysqli call and return one JSON if it was successful, and another on failure. I might suggest having the failure rendition return the error message.
You should test your PHP either in a web browser, or test it from a device using something like Charles. Make sure you're getting back the JSON you expected before you go too far with your client code. Bottom line, see if you can test the client code and the server code in isolation of each other (or keeping it as simple as possible at first).
I'm not familiar with this $_SERVER['HTTP_JSON']; construct. If that works for you, great, but it doesn't work on my server. I've historically done fopen of php://input as illustrated below.
For example, this is a different database/table, but it might illustrate the idea of what the PHP code might look like:
// read JSON input
$handle = fopen("php://input", "rb");
$raw_post_data = '';
while (!feof($handle)) {
$raw_post_data .= fread($handle, 8192);
}
fclose($handle);
$request_data = json_decode($raw_post_data, true);
// prepare header for reply
header("Content-Type: application/json");
// open database
$mysqli = new mysqli($host, $userid, $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 locations (message, device, longitude, latitude) VALUES (?, ?, ?, ?)";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ssdd", $request_data["message"], $request_data["device"], $request_data["latitude"], $request_data["longitude"]);
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);
Obviously, change this for your tables, but it illustrates some of the above concepts. I would generally add more error checking (e.g. the Content-Type of the request, test to make sure variables were set before I tried to use them, etc.), but you probably get the idea.
On the client side, there are also a few more minor observations:
The most serious problem is the use of sendSynchronousRequest. Use sendAsynchronousRequest instead (or any of a myriad of other, asynchronous techniques). Never issue synchronous requests from the main thread.
When parsing the response, resString will contain the raw JSON. I don't know what the jsonData variable you reference when building jsonString, but that doesn't look right.
If you want to parse the response, it would be:
NSError *parseError;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
By the way, the above assumes you return a JSON dictionary in your response, like I do in my example, rather than what your original JSON did.
I am a beginner to iOS. I have a simple web service that retrieves data from a table and sends out the results in JSON. I am trying to communicate with that web service from iOS to receive the JSON response but facing issues. This is the error i receive:
Request Failed with Error: Error Domain=AFNetworkingErrorDomain Code=-1016 "Expected content type {(
"text/json",
"application/json",
"text/javascript"
)}, got text/html" UserInfo=0x7598e70
Here are my code snippets:
PHP Web Service:
$stmt = "SELECT STORE_TYPE, STORE_NAME FROM STORE WHERE STORE_ZIP = $zip";
$result = mysqli_query($this->databaseconnection, $stmt);
$storelist = array();
$store = array();
$jsondata;
while ($row = mysqli_fetch_assoc($result)) {
$store['STORE_TYPE'] = $row['STORE_TYPE'];
$store['STORE_NAME'] = $row['STORE_NAME'];
array_push($storelist,$store);
}
$jsondata = json_encode($storelist);
echo $jsondata;
I am getting the following result when i execute my php form the browser:
[{"STORE_TYPE":"GROCERY","STORE_NAME":"Walmart"},{"STORE_TYPE":"BAKERY","STORE_NAME":"Lanes Bakery"},{"STORE_TYPE":"GROCERY","STORE_NAME":"Copps"}]
iOS Code Snippet to communicate with the Web Service:
NSURL *url = [NSURL URLWithString:#"http://localhost/~Sandeep/store/store.php?rquest=getstores&zip=53715"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#"%#", JSON);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
I looked at a lot of tutorials and they all say that performing a 'json_encode' on an array in php encodes the data in JSON format and 'echo' of that is the way to go send the encoded JSON as a response. For some reason my iOS is not seeing that as JSON. I am not sure what I am missing/doing wrong here.
I really appreciate your inputs on this.
Thanks!
You need to set the correct content type(use header), the error lists the acceptable types though you should use application/json
$stmt = "SELECT STORE_TYPE, STORE_NAME FROM STORE WHERE STORE_ZIP = $zip";
$result = mysqli_query($this->databaseconnection, $stmt);
$storelist = array();
$store = array();
$jsondata;
while ($row = mysqli_fetch_assoc($result)) {
$store['STORE_TYPE'] = $row['STORE_TYPE'];
$store['STORE_NAME'] = $row['STORE_NAME'];
array_push($storelist,$store);
}
$jsondata = json_encode($storelist);
header('Content-Type: application/json');
echo $jsondata;
I'am developing an iPhone application to display data from php. Data are obtained from a Mysql database then encoded to JSON format in php file:
include_once 'connectionIncl.php';
if(function_exists($_GET['method'])){
$_GET['method']();
}
function getSQLIntoJSONFormat()
{
$arr;
$sql = mysql_query("SELECT * FROM pecivo");
while($pecivo = mysql_fetch_assoc($sql)){
$arr[] = $pecivo['typ'];
}
$arr= json_encode($arr);
echo $_GET['jsoncallback'].'('.$arr.')';
}
// --- http://127.0.0.1:8887/TeplyRohlik/pecivo.php?method=getSQLIntoJSONFormat&jsoncallback=?
when i run this from browser, it returns correct data :
(["sejra","knir","baba","vousy","sporitelna25"])
Also, on iOS a have this code:
NSString * urlString = [NSString stringWithFormat:#"http://192.168.0.10:8887/TeplyRohlik/pecivo.php?method=getSQLIntoJSONFormat&jsoncallback=?"];
NSURL * url = [NSURL URLWithString:urlString];
NSData * data = [NSData dataWithContentsOfURL:url];
NSError * error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%#",json);
And result is .... (null).
I have no idea how to get this working...
It looks like your PHP method is spitting out JSONP. What you probably want to do is change that to:
function getSQLIntoJSONFormat()
{
$arr;
$sql = mysql_query("SELECT * FROM pecivo");
while($pecivo = mysql_fetch_assoc($sql)){
$arr[] = $pecivo['typ'];
}
$arr= json_encode($arr);
echo $arr;
}
You are seeing the output be wrapped in parentheses as it's expecting a GET parameter in the request called jsoncallback which would make the output look something like this:
javascriptFunction(["a","b","b"])
That's not what you want on your iOS device. You want just the raw JSON string of the array, no wrapping in a callback function call.
I followed Ray Wenderlich's tutorial on creating a web service / hooking it up to iOS but his example the returned results only have one possible row returned in the query. I'd like to return all possible results in a JSON format but I am confused how to store them as the correct key.
Here's what I have for the PHP:
$stmt = $this->db->prepare('SELECT userID, lat, lng FROM Connections WHERE airline=? AND flight_number=? ');
$stmt->bind_param("si", $airline, $flight_number);
$stmt->execute();
$stmt->bind_result($otherUser, $otherLat, $otherLng);
while ($stmt->fetch()) {
break;
}
$stmt->close();
if ($otherUser) {
//sendResponse(403, 'Code already used');
//return false;
$myLatLng = "$lat,$long";
$otherLatLng="$otherLat,$otherLng";
$results = getDistanceBetween($myLatLng,$otherLatLng);
$miles = $results[0];
$minutes = $results[1];
$result = array(
"other_user" => $otherUser,
"distance" => $miles,
"duration" => $minutes,
);
sendResponse(200, json_encode($result));
return true;
}
On the Obj-C side of things I get these values using this code:
if (request.responseStatusCode == 200) {
NSString *responseString = [request responseString];
NSDictionary *responseDict = [responseString JSONValue];
NSString *otherUser = [responseDict objectForKey:#"other_user"];
NSString *otherDistance = [responseDict objectForKey:#"distance"];
NSString *otherDuration = [responseDict objectForKey:#"duration"];
Can someone please help me out?
In your PHP code you want to create a nested array and then use json_encode(). Here is a previous question with more detail about the PHP side of your problem: How to create an array for JSON using PHP?
On the iOS side, since your webservice will return a JSON response representing multiple items, calling JSONValue on the response string will return an NSArray object instead of an NSDictionary. You can then iterate over the items in the array (which will themselves be NSDictionary items) and pull out the values you need.
NSString *responseString = [request responseString];
NSArray *responseArray = [responseString JSONValue];
for (NSDictionary* item in responseArray) {
NSString *otherUser = [item objectForKey:#"other_user"];
NSString *otherDistance = [item objectForKey:#"distance"];
NSString *otherDuration = [item objectForKey:#"duration"];
}