php / php-src

The PHP Interpreter
https://www.php.net
Other
37.94k stars 7.72k forks source link

Problem with mysqli_options and persistent connections in mysqli. #7808

Open Provoker opened 2 years ago

Provoker commented 2 years ago

Description

According to the documentation https://www.php.net/manual/en/mysqli.options.php mysqli_options() should be called after mysqli_init() and before mysqli_real_connect().

But, when using persistent connections and the connection in the pool is broken, when creating a new connection, the MYSQLI_OPT_INT_AND_FLOAT_NATIVE option is lost.

Setting the option AFTER calling real_connect solves the problem

The following code:

<?php
\mysqli_report(MYSQLI_REPORT_ERROR);
function connect(): mysqli {
    $mysqli = mysqli_init();
    $mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
    $mysqli->real_connect('p:127.0.0.1', 'user', 'password');

    return $mysqli;
}

$mysqli1 = connect();
var_dump($mysqli1->query("SELECT 1")->fetch_row()[0]); // int
@$mysqli1->query("KILL {$mysqli1->thread_id}");
unset($mysqli1);

$mysqli2 = connect();
var_dump($mysqli2->query("SELECT 2")->fetch_row()[0]); // string, but int is expected

// next ok
$mysqli2->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
var_dump($mysqli2->query("SELECT 3")->fetch_row()[0]); // int

Resulted in this output:

int(1)
string(1) "2"
int(3)

But I expected this output instead:

int(1)
int(2)
int(3)

PHP Version

PHP 8.0.14, 8.1.1

Operating System

Debian 9.13, Ubuntu 21.10

cmb69 commented 2 years ago

Yeah, right. See also https://bugs.php.net/bug.php?id=74967, where this issue has been reported, and analyzed.