php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #54572 default ini values are not used when constructing new mysqli()
Submitted: 2011-04-20 01:21 UTC Modified: 2011-04-20 06:09 UTC
From: marcos at generic dot cx Assigned:
Status: Not a bug Package: MySQLi related
PHP Version: 5.3.6 OS: MacOS
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: marcos at generic dot cx
New email:
PHP Version: OS:

 

 [2011-04-20 01:21 UTC] marcos at generic dot cx
Description:
------------
---
From manual page: http://www.php.net/mysqli.connect#Description
---

The documentation says:
mysqli::__construct() ([ string $host = ini_get("mysqli.default_host") [, string 
$username = ini_get("mysqli.default_user") [, string $passwd = 
ini_get("mysqli.default_pw") [, string $dbname = "" [, int $port = 
ini_get("mysqli.default_port") [, string $socket = 
ini_get("mysqli.default_socket") ]]]]]] )

this implies that you can set these values via ini_set() and instantiate a new 
mysqli() with no arguments, but this does not actually work.

This is similar to http://bugs.php.net/bug.php?id=38998&edit=2 except that case 
revolved around passing null to the constructor.

The documentation says: "If not provided or NULL, the MySQL server will attempt 
to authenticate the user against those user records which have no password only. 
This allows one username to be used with different permissions (depending on if 
a password as provided or not)." but this is inconsistent with the constructor 
signature which implies that these values are auto-populated from the ini 
values. 

If the ini parameters serve no purpose in an empty constructor invocation, then 
the documentation signature should be updated to reflect that the 
mysql.default_* ini values have no effect (or are overridden by the behavior 
that follows). i.e. the signature should read 

mysqli::__construct() ([ string $host = "localhost" [, string 
$username = ini_get("mysqli.default_user") [, string $passwd = 
"" [, string $dbname = "" [, int $port = 
ini_get("mysqli.default_port") [, string $socket = 
ini_get("mysqli.default_socket") ]]]]]] )

which implies a very different behavior.

Test script:
---------------
ini_set("mysqli.default_host", "localhost");
ini_set("mysqli.default_user", "jack");
ini_set("mysqli.default_pw", "florey");

$sadmysqli   = new mysqli();
$happymysqli = new mysqli(ini_get("mysqli.default_host"), ini_get("mysqli.default_user"), ini_get("mysqli.default_pw"));

print_r($sadmysqli->host_info); 
// ERROR: DB::__construct() [<a href='db.--construct'>db.--construct</a>]: Property access is not allowed yet

print_r($happymysqli->host_info); 
// Localhost via UNIX socket

Expected result:
----------------
the result for both print_r statements should be equivalent. this makes it seem as 
if the default ini values for the constructor are not actually being used when 
calling the constructor

Actual result:
--------------
see above, namely DB::__construct() [<a href='db.--construct'>db.--construct</a>]: 
Property access is not allowed yet

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-04-20 05:11 UTC] dtajchreber@php.net
-Status: Open +Status: Bogus
 [2011-04-20 05:11 UTC] dtajchreber@php.net
You need a $sadmysqli->real_connect(); after creating the object. Mind the note 
on the page: "Calling the constructor with no parameters is the same as calling 
mysqli_init()." Add the real_connect() call and you can ini_set the mysqli ini 
settings as much as your little heart desires and it'll work as expected: 

[david@oslo:~]$ mysql -u root -p
Enter password: 

mysql> use php;
Database changed
mysql> select * from test;
+--------+-------+------------+
| idtest | fname | lname      |
+--------+-------+------------+
|      0 | david | tajchreber |
+--------+-------+------------+
1 row in set (0.00 sec)

mysql> exit
Bye
[david@oslo:~]$ cat t.php 
<?php 

error_reporting(E_ALL | E_STRICT);

ini_set('mysqli.default_host', 'localhost');
ini_set('mysqli.default_socket', '/var/run/mysqld/mysqld.sock');
ini_set('mysqli.default_user', 'root');
ini_set('mysqli.default_pw', 'root');

$m = new MySQLi();
var_dump($m->real_connect());
var_dump($m->ping());
var_dump($m->select_db('php'));
var_dump($m->query('select * from test;', MYSQLI_USE_RESULT)->fetch_all());

[david@oslo:~]$ php t.php 
bool(true)
bool(true)
bool(true)
array(1) {
  [0]=>
  array(3) {
    [0]=>
    string(1) "0"
    [1]=>
    string(5) "david"
    [2]=>
    string(10) "tajchreber"
  }
}
 [2011-04-20 06:09 UTC] marcos at generic dot cx
the problem is that the documentation is ambiguous (or disingenuous) in the method 
signature, not that it's possible to use mysql_real_connect to remedy this.

It's a notation issue: the signature implies that missing arguments are substituted with 
the defaults, but if this is not the case, then you can at least fix this by implying that 
either the host argument is required or the constructor will only initialize a connection 
rather than opening one.


The problem is basically this: 

    float pow($x [, $exp=1])

but then saying 

    if $exp is not specified, the return value may not be a float.

of course this is a ridiculous example, but it's also easily fixed by changing either the 
signature to read:

    mixed pow($x [, $exp=1])
or
    float pow($x, $exp)

but the original example is disingenuous because either the type is incorrect or the second 
argument is not really optional. 


In this *exact way* it's disingenuous to imply that the default values are optional when in 
reality they are required to open a connection.

This could be fixed in the documentation by changing the line

    "Opens a connection to the MySQL Server running on."

to read 

    "Opens a connection to a MySQL Server or initializes a MYSQL object suitable for 
mysqli_options() and mysqli_real_connect() if no arguments are passed to the constructor"

because this effectively sums up the behavior of the constructor. Otherwise, the 
implication is that calling this function in *any* way will open a connection (rather than 
*potentially* opening one or even just *initializing* one.)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 14:01:28 2024 UTC