0

I am using a PHP file to return a JSON array to an iOS app. The table that is being consulted has only 32 records. If I execute the iOS app, it receives an empty array when calling the PHP file. If I execute the PHP on the web browser, the result is also an empty array. If I run the query that is included in the PHP file directly in PHPMyAdmin, the query shows the correct result.

This is the PHP file:

<?php
$host= 'localhost';
$db = 'app_mujer';
$uid = 'XXXXXXXXXXXX';//
$pwd = 'XXXXXXXXXXXX';
$link = mysql_connect($host,$uid,$pwd) or die("No se puede conectar ");
mysql_query("SET NAMES 'utf8'");
mysql_select_db($db) or die ("No se puede seleccionar la bbdd");
$id= urldecode($_GET['id']);
$arr = array();
$rs = mysql_query("SELECT * FROM tbcoordenadas where titulo='$id'");
while ($obj = mysql_fetch_assoc($rs)){  
$arr[] = $obj['procedencia'];
}
echo json_encode($arr);
?>

I have detected that the problem occurs only when the URL parameter get by $id contains a '& character in it.

If I run the following query directly at PHPMyAdmin, the result is the expected record:

SELECT * 
FROM  `tbcoordenadas` 
WHERE  `titulo` =  'D & R'

Any help is welcome.

mvasco
  • 4,965
  • 7
  • 59
  • 120
  • Well, you should not transfer that kind of data via GET. Not because it's not possible, but because of problems like yours. Why don't you transmit it via POST, then you will not need any decoding/encoding functions, which can break the string – Royal Bg Mar 22 '14 at 15:30
  • Your code is vulnerable to SQL injections. You should read on [how to prevent them in PHP](http://stackoverflow.com/q/60174/53114). – Gumbo Mar 22 '14 at 15:30
  • @RoyalBg - The purpose of HTTP methods surpass the convenience that may be possible. Properly handling URL content with appropriate GET requests is preferred if it fits the purpose of the request. – Jared Farrish Mar 22 '14 at 15:33
  • Thank you @RoyalBg, I am not a PHP expert, and the code is taken from a tutorial and normally it is working for me. But in this case I have found the problem about the '&' character. You mean changing POST for GET will solved the issue? So easy? – mvasco Mar 22 '14 at 15:33
  • @mvasco, please supply the URL you are using. – Jared Farrish Mar 22 '14 at 15:34
  • @JaredFarrish, this is the URL http://mujercanariasigloxxi.appgestion.eu/app_php_files/comprobartipo.php?id=D & R, the browser changes the part after = for D%20&%20R – mvasco Mar 22 '14 at 15:36
  • @JaredFarrish GET urls rewritten in the way of MVC are good, yes. Passing ID like real ID also, but passing a string that may break - not. So, if one want to compare a title i.e. `some && string with ^& characters and a lot of ++ spaces and other things, that the %20 url parser will evaluate` should be done in POST – Royal Bg Mar 22 '14 at 15:36
  • The problem you're having is that you have to url encode the id parameter before composing the URL. urlencode('D & R') -> 'D%20%26%20R' – Xavier Rubio Jansana Mar 22 '14 at 15:36
  • @mvasco - That's because you're not encoding the `&` in the query and it is being interpreted as a GET parameter delimeter; see Emilio's answer. – Jared Farrish Mar 22 '14 at 15:38
  • i have already told you to echo your `$id` in your previous post.But you didn't. if you do echo $id then you might have knew it what the value it has – ɹɐqʞɐ zoɹǝɟ Mar 22 '14 at 15:42
  • Also, `print_r()` is your friend to debug this kind of stuff in quick and dirty way ;) – Xavier Rubio Jansana Mar 22 '14 at 15:46
  • @ferozakbar , sorry for that, I didn't seen your comment on the last question. The echo for $id is D+ but D & R is the string written on the browser. – mvasco Mar 22 '14 at 16:14

1 Answers1

3

