How do I make sure that values from MySQL keep their type in PHP?

What exactly do I do to get my MySQL functions in PHP to give me the MySQL results in their native type?

You connect to the database, then you prepare your query, execute it, bind the result and then you fetch it.

Let's do these steps line-by-line:

$conn = new Mysqli('localhost', 'testuser', 'test', 'test');
$stmt = $conn->prepare("SELECT id FROM config LIMIT 1");
$stmt->execute();
$stmt->bind_result($id);
$stmt->fetch();
var_dump($id); # it's an int!

This works for me. As you wrote your code is more complex, you will need to locate the place where you query the database. Check that you're using Mysqli::prepare() and if not, introduce it.

You will also need to use Mysqli_Stmt::execute() and then Mysqli_Stmt::bind_result() otherwise the (here integer) type is not preserved for that result column.


However, my values are still being returned as strings.

You are in PHP, where it does not matter that your data are int, bool, strings... if they have such a type they are called scalar data and dynamic castings will allow you to make them behave as you want. For example, the string "12345"+"54321" will give you 66666. If you absolutely want your data to be of a particular type, as in every language, it is not the driver's job. In Java you've got something like .getString, .getInt methods in JDBC's interfaces, in PHP you do not have as it is not very useful. You will have to cast yourself your data with intval boolval strval... functions or (int), (bool)... casting operators.

As your post said you can have it by using server-side prepared statement:

Advantages of using mysqlnd for PDO

mysqlnd returns native data types when using Server-side Prepared Statements, for example an INT column is returned as an integer variable not as a string. That means fewer data conversions internally.

With PDO

You have to put this line after your connection

$PDO->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);

then, when you want to query :

$s = $PDO->prepare('yourquery');
//here, binding params
$s->bindValue('paramName','paramValue');
$s->execute();

With Mysqli

As you use mysqli, the syntax will be a little different : Note: there is no way of client-side prepared statement so you won't need the configuration line that I put with PDO.

So your query will look like that:

$statement = $MySQli->prepare('your query');
$statement->bind_param('si', $stringParam, $intParam);
$statement->bind_result($var1, $var2 /*,...*/);
$statement->execute();
while($statement->fetch()){
  //process here, result will be in var1, var2...
}

You can see that, here, there is no built-in fetchAll method. To bind your data you need to use variables as it is not passed as value like in PDOStatement::bindValue() but by reference. Moreover the types are defined in the first arg (s for string, i for integer...) There are no named parameters only indexed ones. The fetch method works in a different way and needs you to call bind_result BEFORE the execute statement;