0

I have a form and I let users type some additional details for the form. What if the user enters a text mixed with single and double quotes.

ex:- I'd like to join. So we"are party"this"time'addtional'details`willbe"

I found out that, because of this text, nothing goes into the database. It means literally this thing crashes my whole program.

How do I enter it into the database using PHP or MySQL query?

I've tried these methods

  • Backslashes (')

  • JSON encode

  • str_repalce

  • htmlspecialchars with ENT_QUOTES

But nothing works for me!

  • you did not escape properly... all the methods you mention are useless for a database context. – Honk der Hase Apr 03 '22 at 09:23
  • Then how should I do it for a database? – Паван Викаситха Apr 03 '22 at 09:25
  • Use prepared statements and pass the value as-is - the database driver will do the proper escaping. – Honk der Hase Apr 03 '22 at 09:36
  • ``htmlentities()`` should work though you should rely on pdo or bind param techniques. – OMi Shah Apr 03 '22 at 09:40
  • `htmlentities()` and similar has _nothing_ to do with databases and should not be used in cases like this. Those are for completely different use cases and using them will give you a false sense of security (since you will still be vulnerable). They can also mess up your data since they encode the data for different reasons. – M. Eriksson Apr 03 '22 at 10:29

2 Answers2

1

Just use prepared statements. https://www.php.net/manual/en/pdo.prepare.php this should help with all your escape problems, also offers protection for sql injection

1

ATTENTION! You should really be using parameterized queries along with prepared statements, using either MySQLi or PDO! Otherwise, you're opening yourself up to SQL Injection (SQLI) attacks! Another good reason, is that you don't have to worry about escaping your input(s) anymore. The MySQLi/PDO implementation will handle this for you.

I will move forward with MySQLi in my example. Whichever you end up choosing is completely up to what you prefer at the end of the day.

<?php
// Error handling
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

/*!
 * MySQLI Server Connection
 * The DBHOST, DBUSEr, DBPASS, DBNAME,
 * are define variables. Make your own.
!*/

$conn = new mysqli(DBHOST, DBUSER, DBPASS, DBNAME);

// Language of the server
mysqli_query($conn, "SET character_set_results=utf8");
mb_language('uni'); 
mb_internal_encoding('UTF-8');
mysqli_query($conn, "set names 'utf8'");

// Function to check if connection is alive
function checkConnection($conn) {
    if ($conn->ping()) {
        printf ("Our connection is ok!\n");
    } else {
        printf ("Error: %s\n", $conn->error);
    }
}

/*!
 * Prevents the statement from auto commiting.
 * For this particular use case, you can ignore it.
 * You don't have to use it.
 * However, in case you're going to work with multiple statements,
 * parsing data over etc., I wanted to showcase it.
 * It's one of the simple steps to try and negate incomplete datasets
 * and loss.
!*/

$conn->autocommit(FALSE);

/*!
 * table is your table name,
 * column is the column name.
!*/

$sql = "INSERT INTO table SET column = ?";
$stmt = $conn->prepare($sql);

/*!
 * the 's' argument here indicates that
 * the insert variable is a string type.
 * There are of course multiple types,
 * and you can look them up.
 * You chain them like so:
 * $stmt->bind_param('iss', $value1, $value2, $value3);
 * In the example above, we are expecting int, string, string.
 * so $value1 is an int, $value2 is a string, $value3 is another string.
 * The params are handled chronologically!
 * Back to the actual example again:
 * $value is is your post variable
 * (i.e. the string you want to insert).
!*/

// bind the param(s), there's only one in this case.
$stmt->bind_param('s', $value);
// execute the query.
$stmt->execute();
// only include this if you set the auto commit to be false.
$conn->commit();
// closing the connection again.
$stmt->close();
$conn->close();
?>

Ideally, you'll split the database and connection setup into another file called maybe dbconnect.php and have the SQL logic be in a function, or handled in some other, separate logic, using include to include the datbase connection logic.

Martin
  • 2,326
  • 1
  • 12
  • 22
  • Thank you for spelling out an implementation. Any particular reason why `autocommit` and `commit` are needed here? _Connection logic would be easily usable anywhere if put into an autoloading class_. Unless only one DB is ever used, a property would be more versatile than a constant for the connection statement. My basic DB class takes array of arguments, with constants for host, user and password set as defaults if no specific arguments are provided. (In a dev environment with multiple projects one rarely bothers with lots of users, but the database is frequently different.) – Markus AO Apr 03 '22 at 18:41
  • 1
    @MarkusAO for this particular use case alone, no autocommit and commit are not necessary at all. It's incredibly overkill. My initial idea was to show as much as possible (even if the setting was tiny and isolated). I added extra comments to the code to address your question. – Martin Apr 03 '22 at 21:25