Avatar of Alex Lord
Alex Lord
 asked on

filter $_POST in PHP pdo

foreach($_POST as $key => $val){
			
			$k = $key;
			$v = $val; 
			if($v=='NULL'){
	
				/*$stmt = new Database();
				
				$query = "UPDATE TXT2GIVE_CONTACTS SET :k = :v WHERE ID = :contactId";
				$stmt->query( $query );
				$stmt->bind( ':k', $k);
				$stmt->bind( ':contactId', $contactId );
				$stmt->bind( ':v', $v);
				$stmt->execute();
				$result = $stmt->all(); */
				$updatedFields = "v is null";

			} else {
				$updatedFields = "v is not empty";

				$stmt = new Database();

				$query = "UPDATE TXT2GIVE_CONTACTS SET :k = :v WHERE ID = :contactId";
				$stmt->query( $query );
				$stmt->bind( ':k', $k);
				$stmt->bind( ':contactId', $contactId );
				$stmt->bind( ':v', $v);
				$stmt->execute();
				$result = $stmt->all();
			} 

Open in new window




here is my statement, so as u see it goes into the $_POST and uses these to update the database,  however i also have a field within $_POST that isnt in that database such as subaction which triggers the case this code is currently sitting,  how can i remove these from the $_POST ? or filter them ?
* PDO* POSTDatabasesPHP

Avatar of undefined
Last Comment
Alex Lord

8/22/2022 - Mon
Chris Stanyon

You can just call unset() to remove variable before your loop:

unset($_POST['someKey']);
Alex Lord

ASKER
thanks chris, i may have another question in relation to this when i hit it lol
gr8gonzo

This is bad way to do what you're doing. There are two big problems:

1. It's inefficient - it runs a separate query for each field that is being updated. So if you update 3 fields, then you're running 3 queries instead of just updating 3 fields with one query.

2. It's susceptible to parameter manipulation. For example, if I mess with the contact form (using the developer tools built into every major browser) and add an input like this:
<input name="ID" value="-1">

Open in new window

...then your code will blindly follow the instructions to update the ID field for that record to -1. Granted, ID might not be your biggest field of concern, but if there's some other valuable field, it's equally susceptible.

Trying to modify the $_POST to accommodate the loop is a bad answer, because now you've permanently lost that data. The $_POST and $_GET should never be modified. It only creates confusion later on (is that truly the data that's coming over or is a field missing because I erased it from the array.....?). Just because you CAN modify it does not mean you should.

You should RARELY EVER take the raw value from the end user and put it right into the database. You should always try to validate the input if you can (did they REALLY donate a billion dollars or is that just what the input value said?).

To fix these problems (and your original issue), don't loop through POST.

Yes, it can be kind of cool and convenient to have something dynamic like that, but it also sets you up as a hacking target. Your code should individually extract the desired fields from the $POST array and then build a single update query. There's probably an even cleaner way of doing this, but here's the general idea:

$changedFields = array();

if(isset($_POST["fieldX"]) && ($_POST["fieldX"] != "NULL"))
{
  // Validate the value of fieldX to make sure it's correct, and then once you've done that...
  $changedFields["fieldX"] = validated / sanitized value of fieldX;
}

// Repeat for fieldY, fieldZ, etc...

// Then build your UDPATE
$stmt = new Database();

$query = "UPDATE TXT2GIVE_CONTACTS SET ";
foreach($changedFields as $k => $v)
{
  $query .= ":{$k}_key = :{$k}_value ";
}
$query .= "WHERE ID = :contactId";
$stmt->query( $query );
foreach($changedFields as $k => $v)
{
  $stmt->bind( ':{$k}_key', $k);
  $stmt->bind( ':{$k}_value', $v);
}
$stmt->bind( ':contactId', $contactId );
$stmt->execute();
$result = $stmt->all();

Open in new window

All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
gr8gonzo

@Chris - Really? You suggested modifying $_POST? Come on - you know that's not the right answer here.
Chris Stanyon

@gr8gonzo ... :)

Generally not something I would normally do ( but I have to admit - I have done it in the past !! )
Alex Lord

ASKER
Hmm ok i can see how that will be an issue,

for Validate you got field x than repeact, what do you mean for this section as my $_POST array contains values from 10 inputs and one of them is called subaction which triggers a case statement and isnt within the table.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Chris Stanyon

You might want to show us an example of your POST data. There's nothing fundamentally wrong with looping over your POST data but to give you the best advice, we'd want to see what you're working with.
ASKER CERTIFIED SOLUTION
gr8gonzo

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Alex Lord

ASKER
@gr8gonzo

hey ill give this a good look over and get back to you on outcome, thank you for learning advice.
Steve Bink

Just a couple of additional thoughts:

First and foremost, gr8gonzo's admonition regarding actually altering the $_POST data is right on target.  That's the original version of the data, and should be sacrosanct.  Any alterations to that data should be done, minimally, on a copy, not on the original array.  Ideally, no alteration would be necessary - filtering the keys into a working copy should be sufficient for your purposes.

Regarding which keys to use from $_POST, a very common strategy is to make the application aware of the schema with which it is working.  This is normally done during bootstrap, or through a lazy-load bootstrap strategy, and involves the application actually querying the DB for the table schema prior to work being done.  Assuming your $_POST data matches your field names (or if you have an appropriate map for mismatched names), then filtering becomes very simple.

Finally, gr8gonzo's initial reply mentioned running multiple queries.  Again, the observation is on target.  If you know this update will affect a single table, it is much better efficiency to collect all the changes, then run a single UPDATE query.  The execution of a loop to validate the fields and data is minimal time, but there is a relatively huge amount of overhead involved in sending commands to the database service, even with the connection already open.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Alex Lord

ASKER
Im working on this area but taking it slow using gr8gonzo's advice and taking my time, thax for the help :)