Innovate faster and cut risk with PHP experts from Zend Services.
Explore Services
See How Zend Helps Leading Hosting Providers Keep Their Managed Sites on Secure PHP
Read More
Learn PHP from PHP experts with free, on-demand, and instructor led courses.
Explore Training
Submit support requests and browse self-service resources.
Explore Support
This one looks straightforward, but is actually one of the most complicated changes. Depending on the application, it can be a non-issue or the biggest hurdle.
The mysqli_connect function no longer returns a resource but rather a mysqli object, which needs to be passed around in the application. The original application might not have been passing the resource object and instead relying on mysql_ functions to access the last connection internally.
mysqli_connect
resource
mysqli
mysql_
With mysqli, this means that we would need to store these connections in a centralized location, as that would most closely mimic the mysql_connect behavior. For example, we could create a class named MysqlToMysqli and store the mysqli objects in a static property.
mysql_connect
MysqlToMysqli
If we make a second call with the same arguments, mysql_connect won't connect again, but will instead return the existing connection (link). We can override this behavior by passing true as the fourth argument, which will then always create a new link. In this example that reuses the link, both references are strictly equal and can be used interchangeably.
true
$mysql1 = mysql_connect('host', 'user', 'pass'); $mysql2 = mysql_connect('host', 'user', 'pass'); // $mysql1 === $mysql2;
The mysqli_connect function, on the other hand, always creates a new link and there is no way to override this.
$mysqli1 = mysqli_connect('host', 'user', 'pass'); $mysqli2 = mysqli_connect('host', 'user', 'pass'); // $mysqli1 !== $mysqli2;
If we want to maintain the behavior of the mysql extension while using mysqli, we could maintain a list of connections indexed by the provided arguments. This only applies to cases where mysql_connect did not receive the new_link argument, or received a value of false.
mysql
new_link
false
$args = json_encode(func_get_args()); self::$mysqliLinks[$args] = mysqli_connect($host, $user, $pass);
In addition to reusing connection objects, the mysql extension cares about how many references we have to that connection object. This has an impact when we attempt to close a connection using mysql_close.
mysql_close
Let's say we open a connection using the same arguments twice, and store both connection references.
$mysql1 = mysql_connect('host', 'user', 'pass'); $mysql2 = mysql_connect('host', 'user', 'pass');
If we were to close $mysql1 and use it later anyway, it would still work. This is because we had two references to the same connection, which means that mysql_close merely decremented an internal counter, and did not really close the connection.
$mysql1
mysql_close($mysql1); mysql_query('show tables', $mysql1);
If we were to close it a second time using the exact same variable name, it would fail with a warning:
mysql_close($mysql1); mysql_close($mysql1); mysql_query('show tables', $mysql1); // mysql_query(): 5 is not a valid MySQL-Link resource
It doesn't even matter which of the two references we close and in what order. We need to call mysql_close as many times as we stored the output of mysql_connect (receiving the same arguments).
The existing application may be calling mysql_close, but then still use that connection object later on. With mysqli_close, our connection will always close, so subsequent calls using that connection object would start failing. This can cause the application to crash unexpectedly.
mysqli_close
If your application does not have explicit mysql_close calls, then this problem shouldn't affect you.
The code can be refactored to adapt to the mysqli_close behavior, but that is very risky and is usually very costly. We don't recommend attempting this unless the application has extensive acceptance tests.
Here is the approach that allowed us to permanently solve the problem on very large codebases:
Increase security and cut risk by simplifying PHP application upgrades and migrations.
Long Term Support buys organizations time to migrate.