0

Is it possible to tell php to NOT post data if the form field is null?

right now my post variables in my insert.php page look like this:

fname = $_POST['firstname'];
lname = $_post['lasname'];

sql = "UPDATE profile SET first='.$fname.', last='.$lname.' WHERE id='.$id.'";

If my form fields are empty or null, I'd like the $fname $lname not to post. What would be the best method to do this?

Currently when i submit an update, if those fields are empty they update the entire table with empty rows if nothing is inserted.

Alexander Yancharuk
  • 13,817
  • 5
  • 55
  • 55
MizAkita
  • 1,115
  • 5
  • 21
  • 52

5 Answers5

0

You could use something like this for each field:

$fname = empty($_POST['firstname']) ? null : $_POST['firstname'];

This will set $fname to null if the form field does not exist or the input was empty. Otherwise, it will use the original value.

Update

If you want to only update fields that aren't null, you'll need to add some extra logic:

if($fname !== null && $lname !== null) {
    // update both
}
else if($fname !== null) {
    // update just fname
}
else if($lname !== null) {
    // update just lname
}
George Brighton
  • 5,131
  • 9
  • 27
  • 36
0

Is it possible to tell php to NOT post data if the form field is null? It isn't PHP who is posting data, it is your browser the moment you hit the submit button of the form. In order to prevent this from happening when the fields are empty, you will have to use something client-sided (javascript), which first validates if the fields are indeed filled in before the form is submitted.

This is how I understand your question though. If you don't want to create the SQL query when the $_POST variables are empty, then simply use an if condition or a ternary operator.

pbond
  • 1,888
  • 4
  • 19
  • 35
  • Sounds easy enough but how would i tell Javascript to hide values that are null? It's above my head... – MizAkita Oct 04 '13 at 22:48
  • What are you trying to achieve? Javascript works client-sided and what you're asking here is something server-sided I guess. If you don't want the form to post at all if the fields are empty, you'll need javascript. If you want something done after the form is posted, you need PHP. What exactly do you want to get done? What is the expected behaviour? Clarify your original question a bit, as you can see the answers broadly differ due to the vagueness of the question. – pbond Oct 04 '13 at 22:50
  • Before the form is submitted, hide the unchanged fields. The null or empty fields only. Currently when i submit an update, if those fields are empty they update the entire table with empty rows if nothing is inserted. – MizAkita Oct 04 '13 at 23:04
0

I'd do this:

$fname = isset($_POST['firstname']) && strlen($_POST['firstname']) > 0 ? $_POST['firstname'] : null;

This way, $fname will be defined to the $_POST['firstname'] value if the variable is set and not empty, otherwise it will be null

By the way, if you're working inside double quotes ("), there's no need to use a dot to add values to the $sql string. Even more, your syntax is wrong. This is a working way to do it:

$sql = "UPDATE profile SET first='$fname', last='$lname' WHERE id='$id'";

You should NOT use this kind of SQL-query generation. It's vulnerable to SQL injections. Better use PDO or MySQLi parametrized queries.

And, by the way, if you want to deny the insertion if a value is empty, you better do it when creating the MySQL table (assigning a not null property to the column). For example:

CREATE TABLE user(
    first VARCHAR(50) NOT NULL,
    last VARCHAR(50) NOT NULL
)

** EDIT: If I'm understanding well, this is that you want:

$valuesToAdd = "";
// Concatenate values to the query if they are defined
if (isset($_POST['firstname']) && strlen($_POST['firstname']) > 0) $valuesToAdd .= "first = '{$_POST['firstname']}',";
if (isset($_POST['lastname']) && strlen($_POST['lastname']) > 0) $valuesToAdd .= "last = '{$_POST['lastname']}',";
// Repeat for any other values...

// By default, the SQL string is empty
$sql = "";

// If changes were made...
if (strlen($valuesToAdd) > 0) {
    // Remove the last ","
    $valuesToAdd = substr($valuesToAdd, 0, strlen($valuesToAdd)-1);

    // Generate the SQL string with the values which will be added
    $sql = "UPDATE profile SET {$valuesToAdd} WHERE id='{$id}'";

    // echo $sql; die;
}


