codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.28k stars 1.88k forks source link

Bug: TypeError in pg_ping() #9043

Open warcooft opened 1 month ago

warcooft commented 1 month ago

PHP Version

8.3

CodeIgniter4 Version

4.5.3

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

macOS

Which server did you use?

apache

Database

PostgreSQL 16.3

What happened?

pg_ping() expects the first parameter to be a PostgreSQL connection (or null), but receives the boolean value false.

See also https://github.com/codeigniter4/queue/issues/45#issue-2401691847

This is a blocker for other packages.

Screenshot 2024-07-11 at 05 47 49

Steps to Reproduce

$db = db_connect();
d($db->connect());
d($db->close());
d($db->reconnect());
d($db->getDatabase());
d($db->getVersion());
dd();

Expected Output

The output should show the db name and db driver version.

Anything else?

No response

warcooft commented 1 month ago

it looks like the close() function also doesn't work when using the PostgresSQL driver:

Screenshot 2024-07-11 at 07 24 15

  this when using MySQL:

Screenshot 2024-07-11 at 07 25 22

Steps to Reproduce

$db = db_connect();
d($db);
// d($db->connect());
d($db->close());
// d($db->reconnect());
d($db->getPlatform());
d($db->getVersion());
dd();
warcooft commented 1 month ago

and both connections cannot be closed if before closing we run connect() as follows:

$db = db_connect();
d($db);
d($db->connect());
d($db->close());
// d($db->reconnect());
d($db->getPlatform());
d($db->getVersion());
dd();
paulbalandan commented 4 weeks ago

I can reproduce the TypeError in the original issue.

paulbalandan commented 4 weeks ago

Dumb question: if you call reconnect() on a closed DB connection, should you initialize again? In the Postgres driver, you only call pg_ping() which just pings the connection if still active and tries to reconnect if broken. For MySQL driver, it explicitly closes then reinitializes the connection. Clearly a difference in behaviors, I suppose.

warcooft commented 4 weeks ago

For MySQL driver, it explicitly closes then reinitializes the connection. Clearly a difference in behaviors.

I'm not sure if the way used to produce the error above is correct. I think both have the same behavior. thankyou for enlighten me.

kenjis commented 3 weeks ago

The behavior of reconnect() is to keep the connection alive or re-establish it.

If the database server’s idle timeout is exceeded while you’re doing some heavy PHP lifting (processing an image, for instance), you should consider pinging the server by using the reconnect() method before sending further queries, which can gracefully keep the connection alive or re-establish it. https://codeigniter4.github.io/CodeIgniter4/database/connecting.html#reconnecting-keeping-the-connection-alive

So if there is a ping method in the DB module, we should use it.

But in MySQL, ping() is no longer working. See #462

warcooft commented 3 weeks ago

That helps! thanks for explaining.