In my webapp I have a page called display.php. The script in this page behaves in different ways depending on POST and GET array content/existence, let's say: If I call this page and GET array isset, the script'll load a record using $_GET['id'], in another case, if no GET isset but isset a ceratin POST key the script'll load a random record from the DB... and so on.
At the top of my page I've added this simple(trivial) code:
//random loading
if(!isset($_GET['id']) && !isset($_POST["MM_update"])){
##
$fresh_call=true;
$saving_call=false;
$pick_a_call=false;
##
$_SESSION['call_id']=time().$_GET['operatore'];
$call_id=$_SESSION['call_id'];
//I need to load a specified record
}else if (isset($_GET['id']) && !isset($_POST["MM_update"])) {
##
$pick_a_call=true;
$saving_call=false;
$fresh_call=false;
##
$_SESSION['call_id']=$_GET['id'];
$call_id=$_SESSION['call_id'];
//update the record
}else if (!isset($_GET['id']) && isset($_POST["MM_update"])){
##
$saving_call=true;
$pick_a_call=false;
$fresh_call=false;
##
$call_id=$_POST['call_id'];
}
In display.php there's also a form that self-post data to display.php for record update (last condition in the code).
In rest of the script I'm checking $fresh_call, $saving_call, $pick_a_call values to query the db with the right UPDATE/INSERT/SELECT SQL.
I'm not sure about my solution, I would like to design a class that can help me making my script more "clear" and lighter. I think also that this situation is probably a typical problem to solve in PHP coding.
Here's a functional alternative which should work the same as the code you posted, but may be a little easier to understand:
function set_call_id( $val )
{
$_SESSION['call_id'] = $val;
}
if( isset($_GET['id']) )
{
set_call_id( $_GET['id'] );
pick_a_call();
}
else if( isset($_POST["MM_update"]) )
{
set_call_id( $_POST['call_id'] );
saving_call();
}
else
{
set_call_id( time() . $_GET['operatore'] );
fresh_call();
}
It's not part of the script you have posted, but I think the most important thing you need to do is make sure you are first escaping your GET/POST vars before using them to query the database.
For example, if you are using MySQL, you could use mysql_real_escape_string().
Related
While I refresh my browser the entries of the registration form goes into the Database every time i press REFRESH, Professor told me to resolve this problem with the help of LAST_INSERT_ID().
I am able to get the last_insert_id from the database but doesn't know what would I do further with that ID.
Please help..
enter image description here
The recommended way is to use the Post/Redirect/Get pattern.
There are other ways to achieve what you desire here.
I am not sure what your professor is asking to do with the last insert id. Maybe he is referring to something like this,
if(isset($_SESSION['last_insert_id'])){ // At the beggining
//redirect to a another location
}
// Code for insertion goes here
$_SESSION['last_insert_id'] = $last_insert_id; // Get and store the insertion id as a session
I think you are using the same page to Save the Data, If it is So, then follow the following method :
<?php
if(isset($_POST[userName]))
{
// Put your Registration Operation Code Here
header('Location: ./Registrationform.php');
}
?>
After DataBase Insertion it redirects to the same page. Now Refresh is made with the GET Method not by the POST Method. So, you can eliminate the duplicate entries by this way.
As per your requirement I used the Last Inserted ID for the Validation before Inserting Records in the Database.
<?php
session_start();
if(isset($_POST[userID]))
{
$flag = false;
if(isset($_SESSION['last_insert_id']))
{
if($_SESSION['last_insert_id'] == $_POST[userID])
{
$flag = false;
header('Location: ./Registrationform.php');
}
else
{
$flag = true;
$_SESSION['last_insert_id'] = $_POST[userID];
}
}
if($flag == true)
{
// Put your Registration Operation Code Here
}
}
?>
I'm developing a plugin for wordpress, the parameter of the $ _GET is recorded in the database according to the preference of the User via the Wordpress Admin Panel. The following validation has to be via the $ _GET, this is the function:
$db_url = get_option('my_get_url');
// returns the value of the database entered by User
// on this case return --> page=nosupport
$url_explode = explode("=", $db_url);
$url_before = $url_explode[0]; // --> page
$url_after = $url_explode[1]; // --> nosupport
echo "Before: ".$url_before; // here are ok, return --> page
echo "After: ".$url_after; // here are ok, return --> nosupport
My problem is here:
// here $_GET no have any value, dont work on validate...
if($_GET[$url_before] != ""){
if($_GET['$url_before']=="nosupport"){
// my function goes here...
}
}
I using for test the parameter:
echo $_GET[$url_before];
But dont return any value...
I found the problem, i had already tested all of these options, but ever dont working, the problem was that I was testing the function inside the main page of my site, and on the main page (mysite.com) does not get the parameter (?page=nossuport), so always returning null values, when I used the variable in the GET or used the echo $GET[$my_var] to test.. It was a great carelessness of mine, would never work...
by the way, the two parameters works correctly:
$_GET[$url_before]
$_GET["$url_before"]
The Problem are solved, Thanks for help.
if($_GET[$url_before] != ""){
if($_GET[$url_before]=="nosupport"){ // note no "" here
// my function goes here...
}
}
In your solution, the key was treated as a string, with no variables evaluated.
You forgot to take out the ' in the second condition.
You wrote:
$_GET['$url_before']
I'm guessing it should be:
$_GET[$url_before]
foreach($_GET as $key => $value){
if($key == "nosupport"){
}
}
I am fairly new to PHP and am using a couple of _GET variables to determine page layout/web service data and some other logic on the page. I am not storing the data or writing to a DB of any kind. What kind of sanitization should I be using for this?
For example, one var I'm using is like this:
$querystring = $_SERVER['QUERY_STRING'];
if(isset($_GET['semester']) && $_GET['semester'] != ''){
$listxml = simplexml_load_file("http://path/to/webservice/?".str_replace('semester','term',$querystring));
What's going on there is if the querystring has the ?semester= set and not blank then I replace it with 'term' and pass through the querystring as is to a web service URL (the web service uses the term variable but the term variable interferes with wordpress and redirects to the posts page for that 'term' (tag/category in WP) so I pass it through WP as semester and then just change it to term for the web service call.
So in this case I'm not doing anything with the _GET except passing it on as is to a web service what the web service does with the querystring is out of my hands, but should I 'prep' it in any way for them?
--
I've also got cases similar to this:
$display = '';
if (isset($_GET['display'])) {
$display = $_GET['display']; //set sort via querystring
} else {
$display = 'interest'; //set to default by interest
}
later:
<div id='byalphabet' class='<?php global $display; if($display != 'alphabet'){echo 'hide';} ?>'>
and
<div id="byinterest" class="<?php global $display; if($display != 'interest'){echo 'hide';} ?>">
--
Also using for some dynamic javascript:
$view = '';
if (isset($_GET['view'])) {
$view = $_GET['view']; //set view via querystring
}
Later:
<script>
<?php if ($view != ''){ $view = str_replace('/','',$view); ?>
jQuery('#<?php echo $view; ?>').trigger('click'); //activate view option accordion pane
jQuery('html,body').animate({'scrollTop':jQuery('#<?php echo $view; ?>').offset().top - 50},500); //scrollTo view
</script>
--
Other cases include searching an array for a _GET value array_search($_GET['major'], $slugs); and redirecting a page using:
$parts = explode('/',$_SERVER['REQUEST_URI']);
Header( "HTTP/1.1 301 Moved Permanently" ); //SEO friendly redirect
Header( "Location: http://www.site.ca/programs/outline/".$parts[3]."/" );
Edit: I have read many of the suggested similar questions that popped up but they mostly refer to using the data in some other way such as inserting into a DB.
You should always sanitize input parameters. Even if you aren't using them in the database, you are still vulnerable to cross site scripting/XSS attacks.
<?php $view = $_GET['view'] ?>
<script>jQuery('#<?php echo $view; ?>').trigger('click');</script>
For example given the above code, everything is fine if ?view=page_one because your JavaScript looks like jQuery('#page_one').trigger('click');.
But what if your querystring is ?view=hacked%27)%3B%20alert(document.cookies)%3B%20jQuery(%27%23page_one - now your javascript looks like the following on the page:
jQuery('#hacked'); alert(document.cookies); jQuery('#page_one').trigger('click');
The alert() could just as easily be an AJAX request to send auth tokens, etc to a different server.
Ultimately the type of sanitizing you do depends on the context that you are using the input. In this example, you might want to make sure you escape single quotes for example, but what is appropriate may differ between implementations.
Good article on sanitizing inputs here: http://coding.smashingmagazine.com/2011/01/11/keeping-web-users-safe-by-sanitizing-input-data/
I am redirecting to a different page with Querystring, say
header('location:abc.php?var=1');
I am able to display a message on the redirected page with the help of querystring value by using the following code, say
if (isset ($_GET['var']))
{
if ($_GET['var']==1)
{
echo 'Done';
}
}
But my problem is that the message keeps on displaying even on refreshing the page. Thus I want that the message should get removed on page refresh i.e. the value or the querystring should not exist in the url on refresh.
Thanks in advance.
You cannot "remove a query parameter on refresh". "Refresh" means the browser requests the same URL again, there's no specific event that is triggered on a refresh that would let you distinguish it from a regular page request.
Therefore, the only option to get rid of the query parameter is to redirect to a different URL after the message has been displayed. Say, using Javascript you redirect to a different page after 10 seconds or so. This significantly changes the user experience though and doesn't really solve the problem.
Option two is to save the message in a server-side session and display it once. E.g., something like:
if (isset($_SESSION['message'])) {
echo $_SESSION['message'];
unset($_SESSION['message']);
}
This can cause confusion with parallel requests though, but is mostly negligible.
Option three would be a combination of both: you save the message in the session with some unique token, then pass that token in the URL, then display the message once. E.g.:
if (isset($_GET['message'], $_SESSION['messages'][$_GET['message']])) {
echo $_SESSION['messages'][$_GET['message']];
unset($_SESSION['messages'][$_GET['message']]);
}
Better use a session instead
Assign the value to a session var
$_SESSION['whatever'] = 1;
On the next page, use it and later unset it
if(isset($_SESSION['whatever']) && $_SESSION['whatever'] == 1) {
//Do whatever you want to do here
unset($_SESSION['whatever']); //And at the end you can unset the var
}
This will be a safer alternative as it will save you from sanitizing the get value and also the value will be hidden from the users
There's an elegant JavaScript solution. If the browser supports history.replaceState (http://caniuse.com/#feat=history) you can simply call window.history.replaceState(Object, Title, URL) and replace the current entry in the browser history with a clean URL. The querystring will no longer be used on either refresh or back/previous buttons.
When the message prompt ask for a non exsisting session. If false, show the message, if true, do nothing. session_start(); is only needed, if there is no one startet before.
session_start();
if ($_GET['var']==1 && !isset($_SESSION['message_shown']))
{
$_SESSION['message_shown'] = 1;
echo 'Done';
}
Try this way [Using Sessions]
<?php
//abc.php
session_start();
if (isset ($_GET['var']))
{
if ($_GET['var']==1)
{
if(isset($_SESSION['views']))
{
//$_SESSION['views']=1;
}
else
{
echo 'Done';
$_SESSION['views']=1;
}
}
}
?>
Think the question mean something like this?
$uri_req = trim($_SERVER['REQUEST_URI']);
if(!empty($_SERVER['REQUEST_URI'])){
$new_uri_req = str_replace('?avar=1', '?', $uri_req);
$new_uri_req = str_replace('&avar=1', '', $new_uri_req);
$pos = strpos($new_uri_req, '?&');
if ($pos !== false) {
$new_uri_req = str_replace('?&', '?', $new_uri_req);
}
}
if( strrchr($new_uri_req, "?") == '?' ){
$new_uri_req = substr($new_uri_req, 0, -1);
}
echo $new_uri_req; exit;
You can use then the url to redirect without vars. You can also do the same in js.
str_replace() can pass array of values to be replaced. First two calls to str_replace() can be unified, and filled with as many vars you like that needs to be removed. Also note that with preg_replace() you can use regexp that can so manage any passed var which value may change. Cheers!
I'm trying to pass an error message from a server side form validator in a function back to the form it was submitted in. The validator is working as it prevents the rest of the code saving it to a database as planned. However I cant get it to pass back to the form to display the error
function saveComment(){
$validate = array();
$id = isset($_POST["articleId"]) ? $_POST["articleId"] : '';
if ( isset( $_POST['saveChanges'] ) ) {
if ( $_POST['name'] == "" ){
$validate['errorMessage'] = "Please fill out your name.";
header( "Location:".HOME_PATH."/.?action=viewArticle&articleId=".$_POST['articleID']."");
}
I' trying to pass it back to this
if ( isset( $validate['errorMessage'] ) ) {
echo $validate['errorMessage'];
}
When I remove the if on the display function I get the error unidentified index
What do I need to do to get the form to display the error message. Do I need to pass the array to the function that handles the display of the article?
FEEDBACK
For anyone that may find this useful I used #OliverBS post method pretty much unaltered.
Also thank you to #lethal-guitar as he explanation has helped me understand where I went wrong and the various methods that can be used to solve this problem +1
You're setting a variable $validate for your currently executing script. Afterwards, you send a redirect header. This will cause your browser to issue a new request, thus ending the currently executing script and scrapping the variable. The new request will trigger another script invocation, where the variable is not known anymore since it only existed for the duration of the first request.
HTTP is stateless, so every variable you set on the server side will only exist until you finish your current request and respond to the client. What you need is a way to pass this variable to the script handling the second request. There are several ways to do so:
Pass a GET parameter. You could append something like "&validationError=" . $validate['errorMessage'] to the URL you're passing to the Location header, and then in the display page access it via $_GET.
Save the validation status in the $_SESSION. The PHP manual contains a lot of information about sessions (maybe you're already using them?)
Restructure your code in a way that you don't redirect on error, but on success.
Some more information on the 3rd proposal: You write one PHP-Script which displays the form and handles the form post request. If validation fails, you simply redisplay, and insert the echo statement you already have. If it suceeds, you redirect to some success page. This way, the variable will remain accessible, since it's still the same request.
On a quick glance try this
Session way
Make sure to start the session by doing session_start(); at the top of the file where saveComment is and the isset checked.
function saveComment(){
$id = isset($_POST["articleId"]) ? $_POST["articleId"] : '';
if ( isset( $_POST['saveChanges'] ) ) {
if ( $_POST['name'] == "" ){
$_SESSION['errorMessage'] = "Please fill out your name.";
header( "Location:".HOME_PATH."/.?action=viewArticle&articleId=".$_POST['articleID']."");
}
if ( isset( $_SESSION['errorMessage'] ) ) {
echo $_SESSION['errorMessage'];
}
or you can try
POST way
function saveComment(){
$id = isset($_POST["articleId"]) ? $_POST["articleId"] : '';
if ( isset( $_POST['saveChanges'] ) ) {
if ( $_POST['name'] == "" ){
$error = urlencode('Please fill out your name');
header( "Location:".HOME_PATH."/.?action=viewArticle&articleId=".$_POST['articleID']. "&error=" . $error);
}
if ( isset( $_GET['error'] ) ) {
echo urldecode($_GET['error']);
}
I have not tested this but you should get the basic idea of what to do.
When you do a header location your redirecting the user to a new page. Your going to have to either pass the error in the query string or ideally pass it as a variable in the session.
I would suggest doing this all in one file, i.e. The form and the validation as one file.
Then you can do this:
<?php
//set success to 0
$success = 0;
$errormsgs = array();
//check for post
if(isset($_POST['submit'])){
//get the data from the form post and validate it
$valid = validateFuntion($_POST['data'])
//the is function will validate the data. If it is not valid, it will add a message to $errormsgs
//check for errors
if(!$errormsgs){
//data validation was successful, do stuff
}
}//if validation fails, it will fall out of the this code block and move on
?>
<html>
<body>
<?php
//check for errors
if($errormsgs){
$content .= '<ul class="errors">';
foreach($errormsgs as $error){
$content .= "<li>" . $error . "</li>";
}
$content .= "</ul>";
echo $content;
}
?>
<form name="name" action="" method="post">
<input name="name" value="<?= (isset($_POST['data']) ? $_POST['data'] : '') ?>" type="text">
</form>
</body>
</html>
You're redirecting the user to the "error" page with the header statement. The problem is, of course, this is a completely new page, there's no state left over, so none of your variables exist any more.
There's two ways to do it, either pass it on the query string (so add &error=...) and parse that in your template, or save it to the session.
Of course, you should really be doing this before your template is presented using a different means, but that's a complete rework of your code.