这个代码是一个很好的PHP实践来处理我的查询结果吗?

时间:2015-04-28 14:54:08

标签: php mysql

我想知道这是一个好习惯,在我的查询中是否有巨大的结果。

当我有几行时,一切似乎都很好(即使这种方法不是一个好习惯),但是当我有10,000行时,一切都变得疯狂(致命错误:允许的内存大小)。

abstract class System
{
    public static function arrayOfObjectTo($reference, $rows)
    {
        $response = array();
        foreach($rows as $row) {
            $response[] = new $reference($row)
        }
        return $response;
    }

    public static function arrayOfObjectToJson($rows)
    {
        $response = array();
        foreach ($rows as $object) {
            $response[] = $object->toObject();
        }
        return json_encode($response);
    }
}

class Report
{
    public function __construct($data)
    {
        $this->setName($data['name']);
        $this->setEmail($data['email']);
        $this->setPassword($data['password']);
    }

    public function toObject() 
    {
        $object = new stdClass();
        $object->name = $this->getName();
        $object->email = $this->getEmail();
        $object->password = $this->getPassword();
        return $object;
    }

    // getters and setters ...
}

class ReportModel
{
    public function getAll()
    {
        $this->query('SELECT * FROM ...');
        return System::arrayOfObjectTo('Report', $this->rows);
    }
}

class ReportController
{
    public function show()
    {
        $model = new ReportModel();
        return System::arrayOfObjectToJson($model->getAll());
    }
}

关注我的问题是处理Report对象,验证数据类型和其他内容的最佳方法。

最终结果是向客户显示处理和格式化的所有行。

[
    { name:"A", email:"a@.com", password:"1" },
    { name:"B", email:"b@.com", password:"2" },
    { name:"C", email:"c@.com", password:"3" }
    ...
]

这只是一个例子。有时候我会有一个BIG查询,要显示很多列和行。

1 个答案:

答案 0 :(得分:2)

为了清楚起见,我会稍微修改代码,将ReportModel重命名为ReportList,然后将getAll的结果保存为属性。实现接口JsonSerializable并直接序列化对象。您还必须在Report对象上实现接口,并指定要返回序列化的字段。

class ReportList implements JsonSerializable
{
    protected $reports = array();

    public function getAll()
    {
        $this->query('SELECT * FROM ...');
        $this->reports = System::arrayOfObjectTo('Report', $this->rows);
        return $this;
    }

    public function jsonSerialize(){
        return $this->reports;
    }
}

class Report implements JsonSerializable
{
    public function __construct($data)
    {
        $this->setName($data['name']);
        $this->setEmail($data['email']);
        $this->setPassword($data['password']);
    }

    public function jsonSerialize(){
        return ['name' => $this->name, 'email' => $this->email]; // array of private fields
    }
}

然后

class ReportController
{
    public function show()
    {
        $model = new ReportList();
        return json_encode($model->getAll());
    }
}

此外,如果您想要一些评论,您的代码并不是非常灵活或可靠。您将获得各种错误,例如,如果给Report的构造函数的值不是数组或者是数组但不包含您使用的键。这与问题没有关系所以我会在这里剪掉它,只是想让你知道。您可以在code review上获得有关此主题的更好建议。

关于有很多行时的错误,它取决于很多东西,主要是你的机器和php设置。假设你在10k行上得到这个错误,你要么拥有非常大的行,要么为php提供非常低的允许内存设置。平均行长度为100字节,这可能比您大多数时间要多得多,10k行的100字节大约是1兆字节。我不太了解php内部,但是要将它转换为json,你最多需要5倍于信息本身的空间,这意味着你需要5兆字节的内存(在最极端的情况下),因为它非常大json字符串,添加原始1兆字节的数据本身+类似于PHP使用的200KB,最终不超过7-10兆字节的内存,10k行,平均大小为100字节。如果你的脚本不允许分配10兆字节的ram,那么哦。