简体   繁体   English

PHP最佳实践,用于使用汇总数据查询一组类对象

[英]PHP Best Practices for querying a group of class objects with summarized data

This is a pretty broad question but I'm hoping I could get a bit of guidance. 这是一个相当广泛的问题,但我希望我可以得到一些指导。

I'm building a reporting system for my company. 我正在为我的公司建立报告系统。 I have classes for Customer, Order, Invoice, and Item. 我有用于客户,订单,发票和物料的类。 They work great for individual objects. 它们非常适合单个对象。 However, this is a reporting system and I will need to query and summarize these objects in a variety of ways. 但是,这是一个报告系统,我将需要以多种方式查询和总结这些对象。

For example, a single Order object will have a total dollar value for that one order. 例如,单个Order对象将具有该订单的总美元价值。 But if I'm generating a report for the month, I want to summarize a group of orders that match whatever parameters I pass my query (such as a date range and/or customer number). 但是,如果要生成该月的报告,则我想总结一组与我通过查询的参数(例如日期范围和/或客户编号)匹配的订单。

This typically involves additional work such as accumulating running totals for month to date or year to date comparisons. 这通常涉及额外的工作,例如为月度至今或年度迄今比较累计运行总计。 This is where things get a little fuzzy for me. 这对我来说有点模糊。 Does that logic belong in the Order class? 该逻辑是否属于Order类? If not, then where? 如果没有,那么在哪里? Note I will also have to do the same for my Invoice class. 注意我的发票类也必须做同样的事情。

Here's a simplified version of what I'm doing now with my Order class. 这是我现在使用Order类所做的简化版本。 I use one function (getOrders) that returns an array of Order objects, and another function (getOrderGroup) that returns an array of grouped results (not objects). 我使用一个函数(getOrders)返回一个Order对象数组,另一个函数(getOrderGroup)返回一个分组结果数组(不是对象)。

It's the getOrdersGroup() function I'm most unclear about. 我最不清楚的是getOrdersGroup()函数。 If there is a better practice for reporting on grouped results, along with counts, sums and running totals, please point me down the better path! 如果有更好的做法来报告分组结果以及计数,总计和累计结果,请指出更好的方法!

<?php
class Order {
    public $number;
    public $customer;
    public $date_ordered;
    public $date_shipped;
    public $salesperson;
    public $total;

    public function __construct(array $data = array()) {
        $this->number = $data['number'];
        $this->customer = $data['customer'];
        $this->date_ordered = $data['date_ordered'];
        $this->date_shipped = $data['date_shipped'];
        $this->salesperson = $data['salesperson'];
        $this->total = $data['total'];      
    }

    /**
     * Returns an array of order objects
     */         
    public static function getOrders(array $options = array()) {
        $orders = array();

        // Build query to return one or more orders
        // $options parameter used to form SQL query
        // ......

        $result = mysql_query($query);
        while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
            $order = new Order($row);
            $orders[] = $order;
        }
        return $orders;
    }

    /**
     * Returns an array of grouped order results (not objects)
     */         
    public static function getOrdersGroup(array $options = array()) {
        $group = array();

        // Build query that contains COUNT() and SUM() group by functions
        // ......

        $running_total = 0;
        $result = mysql_query($query);
        while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

            // Accumulate running total for the month
            $running_total += $row['sum_total'];

            // Build the group array with a listing of summarized data
            // Note: The order class is never actually instantiated here
            // Also, in this example we're grouping by date_ordered...
            // but in reality the result should be able to be grouped by a
            // dynamic field, such as by customer, or by salesperson,
            // or a more detailed breakdown with year, month, day and a running
            // total break at each level
            $group[] = array(
                "date_ordered" => $row["date_ordered"],
                "count_customers" => $row["count_customers"],
                "count_orders" => $row["count_orders"],
                "count_salespersons" => $row["count_salesperson"],
                "sum_total" => $row["sum_total"],
                "running_total" => $running_total);
        }
        return $group;
    }

    /**
     * Queries to get ordered items if drilling down to item level...
     */             
    public function getItems() {
        // blah
    }
}
?>

There are a number of tasks to be done and, yes, some of them are specific to each class. 有许多任务需要完成,是的,其中有些任务是特定于每个班级的。 Especially when it comes to knowing which columns there are and how to treat them. 尤其是当要知道存在哪些列以及如何处理它们时。 But on the other hand there is the abstract logic of 'grouping something' and of building search patterns (and this includes of course also a range of date handling functions). 但另一方面,存在“将某物分组”和构建搜索模式的抽象逻辑(当然,这还包括一系列日期处理功能)。 These two can/should be placed in separate objects/functions which can be called from both classes, orders and invoices . 可以/应该将这两个放置在单独的对象/函数中,可以从类, ordersinvoices调用它们。

A similar thing goes for putting together the result arrays. 将结果数组放在一起也有类似的事情。 Here we need to be able to adapt to all sorts of different grouping conditions. 在这里,我们需要能够适应各种不同的分组条件。 The column names are class specific but the general logic can be put in separate classes or functions. 列名称是特定于类的,但是常规逻辑可以放在单独的类或函数中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM