I am using curl to call an API POST and pass 15 post fields, one being an actual wbsite URL. For example
https://www.test.com?URL=https://www.myurl.com;&Name=John
Using urlencode converts the characters in the URL post field and the API receiving the POST call does not recognize it as an actual URL. Is there any way to keep the URL string as is when positing?
If you are using GET query arguments, you need to urlencode the value, then decode it on the backend:
https://www.test.com?URL=https%3A%2F%2Fwww.myurl.com
And then:
urldecode($_GET['url'])
For POST, the same is true for application/x-www-form-urlencoded, but doesn't matter for application/json.
Also, just a heads up, you have an extra ; in your URL, which would make it invalid if you included it.
Edit:
I will additionally add, that in general, it's good practice to always urldecode values received from query arugments/form data. The general thought here being that, while you may not want urlencoded data, that's the way the web is built - You should build your code in a way that it's up to the client. This is considered an important step in data sanitation, and should always happen before validation.
You can use php builtin method to decode the url encoded data.
$actualUrl = urldecode ($_GET ['url']);
Related
I am working on a PayPal payment system, I wanna send 2 values in the custom field. Therefor I used the urlencode(json_encode()) functionality. An example of how it looks without urlencoding.
$customData = array();
$customData['invoiceID'] = $invoiceID;
$customData['username'] = urlencode($_GET['username']);
$p->add_field('custom', urlencode(json_encode($customData)));
Output is:
%7B%22invoiceID%22%3A108674%2C%22username%22%3A%22Just%2Btesting%22%7D
Desired output when urldecoding and jsondecoding:
{"invoiceID":108674,"username":"Just testing"}
But it's giving me this after urldecoding and jsondecoding:
{"invoiceID":108674,"username":"Just+testing"}
The workaround for this issue is to urldecode the username itself as well once again. But why do I have to double urldecode just to get the value that I urlencoded with just one time running this function?
Seems like you are applying two times urlencode() to data so you need to apply two times urldecode() or remove one of them.
I think the "custom" field is used to identify your request on the other end, correct? So, that field is for your use and not for paypal. I think it's a good idea to encode it. But, if you want it to survive paypals back end you might want to use base64encode and base64decode.
What if I pass my searching params in uri request in json-format like this:
http://example.com/?search={"title":"Some+Title","category":12}
instead of
http://example.com/?title=Some+Title&category=12
Before decode json-request I can filter it with some functions like strip_tags(), strpslashes(), etc... But I can do the same with $_SERVER['QUERY_STRING'] with serialize()/unserialize(). Or apply string-filters to N string-params of request, not once to whole request.
Which way do you think will be better, usable and faster to process?
With json
$request = $_GET['search'];
$request = stripslaches(strip_tags($request));
$params = json_decode($request);
The characters { and } are unsafe according to RFC 1738 2.2. They must therefore be encoded before being transferred over a network.
The character : is reserved according to RFC 1738 2.2. It must therefore be encoded before being transferred over a network unless it is used for the purpose for which it was reserved.
Don't use $request = striplashes(strip_tags($request)). If $_GET['search'] does not json_decode sucessfully, treat it as faulty input; don't try to fix it.
Isn't it better to use http_build_query instead of passing JSON throw URL? HTTP_build_query is specially designed to pass data throw url params.
Applying this filter to whole param_str of URL may cause unexpected behaviour, besides fact that is actually little bit faster.
I think that you should pass every one parameter throw your filter functions.
Sending an encoded JSON string is possible, as any string (you should urlencode and urldecode it though, no stripping needed) but it's not really a good way to do it - use the standard way of passing data in request - if you have only simple data to send, just translate it into traditional GET variables (it's really easy, e.g. with http_build_query as Tomasz suggests). You may also run into difficulities with the request URI length (see What is the maximum length of a URL in different browsers?) if you pack too much data into the JSON object.
Why don't you just represent everything with JSON?
http://www.example.com/{"article":"something","page":12,"fragment":"#menu"}
Query strings are already used to represent flat lists of key-value pairs, so what problem does your JSON solution solve? You'll just be adding a new layer of complexity without any benefits.
With this Symfony page, I am passing $_GET parameters in the URI like this:
http://www.mysite.com/article?page=4&sort=1
Once in my layout, there are certain links in the page that need to have the same query string in them.
Anyways, using Symfony's url_for() command I'm making URLs like so:
$url = url_for('article/index?.http_build_query($_GET));
That way it makes a new url using the $_GET variables. For some of the links I'm changing the $_GET values ahead of time, like $_GET['sort']=0; before generating the url. That's why I'm using this method.
Anyways, when I look at the generated URL, it now looks like this:
http://www.mysite.com/article?page=4&%3Bsort=1
The &%3B is the encoded form of & which is just an & character.
So the problem is that when I check for my $_GET parameters in my controller now, there is no longer a sort parameter that is passed. It's now called &%3Bsort... It's causing all sorts of issues.
Two questions:
How do I avoid this problem? Can I decode the $_GET parameter key values in my controller or something?
Why is symfony encoding a & character in the first place? It's a perfectly acceptable URI character. Heck, even the encoded value, &%3B contains a & !!!
I believe, it is because of output escaping is ON in your application. As a result, $_GET array is wrapped inside sfOutputEscaperArrayDecorator class. You can get a raw value using this: $_GET->getRawValue().
$url = url_for('article/index?.http_build_query($_GET->getRawValue()))
Or you can decode the result query using sfOutputEscaper::unescape
$url = url_for('article/index?.sfOutputEscaper::unescape(http_build_query($_GET)));
Hope this will be useful.
Best if you use Symfony's own method for getting the request parameters. For example, in templates, use:
$sf_request->getParameter('some_param');
If you must use $_GET, maybe try:
((( $sf_data->getRaw('_GET') )))
... to get past the output escaping. Not totally sure if that'll work as is.
I am trying to parse this json data from the url but i get NULL how do i fix this issue.
$source = file_get_contents('http://partners.socialvi.be/e414f702cf3db89a2fe58066bbab369d65b6a058/activities/available.json');
$json = json_decode($source);
var_dump($json);
That's because the API returns the data in JSONP format, not pure JSON. Notice the surrounding onSVJson([]). You'll either have to strip this out, or read the API documentation and try another request format. My guess would be that leaving out the final &callback=onSVJson should do the trick.
That's because if you call the url (go to http://partners.socialvi.be/e414f702cf3db89a2fe58066bbab369d65b6a058/activities/available.json?network_user_id=3459874&max_activities=9&callback=onSVJson with your browser) the json that is returned has no values
Remove the last part of the URL (&callback=onSVJson) and it'll work.
Many APIs offer a feature called JSONP, that allows the JSON to be passed to a callback function, in order to simplify access via cross domain JavaScript. But for PHP you don't need that.
The name of the callback function is typically specified using the callback GET parameter. If you leave that out, no callback function is used - just plain JSON.
I am looking to have a list of arguments passed across in an a URL.
$url['key1']=1;
$url['key2']=2;
$url['key3']=3;
$url['key4']=4;
$url['key5']=5;
$url['key6']=6;
$url['key7']=7;
Please Note I am trying to pass this in the URL in 1 GET variable. I know this would be better done by ?key1=1&key2=2&key3=3...etc but for reasons that are too complicated to try and explain they can't be in this format.
Any suggestions how I can convert this array into something that can be passed as 1 get var in a URL string?
Thanks in advance.
You can use json_encode() or serialize()
$myUrl = 'http://www.example.com/?myKey=' . urlencode(json_encode($url));
or
$myUrl = 'http://www.example.com/?myKey=' . urlencode(serialize($url));
Using json_encode will usually give you a shorter string, but very old PHP version might not have the json_decode function available to decode it again.
The final way would be to create your own custom encoding... it could be as simple a pipe-separated values: key1|1|key2|2|key3|3
This would give you the best option for a short URL, but is the most work.
Try http_build_query:
$url['key1']=1;
$url['key2']=2;
$url['key3']=3;
$url['key4']=4;
$url['key5']=5;
$url['key6']=6;
$url['key7']=7;
echo http_build_query($url);
//echos key1=1&key2=2&key3=3&key...
What it does is converting an array into a query string using the keys and automatically takes care of url-encoding.
EDIT:
Just read your additional requirement that it should be just one variable. So nevermind this answer.
If your problem was the proper encoding though you might want to give this another try.
Hope that helps.
The recommendation to use serialize() is fine. If space is an issue, then use a combination of bzcompress() and serialize().
However, there's a security considering that hasn't been brought up, and that's that the end user (who can see and edit this url) could manipulate the data within it. You may think it's difficult, but most of the PHP-attacking worms in the wild do this to some degree or another.
If letting the user directly manipulate any of the keys or values (or replacing it with an integer, or an object, or anything else), then you should protect your script (and your users) from this attack.
A simple solution is to simply use a shared secret. It can be anything; just so long as it's unique and truly secret (perhaps you should randomly generate it at install-time). Let's say you have in your config file something like this:
define('SECRET', 'unoqetbioqtnioqrntbioqt');
Then, you can digitally sign the serialized data created with: $s=serialize($m) using $k=sha1($s.SECRET) and make the url value $k.$s
Then, before you unserialize() do this:
$v=substr($input,0,40);
$s=substr($input,40);
if ($v != sha1($s.SECRET)) { die("invalid input"); }
$m=unserialize($s);
This way, you know that $m is the same as the original value that you serialized.
If you like, you can use the following drop-in replacements:
define('SECRET','buh9tnb1094tib014'); // make sure you pick something else
function secureserialize($o) {
$s=serialize($o);
return sha1($s.SECRET).$s;
}
function secureunserialize($i) {
$v=substr($i,0,40);$s=substr($i,40);
if ($v!=sha1($s.SECRET)){die("invalid input");}
return unserialize($s);
}
You could serialize them as key-value pairs when constructing the URL, putting the resultant serialized value in a single $_GET variable (e.g. data=sfsdfasdf98sdfasdf), then unserialize the $_GET["data"] variable. You'll need to use urlencode to make sure the resultant serialized values are URL-safe. Make sure you watch out for maximum URL lengths - 2083 characters in IE.
However, unless you really can't use key-value pairs in URLs (per your question), key1=foo&key2=bar... is definitely the way to go.
If you don't mind dropping the key names, you can use
http://example.com?url[]=1&url[]=2&url[]=3
EDIT Keeping the key names:
http://example.com?values[]=1&values[]=2&values[]=3&keys[]=1&keys[]=2&keys[]=3
Then in your PHP script:
$url = array_combine($_GET['keys'], $_GET['values']);
Could you solve your problem by saving the data as a HTML cookie? That way you don't have to modify the URL at all.
If you know the values in advance, you can set them from the server side when you send the user the page with your target link on it.
If you won't know the values until the user fills out a form it can still be done using JavascriptL When the user clicks the form submit you can set multiple cookies by making multiple javascript calls like:
document.cookie = 'key1=test; expires=Mon, 7 Sept 2009 23:47:11 UTC; path=/'
The security model might give you some trouble if you are trying to pass this data from one domain to another though.