Short answer: I wanted this idea to be as short as 1 line of code:
$stmt = $PDO->query( "SELECT * FROM my_table" );
$rows = (int) $PDO->query('SELECT FOUND_ROWS()')->fetchColumn();
- use
SELECT FOUND_ROWS()
, then fetchColumn()
, then class it as an (int)
TLDR Version:
Since PHP8 I have just been using rowCount()
with impunity, no problems. Then when working on a stack of WP updates across other peoples servers I find rowCount()
failing to return the proper number of rows
Of course, I google it and find a decades long debate. I did not like most answers, so I read the documentation https://www.php.net/manual/en/pdostatement.rowcount.php
According to docs DELETE
, INSERT
, or UPDATE
work with
rowCount()
, but even on the PHP.NET examples page as far back as 11
years ago folks have been wrestling with the best/easiest way to just
count the result.
After testing about 20 answers (stackOverflow to Php.net) the final script [below] worked best to patch 32 WP sites across 20 different servers, 5 hosts and several versions of PHP ranging from 7.4 to 8.1 (GoDaddy, Bluehost, WPengine, InMotion, Amazon AWS Lightsail)
Note that $opts
turned out to be important (shared, cloud, dedicated)
$db_host = "localhost"; //DB_HOST in WP
$db_name = "yours"; //DB_NAME in WP
$db_charset = "utf8mb4";//usually
$dsn = "mysql:host=$db_host;dbname=$db_name;charset=$db_charset";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_LOCAL_INFILE => true,
// on/off based on your need: https://www.php.net/manual/en/ref.pdo-mysql.php
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
//makes sure addons like counting rows is enabled
];
$PDO = new PDO($dsn, $db_user, $db_password, $opt);
// Run the Jewels - do your stuff here
$stmt = $PDO->query( "SELECT * FROM wp_posts WHERE post_status='publish' " );
// one-line count, no shenanagans
$rows = (int) $PDO->query('SELECT FOUND_ROWS()')->fetchColumn();
echo "tell me something useful: $rows";