8

i want to check if a variable from $_POST is empty and INSERT a NULL to my Database.

But when I do it my way i always get a String called NULL and not a real NULL in my data set.
This is how I tried it:

if(isset($_POST['folge'])){
    $comment = !empty($_POST['comment']) ? "'".$_POST['comment']."'" : null;

    $sqlstring = "INSERT INTO eventstest (comment) VALUES (".$comment.")";
    echo $sqlstring;
    if ($mysqli->query($sqlstring) === TRUE) {
      printf("Table myCity successfully created.\n");
    }else{
      printf("Errorcode: %d\n", $mysqli->errno);
        printf("Error: %d\n", $mysqli->error);
    }

if I send the form without making inputs to "comment" page output is:

INSERT INTO eventstest (comment) VALUES ()Errorcode: 1136 Error: 0

Whats wrong? Or whats the better way to check for empty inputs and add NULL to DB?

PS: The database cell has STANDARD: NULL

pfmd86
  • 81
  • 1
  • 1
  • 5

2 Answers2

21

If you want to insert a NULL value into MySQL, you have to pass a null-value in the SQL query, not the string of null. It will still be a string from a PHP perspective, but not from the MySQL perspective.

if (!empty($_POST['comment'])) {
    $comment = "'".$mysqli->real_escape_string($_POST['comment'])."'";
} else {
    $comment = "NULL";
}

You can also shorten that into a one-liner, using a ternary operator

$comment = !empty($_POST['comment']) ? "'".$mysqli->real_escape_string($_POST['comment'])."'" : "NULL";

Then, because you assign the quotes around the comment-string itself, as you should do, since you alternatively want to pass a null-value, you need to remove the single quotes surrounding the variable from the query. This would otherwise break it too, as you'd get ''comment''.

$sql = "INSERT INTO table (comment) VALUES (".$comment.")";

Of course this assumes that the column comment allows for null-values. Otherwise it will fail, in which case you should either insert empty strings or change the column to accept null values.


It should also be noted that this query is exposed to SQL injection attacks, and you should use an API that supports prepared statements - such as PDO or MySQLi, and utilize those to secure your database against these kinds of attacks. Using a prepared statement with MySQLi would look something like this. See how we supply a PHP null to the value in bind_param() if $_POST['comment'] is empty.

// Set MySQLi to throw exceptions on errors, thereby removing the need to individually check every query
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

if (isset($_POST['folge'])) {
    // $comment = !empty($_POST['comment']) ? $_POST['comment'] : null; // Ternary operator
    $comment = $_POST['comment'] ?? null; // Null coalescing operator, since PHP 7

    $sql = "INSERT INTO eventstest (comment) VALUES (?)";
    $stmt = $mysqli->prepare($sql);
    $stmt->bind_param("s", $comment);
    $stmt->execute();
    $stmt->close();
}
Qirel
  • 25,449
  • 7
  • 45
  • 62
  • The other option is ternary operator inside ``$sql = "INSERT INTO table (comment) VALUES (".$comment.")";`` – Sylogista May 07 '17 at 12:09
  • What do you mean by ternary operator inside the `$sql` variable..? – Qirel May 07 '17 at 12:11
  • Yeah. I don't like ternary operator because of bad looking, but yes – that's what I'm talking about ;) – Sylogista May 07 '17 at 12:12
  • 1
    Well, that's opinionated. They aren't that hard to read, but again - it's really up to what you prefer. At least its shown as an example, then OP can choose which one he likes best ;-) – Qirel May 07 '17 at 12:18
  • I did it that way. When my comment hast content everything works fine. But if comment is empty i get errno 1136 from mysql back... – pfmd86 May 08 '17 at 11:13
  • Can you update your question with your current code, as an edit? That error indicates that the amount of columns specified, and the numbers of values provided, doesn't match - so its possible there are some quote-missmatch or something, hard to say without seeing the code. – Qirel May 08 '17 at 11:24
  • Ah yeah, the `NULL` needs to be `NULL` from a MySQL perspective, but still pass it as a string from PHP. Otherwise it would simply be nothing there. That should do it. I should've seen that before :p – Qirel May 08 '17 at 13:15
  • Works fine now! Thanks for support. I will try to rebuild to secure prepare version now with the linked article [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) – pfmd86 May 08 '17 at 13:26
  • Worth noting you can bind `null` as an integer or double as well. – tagurit Jul 05 '19 at 22:32
  • I tested. If default for mysql table is NULL and i insert `$comment = "NULL";`, i will see `0` in mysql table. To see `NULL` i must insert $comment = NULL; – user2360831 Sep 17 '19 at 07:12
  • Depends entirely if you're using a prepared statement or not - and if not, then it matters if the string is quoted or not. Doing `$comment = "NULL"` will be `NULL` (and not the string null) in MySQL if its not quoted in a non-prepared statement. – Qirel Sep 17 '19 at 07:36
  • this isn't working in MySQL 5.7+ it shows 'NULL' which is an SQL syntax error – Md Emrul Easir Jun 30 '20 at 11:44
  • Then you are doing something different. Without seeing the code you are posting its hard to say what that is, but my first guess is that either your code is different, or you are trying to insert "null" (as a string-value) from a form (which will be a string). I'd however recommend using the latter of the two alternatives, as that is vastly more secure. – Qirel Jun 30 '20 at 16:27
1

Several things wrong here. First is that you are using string concatenation instead of prepared statements. This leaves you open to SQL injection. I suggest you stop this project right now and return after learning to use PDO and prepared statements.

Secondly, 'NULL' != null you need to specify it as null

Last but not least, generally there isn't a need to explicitly check for null in postvars and then pass a null again. If the column type allows null and you do not pass in a non null value. null will be stored in it anyway

e4c5
  • 52,766
  • 11
  • 101
  • 134
  • I know about that. But at the moment I am far away from productive enviroment. But I will change to prepared statements as soon as i know my project works as i imagine. – pfmd86 May 08 '17 at 11:16
  • If you already know about it you should know that it's more than 3x effort make that change later on – e4c5 May 08 '17 at 11:19