// Check if the SQL string is not empty
if (strlen($sql) > 0) {
    // Here the SQL has been generated, use it for a SQL query...
    // $con = mysql_connect(...); .....
}
Alejandro Iván
  • 3,969
  • 1
  • 21
  • 30
  • The use of `isset()` is redundant; the check is included in `empty()`. – George Brighton Oct 04 '13 at 22:47
  • For the sake of time, and not wanting to copy my entire insert.php page, i quickly drafted the above. so if i am correct, isset would replace my $_POST variables? – MizAkita Oct 04 '13 at 22:52
  • No, isset is used for a conditional assignation. For example, `$v = isset($a) ? $a : null;` is equivalent to `if ( isset($a) ) $v = $a; else $v = null;`, but the "avoid inserting empty values" is better to be done in MySQL rather than PHP (you'll be ensuring consistency of your database). – Alejandro Iván Oct 04 '13 at 22:53
  • Well... what i did is, created a form which submits some profile information. I then duplicated that form and made it an update page. This page fetches the associated id of the profile and updates the record. The problem is, is when u submit a field with changes, the others are deleted. – MizAkita Oct 04 '13 at 23:03
  • You should not use `empty` in these case. Otherwise the user will not be able to store values such as `0` and `0.0` in database. – Salman A Oct 04 '13 at 23:17
  • ok i just tried this but it didnt work :-( there are syntax errors and some other issues. gonna see what other options are out there. – MizAkita Oct 04 '13 at 23:51
  • Sorry, it should be `$valuesToAdd = substr($valuesToAdd, 0, strlen($valuesToAdd)-1);` – Alejandro Iván Oct 05 '13 at 03:03
0
$fname = $_POST['firstname'];
$lname = $_POST['lastname'];

$sets = array();

if(trim($fname)) {
  $sets[] = "first = '".mysql_real_escape_string($fname)."'";
}
if(trim($lname)) {
  $sets[] = "last = '".mysql_real_escape_string($lname)."'";
}

if($sets) {
  $sql = "UPDATE profile SET ".implode(", ", $sets)." WHERE id='".mysql_real_escape_string($id)."'";
}

Remember to properly escape your values before you glue them to SQL.

Kamil Szot
  • 17,436
  • 6
  • 62
  • 65
  • what exactly does this do? – MizAkita Oct 04 '13 at 23:25
  • @MizAkita Takes values that came from browser in POST. If they are not empty, escapes them and attaches them to database field names. Then merges them into single query. Basically, what you wanted to do but without vulnerability to SQL injection. – Kamil Szot Oct 13 '13 at 18:25
-1

You need form validation. Easy solution will not allow empty fields save in db and prevent SQL-injections.

Easy solution:

$fname = isset($_POST['firstname']) and nameIsValid($_POST['firstname'])
    ? $_POST['firstname'] : false;
$lname = isset($_POST['lastname']) and nameIsValid($_POST['lastname'])
    ? $_POST['lastname'] : false;

if (false === $fname or false === $lname) {
    // report about not valid form fields
} else {
    $dsn = 'mysql:dbname=yourdb;host=yourhost;charset=utf8';
    $dbh = new PDO($dsn, 'user', 'pass');
    $sql = "UPDATE profile SET first = :fname, last = :lname WHERE id = :id";

    $stmt = $dbh->prepare($sql);
    $stmt->execute(array(':fname' => $value, ':lname' => $lname, ':id' => $id));
}

/**
 * Validation names for empty values
 *
 * @param string $name First name or last name
 * @return bool
 */
function nameIsValid($name) {
    return '' !== $name;
}

But be aware of XSS-injection. For example somebody can save in your db Fist name:

<script>alert('Woohoo! You have vulnerability!');</script>

And next time, when you print First name of the user, everyone will see message about vulnerability :)

You may decide implement more strict validation rules, which will not allow names like "asfyua23807*^2#", "-2*&%$9837239askHF" or XSS-injections. In this case you should modify nameIsValid() function.

Safe solution:

/**
 * Validation names and prevent XSS-injections
 *
 * @param string $name First name or last name
 * @return bool
 */
function nameIsValid($name) {
    $pattern = '/^[\.a-z-]+$/i';
    return (bool) preg_match($pattern, $name);
}

This logic allow names containing A-z . - symbols: J.Jameson, Jackson-Piterson, JOHn, smIth, etc. For more strict validation rules check Official PHP Regular Expressions manual.

Community
  • 1
  • 1
Alexander Yancharuk
  • 13,817
  • 5
  • 55
  • 55
  • And what if user's name contains german, chinese, russian characters? Then surely your function `nameIsValid()` would **lie** to you. – Yang Oct 06 '13 at 05:31
  • Also, `nameIsValid()` does not prevent XSS since it does only `preg_macth()`. If it were `preg_replace()`, then that description would make sense. – Yang Oct 06 '13 at 05:32
  • @DaveJust in couple with proposed logic, YES, this prevent XSS. For german, chinese, russian characters just modify `$pattern` as i noted in my answer: "For more strict validation rules check Official PHP Regular Expressions manual." – Alexander Yancharuk Oct 06 '13 at 07:10
  • @DaveJust Also, i sad that `$pattern` allow names containing A-z . - symbols. The questioner doesn't said something about german or russian names. – Alexander Yancharuk Oct 06 '13 at 07:17
  • So, how do you know where your user comes from? He could come from anywhere and his name could contain foreign characters, like `Ü, ß`. **So what's the point?** So, if his name contains, say `ß`, then `nameIsValid()` will return `FALSE`, even if his name is valid. You say that `$pattern` should be modified. Okay, then should it be modified for all languages? **That's a bad solution**. Instead, a black list of characters should be defined and each time you should check if that string contain bad characters. – Yang Oct 06 '13 at 07:23
  • To prevent XSS, something like `htmlentities()` would be great enough on data outputing. – Yang Oct 06 '13 at 07:25
  • @DaveJust "He could come from anywhere". Hmm.. How do you know this? You see this in question? Can you point me exactly where you found that? May be questioner don't want names like `Üßsaldj`. This is another question **how to validate unicode characters in forms**. – Alexander Yancharuk Oct 06 '13 at 07:45
  • Yes, this could be another question. But I'm critiquing your **solution**, because **it will be so easy to break** your validation. If you want to test whether name is valid, check 1) its length (max and min) 2) If it does not contain **undesired** characters. Because you're testing characters to find out if they meet your requirements. `preg_match('/^[\.a-z-]+$/i', $name)` is purely bad solution. If you don't believe me, then see how a validation layer is implemented in `ZF2` against values like `$name`. The problem again - you're looking only **for desired characters** when approaching names – Yang Oct 06 '13 at 07:53
  • @DaveJust i can accept your point only if questioner will update question for unicode names requirements. Then i'll update solution to unicode variant. But she can update requirements to ASCII names. So, your talk about "bad solution" is pointless. – Alexander Yancharuk Oct 06 '13 at 08:05