Ive been using URL-parameters to make a landingpage behind a searchform more personal. I felt relatively bulletproof validating stuff like this
$string = $_GET['city']
$res = preg_replace("/[^a-zA-Z0-9]/", "", $string);
until I tried something like ?city=# as a value and my whole page crashed and im not so sure anymore.
What is the way to go to validate without writing a whole engine or at least stop my page crashing from #?
Thanks
PHP has a lot of functionalities which help you avoid problems like this.
Whenever you create URL to be displayed in the browser it has to be urlencoded. If you are just appending the query string part to a fixed url you can build that string with http_build_query. For example:
$querystring = [
'param1' = 123,
'param2' = 'hello with a #'
];
$QS_encoded = http_build_query($querystring);
echo 'My link';
# in URL denotes another part of URL which is the hash part. This is not going to be a part of your $_GET superglobal.
If for any reason you would like to type out the URL with a query string containing # manually by hand, then you need to use the encoded version %23. e.g. http://php.net/manual-lookup.php?pattern=%23
On a side note. You shouldn't use regex for filtering data like this. PHP once again has already an extension for this: filters.
Related
I have a POST form in PHP that I'm converting to GET.
The form works and gives me the first page of results without any problems.
But how do I link to the second page? I assume I have to replicate all the GET parameters into the "Next Page" link plus the page number (which the script already handles), but how would I do that?
CLARIFICATION: How do I get all the GET variables from a form onto a link in the page?
simpliest way is too to do something like:
$get = preg_replace("/page=\d+/i", "", $_SERVER['QUERY_STRING']);
$link = "somepage.php?".$get."&page=".($_GET['page']+1);
echo "<a href='".$link."'>Next Page</a>";
That will simply take the get string, remove the page then add the page back in as +1. Please note this would be insecure as people could pass anything in the query string. A better option would be to build the the URL explicitly by checking for each expected $_GET key=>value pair, validating it, then adding it to a link variable. That way any additional bits in the query string wont be echo'd to the page.
EDIT:
Ok so heres a very quick example.
$category = (int)$_GET['cat'];
$keyword = trim($_GET['keyword']);
$keyword = filter_var($keyword, FILTER_SANITIZE_STRING);
$nextlink = "somepage.php?";
$nextlink .= http_build_query(array(
"cat" => $category,
"keyword" => $keyword,
"page" => $page+1
));
So basically you get the GET var's you want, validate them, then just use http_build_query and an associative array to build your query string for the link. The security i put in their is very basic, but typecasting numbers and limiting the amount of crud you can stick into a string is a place to start
Simplistically speaking, you would read them out of the request like this:
$link = 'mypage/?someitem=' . $_GET['someitem'] . '&page=' . ($page + 1);
Although you may not wish to trust the parameters as they may contain an HTML injection or other nasty tricks designed to attack your website.
Isn't it just URL?param1=val1¶m2=val2&...?
The problem i'm facing right now is im getting a URL, like so:
www.example.com/example.php?url=www.google.com
now the problem is, if theres a get in my url, like so:
www.example.com/example.php?url=www.google.com?id=1
it doesn't actually cause a problem yet, but if theres two GET vars in the my URL, it doesn't know where the "and" goes, the first get or the second one, and basically just chooses the first, ex:
www.example.com/example.php?url=www.google.com?id=1&username=me
is there a workaround? I could recode a lot of things to have it as one get variable, but it'll involve a lot of work and I wish i could have a solution!
thanks!
Heres my code:
$facebookapi=new facebook(array('appId'=>'*******','secret'=>'********','fileUpload'=>'false'));
$url='http://******.com/questions/view.php?id=884&username=robot';
$facebookapi->api('/me/******app:answer?question=' . urlencode($url),'POST');
You need urlencode to encode the url parameter.
$url = 'www.google.com?id=1';
echo 'www.example.com/example.php?url='.urlencode($url).'&username=me';
Edit:
After seeing your posted code, it seems that you should use the third parameter for params.
$url='http://******.com/questions/view.php?id=884&username=robot';
$facebookapi->api('/me/******app:answer', 'POST', array('question' => $url));
Well the function urlencode is perfect for this.
Once the url is encoded,
The first get variable will turn from this
www.google.com?id=1&username=me
to this
www.google.com%3Fid%3D1&6username=me
Your website will then appear as [www.example.com/example.php?url=www.google.com%3Fid%3D1%26username%3Dme]
Once PHP receives that variable you can decode it
$url = urldecode($_GET['url']);
Note: some versions of PHP do it automatically.
I think I have seen this question before but I don't think it's answered good enough yet because I can't get it to work.
The case:
I want to insert an URL into my MySQL database like so:
$url = $_POST["url"]; //$_POST["url"] = "http://example.com/?foo=1&bar=2& ...";
$sql = mysql_query("INSERT INTO table(url) values('$url')") or die ("Error: " . mysql_error());
Now, the URL is inserted into the database properly but when I look at it, it looks like this:
http://example.com/?foo=1
It's like the URL is cut right at the "&" character. I have tried: mysql_real_escape_string, htmlspecialchars, escaping by doing "\" etc. Nothing seems to work.
I have read that you might be able to do it with "SQL Plus" or something like that.
Thanks in advance.
Regards, VG
Chances are the problem here is nothing to do with the database query, and more to do with how the url is passed to the page. I suspect you'll find that the URL used to load the page is something like:
http://mydomain.com/?url=http://example.com/?foo=1&bar=2
This will result in a $_GET that looks like this:
array (
'url' => 'http://example.com/?foo=1',
'bar' => '2'
)
What you need is to call page with a URL that looks more like this:
http://mydomain.com/?url=http://example.com/?foo=1%26bar=2
Note that the & has been encoded to %26. Now $_GET will look like this:
array (
'url' => 'http://example.com/?foo=1&bar=2'
)
...and the query will work as expected.
EDIT I've just noticed you're using $_POST, but the same rules apply to the body of the request and I still think this is your problem. If you are, as I suspect, using Javascript/AJAX to call the page, you need to pass the URL string through encodeURIComponent().
It is likely the querystring is not being passed. It looks like you are receiving it from a FORM post. Remember that form posts that use a method of GET append a querystring to pass all of the form variables, so any querystring in the action is typically ignored.
So, the first thing to do is echo the URL before you try to INSERT it to make sure you are getting the data you think you are.
If there are variables you need to pass with the URL, use hidden inputs for that, and a method of GET on the form tag, and they will get magically appended as querystring parameters.
Right !! The problem here is nothing to do with the database query has DaveRandom said.
Just use the javascript function "encodeURIComponent()".
Depending on what you want to do with the stored value, you also urlencode() the string: http://php.net/manual/de/function.urlencode.php
Cheers,
Max
P.S.: SQL*Plus is for Oracle Databases.
maybe escape the url with urlencode then you can decode it if you want to pull it out of the db
I think I have the need to take a uri which has been decoded in PHP, and re-encode it.
Here is the situation:
JavaScript passes encoded uri as query string parameter to php script.
PHP script embeds uri as a hidden input value in an html document, responds with the document to a user agent.
JavaScript reads embedded uri and sets location of current document based on value of hidden input.
On Step 2, I am finding that the Uri is fully decoded after reading it in via $_GET. So when I embed the uri in the hidden input, it becomes un-encoded. So I would like to run a PHP script which re-encodes the Uri properly ex:
http://my.example.com/dog walk?is=very great
==>
http://my.example.com/dog%20walk?is=very%20great
Is there a pre-built php function for this or should I just write my own?
PLEASE NOTE: urlencode and urldecode are not the answer to get the desired input/output I have in the example above.
Thanks,
Macy
Are you looking for : http://fr.php.net/manual/en/function.urlencode.php ?
I don't know if will help you, but PHP have 3 useful functions:
$url = parse_url('put the url here');
parse_str( $url['query'], $query ); // generating an array by reference (yes, kinda weird)
echo $query; //in this line, you can encode or decode.
or, if you want to mount a query, you can use http_build_query(); that accepts values from an array, like:
$url = 'http://my.example.com/dog walk?';
$array = Array (
'is' => 'very_great',
);
$url_created = $url . http_build_query($array);
urldecode:
http://www.php.net/manual/en/function.urldecode.php
I know that I should encodeURI any url passed to anything else, because I read this:
http://www.digitalbart.com/jquery-and-urlencode/
I want to share the current time of the current track I am listening to.
So I installed the excellent yoururls shortener.
And I have a bit of code that puts all the bits together, and makes the following:
track=2&time=967
As I don't want everyone seeing my private key, I have a little php file which takes the input, and appends the following, so it looks like this:
http://myshorten.example/yourls-api.php?signature=x&action=shorturl&format=simple&url=http://urltoshorten?track=2&time=967
So in the main page, I call the jquery of $("div.shorturl").load(loadall);
It then does a little bit of CURL and then shortener returns a nice short URL.
Like this:
$myurl='http://myshorten.example/yourls-api.php?signature=x&action=shorturl&format=simple&url=' . $theurl;
$ch = curl_init($myurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
echo 'cURL failed';
exit;
}
echo $data;
All perfect.
Except... the URL which is shortened is always in the form of http://urltoshorten?track=2 - anything after the ampersand is shortened.
I have tried wrapping the whole URL in php's URLencode, I've wrapped the track=2&time=967 in both encodeURI and encodeURIComponent, I've evem tried wrapping the whole thing in one or both.
And still, the & breaks it, even though I can see the submitted url looks like track=1%26time%3D5 at the end.
If I paste this or even the "plain" version with the unencoded url either into the yoururls interface, or submit it to the yoururls via the api as a normal URL pasted into the location bar of the browser, again it works perfectly.
So it's not yoururls at fault, it seems like the url is being encoded properly, the only thing I can think of is CURL possibly?
Now at this point you might be thinking "why not replace the & with a * and then convert it back again?".
OK, so when the url is expanded, I get the values from
var track = $.getUrlVar('track');
var time = $.getUrlVar('time');
so I COULD lose the time var, then do a bit of finding on where the * is in track and then assume the rest of anything after * is the time, but it's a bit ugly, and more to the point, it's not really the correct way to do things.
If anyone could help me, it would be appreciated.
I have tried wrapping the whole URL in php's URLencode
That is indeed what you have to do (assuming by ‘URL’ you mean inner URL being passed as a component of the outer URL). Any time you put a value in a URL component, you need to URL-encode, whether the value you're setting is a URL or not.
$myurl='http://...?...&url='.rawurlencode($theurl);
(urlencode() is OK for query parameters like this, but rawurlencode() is also OK for path parts, so unless you really need spaces to look slightly prettier [+ vs %20], I'd go for rawurlencode() by default.)
This will give you a final URL like:
http://myshorten.example/yourls-api.php?signature=x&action=shorturl&format=simple&url=http%3A%2F%2Furltoshorten%3Ftrack%3D2%26time%3D967
Which you should be able to verify works. If it doesn't, there is something wrong with yourls-api.php.
I have tried wrapping the whole URL in php's URLencode, I've wrapped the track=2&time=967 in both encodeURI and encodeURIComponent, I've evem tried wrapping the whole thing in one or both. And still, the & breaks it, even though I can see the submitted url looks like track=1%26time%3D5 at the end.
Maybe an explanation of how HTTP variables work will help you out.
If I'm getting a page with the following variables and values:
var1 = Bruce Oxford
var2 = Brandy&Wine
var3 = ➋➌➔ (unicode chars)
We uri-encode the var name and the value of the var, ie:
var1 = Bruce+Oxford
var2 = Brandy%26Wine
var3 = %E2%9E%8B%E2%9E%8C%E2%9E%94
What we are not doing is encoding the delimiting charecters, so what the request data will look like for the above is:
?var1=Bruce+Oxford&var2=Brandy%26Wine&var3=%E2%9E%8B%E2%9E%8C%E2%9E%94
Rather than:
%3Fvar1%3DBruce+Oxford%26var2%3DBrandy%26Wine%26var3%3D%E2%9E%8B%E2%9E%8C%E2%9E%94
Which is of course just gibberish.