PHP5.3.5 PDO FETCH_OBJ内存泄漏?

PHP5.3.5 PDO FETCH_OBJ内存泄漏?,php,memory,pdo,memory-leaks,Php,Memory,Pdo,Memory Leaks,我目前正在用PHP开发一个使用PDO的应用程序。我正在写一个导入,它读取一个CSV文件,检查数据库中的记录,更新,删除,等等 我注意到,这个脚本使用的内存似乎非常高,这似乎与我执行查询的方式有关。请参见下面为CSV中的每一行执行的查询示例: $qry = "SELECT * FROM company WHERE id = 1"; $sth = $this->prepare($qry); $sth->execute(); $sth->setFetchMode(PDO::FETCH

我目前正在用PHP开发一个使用PDO的应用程序。我正在写一个导入,它读取一个CSV文件,检查数据库中的记录,更新,删除,等等

我注意到,这个脚本使用的内存似乎非常高,这似乎与我执行查询的方式有关。请参见下面为CSV中的每一行执行的查询示例:

$qry = "SELECT * FROM company WHERE id = 1";
$sth = $this->prepare($qry);
$sth->execute();
$sth->setFetchMode(PDO::FETCH_INTO, new Company());
$sth->fetch();
对于上述内存,获取峰值使用率()=6291456

当使用以下工具时:

$qry = "SELECT * FROM company WHERE id = 1";
$sth = $this->prepare($qry);
$sth->execute();
$sth->setFetchMode(PDO::FETCH_CLASS, "Company");
$sth->fetch();
对于上面的内存_get_peak_usage()=524288

正如你所看到的,差别是相当大的

我想我有三个问题

  • 在PHP5.3.5中使用PDO::FETCH_OBJ时是否存在内存泄漏
  • 使用FETCH_类和FETCH_OBJ有什么区别吗
  • 还有其他人经历过同样的问题吗
  • 公司类很简单:

    class Company {
        function __construct(){}
        /**classvars**/
        public $_tablename = 'company';
        public $transient;
        public $id;
        public $name;
        /**endclassvars**/
    } 
    

    注意:在OP将
    PDO::FETCH_OBJ
    更改为
    PDO::FETCH_INTO

    在那次更新之后,我尝试使用
    PHP5.3.10-1ubuntu3.4
    重现这种行为。两种获取模式之间的内存消耗没有显著差异。我已经使用一个大型MySQL表和一个大型SQLite数据库进行了测试

    正如@SDC所提到的,这个bug是已知的,在5.3.5之后被修复。(如我所见,至少在5.3.10中)

    结论:您必须升级PHP版本


    尽管这种行为很有趣,应该进行调查,但您使用的
    PDO::setFetchMode()
    方法是错误的。当$mode(第一个参数)是PDO::FETCH_OBJ否时,应使用第二个参数。如果使用第二个参数,则对
    setFetchMode()
    的调用将失败(returnin false),并将使用默认的获取模式
    fetch\u这两个

    启用
    PDO::ERRMODE\u异常时,您可以看到此错误:

    $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());
    
    致命错误:未捕获异常“PDOException”,消息为“SQLSTATE[HY000]:一般错误:获取模式不允许任何额外参数”


    当您希望结果行应该是特定类的对象时,那么
    PDO::FETCH_class
    就是工作尝试
    PDO::FETCH_OBJ
    将从类型
    StdClass

    FETCH_INTO返回对象:表示提取到现有对象(使用新对象创建,例如)

    FETCH_类:意味着进入一个新对象(每行调用一个构造函数)

    请注意,如果您公司类中的构造函数具有依赖项,则每行都会调用它们。因此,构造函数不应包含进行DB连接的函数或类,例如,仅简单初始化

    您的公司类是什么样子的?

    查看,在5.3.4中似乎有一个相关的修复程序,其中

    根据你所说的,我怀疑是的,这就是你看到的bug。当然,解决方案是升级——坚持使用旧的补丁版本是没有意义的


    即使这不是你看到的bug,在5.3.3到现在的版本中已经有大量的PDO修复;我敢肯定,其中至少有一部分与你有关。

    @MikeB:但他问的问题是,为什么会有如此巨大的差异。@Martin你可能误解了
    PDO::FETCH_OBJ
    。看我的answer@MikeB公司类的内容与此无关。。。他正在以任何一种方式实例化一个公司对象。Company类做什么并不重要,因为它在这两种情况下都做相同的事情。对不起,我输入了错误的代码。。它不是PDO::FETCH_OBJ,我拥有的是PDO::FETCH_INTO。问题仍然存在。我已经编辑了我的帖子如果您怀疑5.3.5中可能存在内存泄漏,那么您应该尝试的第一个解决方案是更新到最新的补丁版本,目前为5.3.21。在5.3.5和5.3.21之间修复了很多bug和安全问题。无论如何,你真的应该让你的软件保持最新的补丁。对不起,我输入了错误的代码。。它不是PDO::FETCH_OBJ,我拥有的是PDO::FETCH_INTO。问题仍然存在。我已经编辑了我的post@Martin好,我们会进一步调查。目前正在浏览pdo_stmt.c:)好的,我想这是因为:$sth->setFetchMode(pdo::FETCH_INTO,new Company());如果您正在调用$sth->setFetchMode(PDO::FETCH_类,“Company”);PHP必须确定并创建类,在第一种情况下,它就在那里。感谢您指出这一点。我猜这只是我发布的版本中的一部分。我必须试着升级,然后检查一下。再次感谢