PHP 5.3.5 Memory leak PDO FETCH_OBJ?

I am currently developing a PHP application that uses PDO. I am writing an import that reads in a CSV file, checks the database for writing and updates, deletes, etc.

Something I noticed is the memory used by this script seems very high, and it looks like it might be related to how I execute the request. see below for an example query that runs for each row in a CSV:

$qry = "SELECT * FROM company WHERE id = 1"; $sth = $this->prepare($qry); $sth->execute(); $sth->setFetchMode(PDO::FETCH_INTO, new Company()); $sth->fetch(); 

for the above memory_get_peak_usage () = 6291456

When using below:

 $qry = "SELECT * FROM company WHERE id = 1"; $sth = $this->prepare($qry); $sth->execute(); $sth->setFetchMode(PDO::FETCH_CLASS, "Company"); $sth->fetch(); 

for the above memory_get_peak_usage () = 524288

As you can see, the difference is quite large.

I think I have 3 questions.

  • Is there a memory leak when using PDO :: FETCH_OBJ in PHP 5.3.5?
  • Is there a difference between using FETCH_CLASS as opposed to FETCH_OBJ?
  • Has anyone else experienced the same issue?

The company class is simple:

 class Company { function __construct(){} /**classvars**/ public $_tablename = 'company'; public $transient; public $id; public $name; /**endclassvars**/ } 
+4
source share
3 answers

Looking at the PHP changelog , it seems that in 5.3.4 there is a corresponding fix in which .

From what you said, I suspect that yes, this is the mistake you see. The solution, of course, should be updated - there really is no point in sticking to the old patch release.

Even if this is not the error you see, in versions between 5.3.3 and now there were a lot of PDO fixes; I am sure that there are good chances that at least some of them apply to you.

+3
source

Note : the original response was set before the OP changed PDO::FETCH_OBJ to PDO::FETCH_INTO

After this update, I tried to reproduce the behavior using PHP 5.3.10-1ubuntu3.4 . Where there are no significant differences in memory allocation between sampling modes. I tested using a large MySQL table and a large SQLite database.

As noted in @SDC, the error is known and was fixed after 5.3.5. (At least in 5.3.10, as I saw).

Conclusion: You must upgrade your version of PHP.


Although the behavior is interesting and should be investigated, you are using the wrong PDO::setFetchMode() path. When $ mode is the first parameter - PDO :: FETCH_OBJ no the second parameter is expected. If you use the second parameter, the call to setFetchMode() will fail (returnin false), and the default FETCH_BOTH mode FETCH_BOTH will be used.

You can see this error when you enable PDO::ERRMODE_EXCEPTION :

 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $db->query('....'); // the following line will trigger an exception $stmt->setFetchMode(PDO::FETCH_OBJ, new Company()); 

Fatal error: throw a "PDOException" exception with the message "SQLSTATE [HY000]: general error: the sampling mode does not allow adding additional arguments

When you expect result strings to be objects of a particular class, then PDO::FETCH_CLASS is a working attempt. PDO::FETCH_OBJ will return objects from type StdClass

+2
source

FETCH_INTO: means fetching into an existing object (which was created with a new one, for example.)

FETCH_CLASS: means selection to a new object (the constructor is called by each line)

Be careful if the constructor in your company class has dependencies; they are called for each row. Therefore, the constructor should not contain functions or classes that perform a connection to the database, for example. just a simple initialization ...

What does your company class look like?

0
source

All Articles