【问题标题】:PHP Exceeding memory while accessing databasePHP访问数据库时超出内存
【发布时间】:2015-11-11 07:04:24
【问题描述】:

我正在使用 PHP 开发一个面向对象的网站,同时使用我刚刚学到的一些设计模式。 我有一个用于数据库的单例类和其他一些使用数据库类的实例执行一些数据库操作的类。

类,

  1. 数据库(单例)
  2. 用户
  3. 节点
  4. 传感器

class Database {
    //adaptor variable 
    private $db;

    //singleton instance
    private static $instance=NULL;

    private $config = array(
                            'host'      => 'localhost',
                            'username'  => 'XXXXXXX',
                            'password'  => '',
                            'dbname'    => 'XXX'
                            );

    private function __construct() {
        try
        {
            echo "using construct";
            //adaptor
            $this->db = new PDO('mysql:host=' . $this->config['host'] . ';dbname=' . $this->config['dbname'], $this->config['username'], $this->config['password']);
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            die($e->getMessage());
            exit();
        }
    }


    public static function getConnection()
    {
        if(self::$instance==NULL)
        {
            self::$instance = new Database();
        }
        return self::$instance;
    }

    public function prepare($sql)
    {
        return $this->db->prepare($sql);
    }
}

其他类使用getConnection函数获取单例实例

class User extends Visitor {
//* has getters and setters(setters via database only)
private $db;
private $username; //*
private $email; //*
private $confirmed;//*
private $nodes;
private $id;
public function __construct() {
    $this->db = Database::getConnection();
    $argv = func_get_args();

    switch( func_num_args() ) {
        case 0: 
            self::__construct1();
            break;
        case 1:
            self::__construct2($argv[0]);
            break;
     }
}
}

所以这是每个类的基本结构。

我将单例用于数据库,因为我不希望在我的服务器中发生太多连接,这会占用我的内存。

为了检查单例是否正常工作,我在数据库类的构造函数中添加了一个回显。

总而言之,这应该可以正常工作。它一直正常工作,直到我向用户类添加了更多方法(能够删除节点,我在用户类中有 550 行,我想,这应该没关系)

我得到的错误是这样的

致命错误:允许的内存大小为 134217728 字节已用尽(已尝试 分配 65488 字节)在 C:\xampp\htdocs\WeatherCenter\lib\classes\Database.php 第 18 行

即指向数据库类中的配置数组。 首先,我在“节点”课上得到了这个。然后我加了一些

未设置()

将方法放入该类,然后将其移至 Database 类。我不确定为什么会出现这个问题,我在 Database 类中没有任何重复的结构(但我在 Node 类中有)

ini_set('memory_limit', '-1');不是一个选项,因为我不想使用任何方法,我需要在这里调试错误。

我会上传你需要的文件,

提前致谢, 巴希特

【问题讨论】:

  • 检查某处是否有东西进入无限循环。
  • @bansi 会做队友。现在检查
  • @bansi 底层有一个递归循环,我以前没见过,我笨。问题是我正在检查用户是否有任何节点连接到系统。所以 getNodes() 是 User 类中的一个方法。然后我有另一种方法来获取节点类中节点的所有者,它也是一个用户,所以当我调用用户构造函数时,它会创建另一个用户并检查它的节点。这将永远持续下去:)
  • 很高兴听到您的问题已解决。在 PHP 中首先要检查的是无限循环,当您遇到内存耗尽错误时,除非您知道您将达到内存限制。
  • @bansi 是的,我正在检查我的循环结构中的无限循环,从没想过它也会发生在其他领域:) 谢谢伙计!我会回答我自己的问题,但如果您能对这个案例提供一些见解,我将不胜感激,然后我可以将其标记为正确答案

标签: php mysql database memory fatal-error


【解决方案1】:

您需要找到造成这种巨大内存消耗的真正原因。您的错误消息中提到的行完全具有误导性,因为您的大部分内存将在其他地方消耗。

要找到代码的关键部分,您可以通过在适当的位置输出类似的内容来调查内存使用情况:

echo "current: " . memory_get_usage(true) . " bytes max: " . memory_get_peak_usage(true) . " bytes";

http://php.net/manual/de/function.memory-get-usage.php

【讨论】:

  • 我试过你的sn-p,我在初始化第一个对象之前添加了它,它是用户类型的。它返回,current: 524288 bytes max: 524288 bytes 但是,在我添加这个之前,我有一些 require 方法来导入类
  • 您的说法实际上是正确的,我在数据库类的某个地方遇到了错误,而实际上它在另一个类中。
  • 要查找的关键位置通常是: - 获取数据库结果 - 实例化复杂对象
【解决方案2】:

应该有一个用于调试此类事情的清单。

内存不足错误或此允许的内存超出错误是由于无限循环或错误状态而发生的,您的任务专用内存不足,操作系统终止了您的进程。

我为调试此错误所做的是逐行检查程序并检查每一行中发生的情况。您可能还需要做笔记。正如@maxhb 指出的那样,错误可能并不指向错误所在的确切位置,而是指向它去往并丢失记忆的路径上的某个地方。

在我的例子中,有两个对象在它们的构造函数中相互调用,最终会在内存中永远创建对象,直到你发现你没有足够的内存。

经验教训:

1 你真的应该坚持类图并创建面向对象的程序。

2 你应该相信你的错误所说的,它们在大多数情况下都是绝对具体的

3 递归调用对方从来都不是好事

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-31
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2016-05-19
    • 1970-01-01
    相关资源
    最近更新 更多