I have detected that the problem occurs only when the URL parameter get by $id contains a '& character in it.

That's where the problem is.

http://www.example.com/example.php?id=1&2&3

For this request, the value of $_GET['id'] will be 1 (and you would expect it to be 1&2&3). This is because the & symbol is used to add another URL parameter.

Since the value includes &, you need to urlencode() the ID before sending it to the PHP script. As pointed out by @Jared Farrish, this should be done on every GET value (to prevent problems such as this one).

Emilio
  • 326
  • 1
  • 9
  • This is the reason, according to the OP's reason. – Jared Farrish Mar 22 '14 at 15:38
  • POST has also the same problem, unless you use multipart encoding. But for regular application/x-www-form-urlencoded, the problem is exaclty the same. Solution is URL encoding your parameters, or encapsulate it in a different encoding (JSON, XML...). In this case this may be overkill, so just URL encode. – Xavier Rubio Jansana Mar 22 '14 at 15:39
  • @XavierRubioJansana the POST will not go through the url, which will not inseparate the params – Royal Bg Mar 22 '14 at 15:40
  • @RoyalBg You're wrong. See http://en.wikipedia.org/wiki/POST_(HTTP) section "Use for submitting web forms". ;) – Xavier Rubio Jansana Mar 22 '14 at 15:42
  • 1
    @RoyalBg - It's possible to submit POST data as url-encoded, which if handled exactly the same way, will end with the same result. POST is not a solution here, properly URL encoding the GET parameters is. – Jared Farrish Mar 22 '14 at 15:42
  • @emilio, note that all parameters sent as GET should be url encoded, not just ones that include an ampersand. It's a matter of practice to do so. – Jared Farrish Mar 22 '14 at 15:44
  • Why does a value sent via POST should be url-encoded, since it's not part of the URL? – Royal Bg Mar 22 '14 at 15:47
  • @JaredFarrish you are right, I was just trying to describe the problem's specifics - I'll change the answer to display that. Thanks. – Emilio Mar 22 '14 at 15:47
  • @RoyalBg - You're missing the point. The problem isn't the *method*, it's the way the method is being *used* (incorrectly) for the result expected. You're relying on a browser's side effect of auto-url-encoding content (which is [default behavior](http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1)), when in reality the OP is probably constructing a URL inline in a script and appending it to a URL. It is a matter of *practice*, not a matter of *method*. – Jared Farrish Mar 22 '14 at 15:52
  • @Emilio, I have changed my code for $id= urlencode($_GET['id']); and the result is the same, an empty array. – mvasco Mar 22 '14 at 16:10
  • The urlencode() must be done where the request is being made (another server, app...) – Emilio Mar 22 '14 at 16:11
  • Thank you @Emilio, I will try it at my iOS code, but how could I check it directly running the PHP at the web browser? – mvasco Mar 22 '14 at 16:21
  • If you are making the requests manually, you can urlencode() the **value** of the ID parameter here http://meyerweb.com/eric/tools/dencoder/ and use it in your request. In my example, I'd urlencode "1&2&3" and would make this request: http://www.example.com/example.php?id=1%262%263 – Emilio Mar 22 '14 at 16:26
  • @Emilio, then I can leave my PHP file as it was and try to change the JSON request in my iOS app? – mvasco Mar 22 '14 at 16:29
  • If you have no other problems (and the test you did worked), yes. However the script, as it is, has a big security risk - you're sending the data from the request to the DB directly, without sanitizing user input. And even though the URL may not be published to users, malicious users can find out you're calling this URL. – Emilio Mar 22 '14 at 16:37
  • 1
    @mvasco - You need to `urlencode()` (or whatever is available on the platform) the URL parameters at the source of the request (browser, mobile app, etc.) so that the URL `id` argument looks like this: http://codepad.viper-7.com/DZYoME Note the encoded `&` between the `D%20` and `%20R`. – Jared Farrish Mar 22 '14 at 17:23