$_POST variables acting like freaking GHOSTS! - $20 for fix!

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Hattemageren
Forum Newbie
Posts: 5
Joined: Tue Jan 18, 2011 3:19 pm

$_POST variables acting like freaking GHOSTS! - $20 for fix!

Post by Hattemageren »

Hello!

I've been struggling with this problem for over a week now - and I finally crawl the cross and ask for help. Because I'm 100% and totally lost on this issue. On my website I use lots of forms, obviously. The thing is, around a week ago these forms started acting really weird - not just "mentally unstable"-weird, I mean weird by the core defintion of that word!

Basically, at first it seemed random when a variable would lose and not lose its content. But I have isolated a couple of incidents where certain things happen. Let's take this code as our starting point:

Code: Select all

$name = $_POST['setname'];
mysql_query("UPDATE em_database_content SET name='$name' WHERE id='$id'");
This code will always lose the content of the variable, but FIRST when it is executed in the query. The query will run without errors, but $name will be inserted as empty. Nothing weird in that, could happen to anybody, right? BUT, I tried echo the content of $name JUST before the query - it HAS content. Now, if I submit the very same form and run the very same code this snippet WILL work right:

Code: Select all

$name = $_POST['setname'];
$name && mysql_query("UPDATE em_database_content SET name='$name' WHERE id='$id'");
So it only runs the query if something exists in $name - works fine, and even executes the query everytime (which it wouldn't if $name was empty which it APPEARS to be when $name && is not validated in front of the query). If I do nothing else but removing $name && again, the error re-occurs and the data will be lost. I'm 100% sure no "stupid mistake" is involved in this, as I said I've been error isolating over a week now.

Also, I could of course just do the $name && in front of all queries, but I dont want that. I want my code to work - and I want to understand WHY it works.

If I do this:

Code: Select all

$name = $_POST['setname'];
mysql_query("UPDATE em_database_content SET name='$name' WHERE id='$id'");
echo $name;
$name will be perfectly echoed - So my logic tells me query is the thing that doesn't function. But yet it does update the information whenever I had the $name && in front. And replacing $name with static text in the query will also execute perfectly (and of course update the information).

Another weird thing I'm not 100% sure is related to this, is that I can execute this code:

Code: Select all

echo "--" . $_POST['setname'] . "--";
This will correctly show -- then the content of the POST variable and then --. HOWEVER, if I open to view the source there's only the dashes.. So the source code will show: ----
WHILE in the render there is the content of the $POST variable.. How is this even possible? It shouldnt be to my understanding. This only happens in Google Chrome, in Firefox and IE it shows up correctly in the source code.

I've never seen anything like this in my 7 years of PHP programming, and I really hope someone can help me out. This is holding back the project of my life which Ive been working on for over 2 years now. And it has spread to all corners of my app :-/ I have too been thinking virus, but then again, how can I virus on the server side make the browser act weird - and how can a client side virus make the database lose information?

I also tried a complete server move and messed around with magic_gpc and register_global. Feels like I've tried everything possible several times.

I'm really lost. I'm so lost I will pay $20 for the solution (via Paypal) - if several people contribute to the actual fix the amount will be split.
Last edited by Hattemageren on Tue Jan 18, 2011 4:34 pm, edited 5 times in total.
s992
Forum Contributor
Posts: 124
Joined: Wed Oct 27, 2010 3:06 pm

Re: $_POST variables acting like freaking GHOSTS!

Post by s992 »

You obviously need to use the $_GHOST superglobal instead of $_POST.
Hattemageren
Forum Newbie
Posts: 5
Joined: Tue Jan 18, 2011 3:19 pm

Re: $_POST variables acting like freaking GHOSTS!

Post by Hattemageren »

Btw, don't mind the switch between "setname" and "name" - it has no influence.. Setname was not renamed until today..

s992: Haha, true that! :D
Hattemageren
Forum Newbie
Posts: 5
Joined: Tue Jan 18, 2011 3:19 pm

Re: $_POST variables acting like freaking GHOSTS! - $20 for

Post by Hattemageren »

I just found another piculiar thing.. If I do this:

Code: Select all

$name = "Something" . $_POST['setname'];
mysql_query("UPDATE em_database_content SET name='$name' WHERE id='$id'");
echo $name;
Inserted into the database is ONLY "Something", while the echo will put out "Something" AND content of POST variable... How is this possible?!

Looks like the query is not happy with POST variables - But why? And how?!!
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: $_POST variables acting like freaking GHOSTS! - $20 for

Post by Benjamin »

Post all the code and escape data before using it in queries. See mysql_real_escape_string().
Hattemageren
Forum Newbie
Posts: 5
Joined: Tue Jan 18, 2011 3:19 pm

Re: $_POST variables acting like freaking GHOSTS! - $20 for

Post by Hattemageren »

Tried it :-/ No effect
User avatar
social_experiment
DevNet Master
Posts: 2793
Joined: Sun Feb 15, 2009 11:08 am
Location: .za

Re: $_POST variables acting like freaking GHOSTS! - $20 for

Post by social_experiment »

Can you paste the complete script, including the html form
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” - Mosher’s Law of Software Engineering
Hattemageren
Forum Newbie
Posts: 5
Joined: Tue Jan 18, 2011 3:19 pm

Re: $_POST variables acting like freaking GHOSTS! - $20 for

Post by Hattemageren »

Let me know if you also want some of the functions

Code: Select all

	if ($action === "updateInfo")
	{
		$name = mysql_real_escape_string($_POST['setname']);
		$hidebyname = $_POST['hidebyname'];
		$hideprofile = $_POST['hideprofile'];
		$showgeotag = $_POST['showgeotag'];
		
		$hidebyname == "on" && $hidebyname = 1
			or $hidebyname = 0;
			
		$hideprofile == "on" && $hideprofile = 1
			or $hideprofile = 0;
		
		$showgeotag == "on" && $showgeotag = 1
			or $showgeotag = 0;
			
		### Refresh Geotag Information ###
		
		// If the user has had geotagging disabled we will want them to immediately have the opportunity
		// to show their location, so they won't have to log out and in again, in order to see an effect.
		// This will cause some users to think it isn't working properly.
		
		!$showgeotag && mysql_query("UPDATE em_users SET geotag='' WHERE id='" . $in_user['id'] . "'");
		
		(!$in_user['cfg_showgeotag'] && $showgeotag) && $_SESSION['setgeotag'] = true;
		
		### Update Profile Picture ###
		
		$ppic = "";
		
		if ($_POST['removepp'])
		{
			unlink($in_user['cfg_profilepic']);
		}
			else
		{
			if ($_FILES['propic'])
			{
				$ppfile = $_FILES['propic'];
				$uploadfail = false;
				
				if ($ppfile)
				{
					if (!getimagesize($ppfile['tmp_name']))
					{
						$uploadfail = true;
					}
						else
					{
						unlink($in_user['cfg_profilepic']);
						$filename = "upload/profiles/" . md5($in_user['id']) . "_" . rand(1000, 9999) . "." . $ext = substr(strrchr($ppfile['name'], '.'), 1);
						move_uploaded_file($ppfile['tmp_name'], $filename);
						$ppic = $filename;
					}			
				}
			}
				else
			{
				$ppic = $in_user['cfg_profilepic'];
			}
		}
		
		### Finalize ###
		
		mysql_query("UPDATE em_users SET name='$name', cfg_showgeotag='$showgeotag', cfg_profilepic='$ppic', cfg_hidebyname='$hidebyname', cfg_hideprofile='$hideprofile' WHERE id='" . $in_user['id'] . "'");
		
		if ($uploadfail)
		{
			SetStatus(STATUS_SETTINGS_PERSONALSAVED_FAILEDUPLOAD, STATUSMSG_ERROR);
		}
			else
		{
			SetStatus(STATUS_SETTINGS_PERSONALSAVED);
		}
		
		redirect("?show=personal");
	}

Code: Select all

<form method="post" action="?show=personal&action=updateInfo" enctype="multipart/form-data">
			
				<?php
				
					SubmitBtn(MENU_SAVE, "location.href = '?show=home'", "540px", "none");
				
				?>
	
				<br>
	
				<div class="sidebar">
					
					<?php SheetInfo(FORM_SHEET_SETTINGS_PROPIC, "100%", "images/icons/profilepic.png"); ?>
					
					<?php
					
						if (!$in_user['cfg_profilepic'])
						{
							echo NOTE_SETTINGS_NOPIC;
							echo "<br>";
						}
							else
						{
							ProfilePicture($in_user['cfg_profilepic']);
						}
						
						echo "<br><b>" . FORM_NEWPROPIC . ":</b><br>";
						
						form_file("propic");
						
						if ($in_user['cfg_profilepic'])
						{
							echo "<br><br>";
							form_checkbox("removepp", FORM_REMOVEPROPIC);
						}
						
						echo "<br><br><span class=\"note_discrete\">" . NOTE_FORM_IMAGEFORMATS . "<br><br>" . NOTE_SETTINGS_PROPICSIZE . "</span>";
					
					?>
					
					<?php EndSheet(); ?>
					
				</div>
				
			<?php SheetInfo(FORM_SHEET_SETTINGS_NAME, "540px", "images/icons/name.png"); ?>
			
				<?php echo NOTE_SETTINGS_FULLNAME ?>
				
				<br><br>
		
				<table>
				
					<tr>
						<td class="formTitle"><?php echo FORM_NAME . ":"?></td>
						<td class="formInput"><?php form_text("setname", $in_user['name']);?></td>
					</tr>
					
				</table>
				
				<br>
				
				<?php echo NOTE_SETTINGS_HIDEFROMSEARCH ?>
				
				<br><br><?php form_checkbox("hidebyname", OPTIONS_SEARCH_HIDEBYNAME, null, $in_user['cfg_hidebyname']); ?>
				<br><br><?php form_checkbox("hideprofile", OPTIONS_SEARCH_HIDEPROFILE, null, $in_user['cfg_hideprofile']); ?>
				<br><br><?php form_checkbox("showgeotag", OPTIONS_SHOWGEOTAG, null, $in_user['cfg_showgeotag']); ?>
				
				<?php EndSheet(); ?>
				
			</form>

The functions that generate the forms:

Code: Select all

  function form_text($name, $value, $onkeyup = "", $style = "")
  {
  	global $tabIndex;
  	
  	$tabIndex++;
  	
  	$onkeyup && $inOnKeyUp = " onkeyup=\"$onkeyup\""
  		or $inOnKeyUp = "";
  		
  	$style && $style = " style=\"$style\"";
  	
  	!SETTINGS_DISABLEAUTOFOCUS && $onmouseover = " onmouseover=\"this.focus();\"";
  	
  	echo "<input tabindex=\"$tabIndex\"$style type=\"text\" id=\"$name\" value=\"". plain2html($value) . "\" name=\"$name\"$inOnKeyUp$onmouseover>";
  }

  function form_checkbox($name, $title = "", $events = "", $value = "", $style = "")
  {
  	$events = " " . $events;
  	
  	$style && $style = " style=\"$style\"";
  	
  	// Determine positive value input in either boolean or integer
  	($value === true || $value == 1) && $checkVal = " checked=\"checked\""
  		or $checkVal = "";
  	
  	echo "<input$style type=\"checkbox\" name=\"$name\" id=\"$name\"$events$checkVal> <label style=\"cursor: pointer;\" for=\"$name\">" . $title . "</label>";
  }
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: $_POST variables acting like freaking GHOSTS! - $20 for

Post by Jonah Bron »

Code: Select all

$hidebyname == "on" && $hidebyname = 1
                        or $hidebyname = 0;
This is frightening. Use a ternary operation.

Code: Select all

$hidebyname = ($hidebyname == 'on') ? 1 : 0;
And you need to clean all $_POST values, not just setname.

Code: Select all

mysql_query("UPDATE em_users SET name='$name', cfg_showgeotag='$showgeotag', cfg_profilepic='$ppic', cfg_hidebyname='$hidebyname', cfg_hideprofile='$hideprofile' WHERE id='" . $in_user['id'] . "'");
Sprintf() makes this sort of thing much neater.

Code: Select all

mysql_query(
    sprintf(
        'UPDATE em_users SET name="%s", cfg_showgeotag="%s", cfg_profilepic="%s", cfg_hidebyname="%s", cfg_hideprofile="%s" WHERE id="%s"',
        mysql_real_escape_string($name),
        mysql_real_escape_string($showgeotag),
        mysql_real_escape_string($ppic),
        mysql_real_escape_string($hidebyname),
        mysql_real_escape_string($hideprofile),
        mysql_real_escape_string($in_user['id'])
    )
);

Code: Select all

!$showgeotag && mysql_query("UPDATE em_users SET geotag='' WHERE id='" . $in_user['id'] . "'");
Again, frightening. Use a normal if statement.

Code: Select all

if (!$showgeotag) {
    mysql_query("UPDATE em_users SET geotag='' WHERE id='" . $in_user['id'] . "'");
}
The intent here is much clearer.

Code: Select all

if ($_POST['removepp'])
{
    unlink($in_user['cfg_profilepic']);
    }
    else
    {
        if ($_FILES['propic'])
        {
Elseif works much better.

Code: Select all

if ($_POST['removepp']) {
    unlink($in_user['cfg_profilepic']);
} elseif ($_FILES['propic']) {
Plus, that doesn't work. You must use isset() when checking for array indices.

Code: Select all

if (isset($_POST['removepp'])) {
    unlink($in_user['cfg_profilepic']);
} elseif (isset($_FILES['propic'])) {
None of this is guaranteed to fix your problem, but they'll certainly help you maintain your code, and make it easier for us here to help you.
Post Reply