mysqli -> fetch_object() vs mysqli -> fetch_object('myclass') - Random memory issue

101 views Asked by At

My php script runs fine if I fetch the mysqli result as StdClass. But, I run into random "out of memory" issues when i cast the mysqli result to a user-defined class.

This always works fine:

while ($O = $result->fetch_object()) {
  $papers[$O -> id] = $O;
}

But this causes an out of memory error at times (only with this specific database, and error thrown randomly)

while ($O = $result->fetch_object('paper')) {
  $papers[$O->id] = $O;
}

The error message is PHP Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 130968 bytes) in D:\programdata\Apache\htDocs\_library\Helper.inc on line 278 (That line number makes no sense. it is a commented line). Try {} except {} blocks do not catch the error. php memory_get_usage(true) returned 7,602,176 Bytes during the last loop (#71 out of 220) before the error.

System Info (Running on Apache 2.4.58 with PHP 5.6 on a Dell PowerEdge R830 with 512GB of RAM and almost nothing else going on in the machine. CPU, RAM usage is under 2% throughout. (The OS is running Windows Server 2016).

To emphasize, this is not repeatable. It works fine sometimes, but not always. (Using the same code without any changes).

Troubleshooting tried: I called $db->store_result() before calling fetch_object() but that did not help. Also, I have simplified the paper class to do absolutely nothing, but still get the the out of memory error.

    class paper {  
      function __construct() {
      }
    }

The database has about 250 rows, but each row is fairly long (about 180 fields with 4 blobs). PHP maxmemory is set to 1.5GB (yes GB) and I confirmed that via phpinfo().

When the error happens php memory_get_usage(true) reports only about 9MB memory usage.

The following function shows what I am doing. The exceptionhandler is not called when the out of memory error occurs. But, this is not a repeatable issue with other databases.

function getData($svr, $usr, $pwd, $db, $table){
    
    $papers = array();
    $db = new mysqli($svr, $usr, $pwd, $db);
        
    try {
      $query = "select * from `$table` where year = 2023 ";
      $result = $db -> query($query, MYSQLI_STORE_RESULT);      
      if (!$result) {
          echo "Query Error: " . $query . "<br>";
          exit;
      }

      while ($O = $result -> fetch_object('paper')) {
        echo memory_get_usage(true) . " Processed {$O -> id}.<br>\r\n ";
        $papers[$O -> id] = $O;
      }
   }
   catch (exception $e) {
     echo "Error: " . $e -> getMessage() . " <br>\r\n";
    }
    return $papers;
}
0

There are 0 answers