I had the same error in Drupal 7.56:
mysqli_real_escape_string()
expects parameter 1 to be mysqli
, null
given ...
Exactly on line 1282 of the new civicrm/install/index.php
, which is different from CiviCRM 4.7.20's index.php
. So I just replaced the new file by the old one and all the checks became green and the installation proceeded normally (Drupal and CiviCRM share the same DB). CiviCRM is working fine.
Edit: after investigating...
I compared both versions install/index.php
files and there is actually a new function that replaces all the connections to MySQL that were made previously and directly through mysqli_connect($server, $username, $password)
.
This is the new function:
protected function connect($host, $username, $password, $database = '') {
$hostParts = explode(':', $host);
if (count($hostParts) > 1 && strrpos($host, ']') !== strlen($host) - 1) {
$port = array_pop($hostParts);
$host = implode(':', $hostParts);
}
else {
$port = '';
}
$conn = @mysqli_connect($host, $username, $password, $database, $port);
return $conn;
}
This function does not add or alter procedures in the installation process. It is basically a verification and treatment of the $server
variable passed as parameter ($host
). What it does:
- Does the
$server
/$host
string contains a port?
- if YES than:
- pop it out from the string and place it under the
$port
variable;
- replace the original
$host
string by a new string without the port.
- if NO than:
- assign an empty string to
$port
.
Establish a connection with the "new" separated parameters like so:
@mysqli_connect($host, $username, $password, $database, $port)
If you notice, the difference from the old version is just one: 2 more parameters provided to mysqli_connect
, in order to support websites running in different ports.
Which means, for all connections without a specific port (most cases), replacing index.php
of version 4.7.21 with the one from version 4.7.20 will work (here's a pastebin with the old index.php
).
How to fix it in version 4.7.21
The problem does not lie in the connect
function parameters treatment, but in the $port
value, which if it becomes an empty string mysqli's result will be null
. Also the $database
value is always empty.
These can be fixed either by:
- adding the proper value to
$database
when connect
is invoked
- providing a valid value for
$port
(not an empty string)
Quickfix (2.)
Do not allow the $port
to become an empty string, i.e. replace only this line in the install/index.php@connect
:
$port = '';
By this line:
$port = NULL;
This will prevent mysqli_connect
result to be null
.
I have tested this in a new installation and it works.
Proper fix (1.):
For making use of the $database
parameter, these lines:
$this->conn = $this->connect($server, $username, $password);
Must be replaced with:
$this->conn = $this->connect($server, $username, $password, $database);
These include lines 1040, 1075, 1105, 1145, 1226, 1270 and 1409.
For the remaining lines (978 and 1192 where the connect
is invoked), since there is no available database name value, we need to add to the respective functions the $database
parameter, i.e.:
- For
requiredMysqlConnection
:
- replace with
public function requireMysqlConnection($server, $username, $password, $database, $testDetails) {
- replace with
$this->conn = $this->connect($server, $username, $password, $database);
- line 445 (after
$databaseConfig['password'],
) add a new line with $databaseConfig['database'],
($dbName
should not be used since it only contains a default value like 'CiviCRM'
)
- For
requireMySQLAutoIncrementIncrementOne
:
- replace with
public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $database, $testDetails) {
- replace with
$conn = $this->connect($server, $username, $password, $database);
- line 465 (after
$databaseConfig['password'],
) add a new line with $databaseConfig['database'],
($dbName
should not be used since it only contains a default value like 'CiviCRM'
)
This handles empty $database
values. However, if $port
is actually an empty string, mysqli_connect
will also return null
. Therefore, the line mentioned in the previous Quickfix (2.) should also be changed.
I have tested this fix and it worked as well. If you have any suggestions/improvements, please comment below and I'll edit.