Yes, $wpdb->update is sufficient protection. You should not escape or prepare the data.
From the documentation of wpdb:
data (array) Data to update (in column => value pairs). Both $data
columns and $data values should be “raw” (neither should be SQL
escaped). This means that if you are using GET or POST data you may
need to use stripslashes() to avoid slashes ending up in the database.
As a side note, you can help wordpress better understand the content to prepare for the database by including format and where_format in your update call.
$uptable = $mydb->update(
'table',
$updatevalues,
$where_data,
$data_format, // '%d' for numbers, '%s' for strings, can be an array
$where_format // Same here
);
Update: In reply to your comment:
It depends on the data you are saving and its purpose.
Your next step after SQL injection is to prevent XSS attacks. This is where a user is able to enter malicious Javascript into your text field, and the database saves it and then your site happens to display it to other users.
While this can be prevented by using esc_html() when displaying the content from the database, it’s better not to have that stuff in the database in the first place!
- If you are saving a simple string, such as a name, or address, use
sanitize_text_field(). - If you are saving HTML, such as text from a text editor, use
wp_kpses() - If you are saving something that needs to be used in an URL, use
sanitize_title() - Here’s more info on them. (That whole article is very good)
- To include your link, the page of all Data Validation types
As for the code to do this, it would look like this:
$user_value = stripslashes($_POST['user_value']);
$user_value = sanitize_text_field($user_value);
$user_data = array('table_column' => $user_value);
$user_format = array('%s'); // Means $user_value is a string
$where_data = array('id' => 5); // example
$where_format = array('%d'); // Means 'id' is a number
$mydb->update(
'table',
$user_data,
$where_data,
$user_format,
$where_format
);
And if you only want that data to be alpha numeric, you could wrap the code after stripslashes with if(ctype_alnum($user_value)). Ultimately you only want the exact data you need and nothing more.
Hope that helps!