For data values you should certainly use prepared statements and query parameters. For example, your $pick1
and $player
values fall into this category. To learn about prepared statements, this is a great place to start.
However, that's not really what you're asking. You're asking about using variables for schema objects (column names, table names, etc.) instead of data values. Those can not be handled by query parameters.
The good news is that you can use a variable to do exactly what you're trying to do. For example:
$query = "UPDATE Table1 SET Col_{$someVar}_X = ?";
This is just interpolating a value into a string like any other string in PHP.
But then, given concerns about SQL injection, the real question becomes:
Where does $someVar
come from?
It should never come from user input. Fortunately, while data values can be anything under the sun, schema objects are finite and known ahead of time. So you can take a simple whitelist approach. When the logic is being processed, you can have a list of all possible valid values for $someVar
. (Either hard-coded or generated from the database schema.)
Then you can compare any input value with the values in that list. If there's no match, return an error. If there is a match, use the matched value from the list. That way you're only ever using known safe values, which is no different than using a literal string.
After all, while this may set off some SQL injection alarms at first glance:
$query = "UPDATE Table1 SET Col_{$someVar}_X = ?";
The context of those alarms is a bit different if you know where the value is coming from:
$someVar = "123";
$query = "UPDATE Table1 SET Col_{$someVar}_X = ?";
SQL injection is not about always using prepared statements as a magic wand. It's about always controlling the SQL code your application executes, wherever that code comes from. As long as you control the code and the user doesn't, you're okay.