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";