Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在数据映射器模式中创建对象数组_Php_Mysql_Oop_Pdo - Fatal编程技术网

Php 在数据映射器模式中创建对象数组

Php 在数据映射器模式中创建对象数组,php,mysql,oop,pdo,Php,Mysql,Oop,Pdo,编辑:在问题的底部输出代码 我刚刚发布了一个问题,以为我的问题是查询,但结果是我的PHP代码 问题出在这里。我有一个GoalChallenge类,它有许多属性,其中一个属性应该是一个,或者一个ProductService对象数组;请参见下面的GoalChallenge类(注意,我已经去掉了其他getter和setter,并留下了与ProductService类相关的getter和setter 当我使用GoalChallenge::findByPersonaId时,会创建一个ProductServ

编辑:在问题的底部输出代码

我刚刚发布了一个问题,以为我的问题是查询,但结果是我的PHP代码

问题出在这里。我有一个GoalChallenge类,它有许多属性,其中一个属性应该是一个,或者一个ProductService对象数组;请参见下面的GoalChallenge类(注意,我已经去掉了其他getter和setter,并留下了与ProductService类相关的getter和setter

当我使用GoalChallenge::findByPersonaId时,会创建一个ProductService对象并与匹配的GoalChallenge对象相关联,但GoalChallenge->product\u服务属性中应该有两个ProductService对象(查询应该匹配两行)。相反,将创建一个重复的GoalChallenge对象,该对象包含除product_service属性之外的所有属性值,该属性包含查询中的第二个匹配对象

我需要两个匹配的ProductService对象成为同一个GoalChallenge对象的一部分(与查询匹配)-我如何才能做到这一点

如果您还需要什么,请询问。非常感谢您的帮助!代码如下

GoalChallenge.class.php

<?php

class GoalChallenge
{
    private $id;
    private $persona_id;
    private $title;
    private $item_category;
    private $description;
    private $solution;
    private $product_service;
    private $research_checklist;
    private $subtopics;
    private $keywords;
    private $status;


    public function __construct(
        $id = null, 
        $persona_id = null, 
        $title = null, 
        $item_category = null, 
        $description = null,
        $solution = null,
        ProductService $product_service = null,
        $research_checklist = null,
        $subtopics = null, 
        $keywords = null, 
        $status = null
    ) {
        $this->id = $id;
        $this->persona_id = $persona_id;
        $this->title = $title;
        $this->item_category = $item_category;
        $this->description = $description;
        $this->solution = $solution;
        $this->product_service = $product_service;
        $this->research_checklist = $research_checklist;
        $this->subtopics = $subtopics;
        $this->keywords = $keywords;
        $this->status = $status;
    }

    public function getProductService()
    {
        return $this->product_service;
    }

    public function setProductService(ProductService $product_service)
    {
        $this->product_service = $product_service;
    }

}
最后是我的ProductService类(减去getter和setter)

这是输出

GoalChallenge Object
(
    [id:GoalChallenge:private] => 173
    [persona_id:GoalChallenge:private] => 14
    [title:GoalChallenge:private] => Lead Gen
    [item_category:GoalChallenge:private] => Business Challenge
    [description:GoalChallenge:private] => 


    [solution:GoalChallenge:private] => Advertising
    [product_service:GoalChallenge:private] => ProductService Object
        (
            [id:ProductService:private] => 1
            [goal_challenge_id:ProductService:private] => 173
            [url:ProductService:private] => www.google.com
            [feature_benefit:ProductService:private] => Array
                (
                    [0] => good for testing
                    [1] =>  mobile
                )

        )

    [research_checklist:GoalChallenge:private] => 0,0,0,0,0,0
    [subtopics:GoalChallenge:private] => 
    [keywords:GoalChallenge:private] => ,,,,
    [status:GoalChallenge:private] => 1
)

GoalChallenge Object
(
    [id:GoalChallenge:private] => 173
    [persona_id:GoalChallenge:private] => 14
    [title:GoalChallenge:private] => Lead Gen
    [item_category:GoalChallenge:private] => Business Challenge
    [description:GoalChallenge:private] => 


    [solution:GoalChallenge:private] => Advertising
    [product_service:GoalChallenge:private] => ProductService Object
        (
            [id:ProductService:private] => 3
            [goal_challenge_id:ProductService:private] => 173
            [url:ProductService:private] => www.test.com
            [feature_benefit:ProductService:private] => Array
                (
                    [0] => good for searching
                    [1] =>  well known
                )

        )

    [research_checklist:GoalChallenge:private] => 0,0,0,0,0,0
    [subtopics:GoalChallenge:private] => 
    [keywords:GoalChallenge:private] => ,,,,
    [status:GoalChallenge:private] => 1
)
mysql>选择目标挑战。*,products\u services.id作为psid,products\u services.url,products\u services.feature\u从目标挑战中获益左加入目标挑战中的产品服务。id=产品服务。目标挑战。id,其中目标挑战。人物角色id=14

+-----+------------+----------+--------------------+-------------+-------------+-----------------+--------------------+-----------+----------+--------+------+----------------+--------------------------------+
| id  | persona_id | title    | item_category      | description | solution    | product_service | research_checklist | subtopics | keywords | status | psid | url            | feature_benefit                |
+-----+------------+----------+--------------------+-------------+-------------+-----------------+--------------------+-----------+----------+--------+------+----------------+--------------------------------+
| 173 |         14 | Lead Gen | Business Challenge |             | Advertising | NULL            | 0,0,0,0,0,0        | NULL      | ,,,,     |      1 |    1 | www.google.com | good for testing, mobile       |


| 173 |         14 | Lead Gen | Business Challenge |             | Advertising | NULL            | 0,0,0,0,0,0        | NULL      | ,,,,     |      1 |    3 | www.test.com   | good for searching, well known |


+-----+------------+----------+--------------------+-------------+-------------+-----------------+--------------------+-----------+----------+--------+------+----------------+--------------------------------+
一组2行(0.00秒)

打印(目标和挑战)


正如所怀疑的那样,
JOIN
查询的结果集需要比您给定的更多的逻辑来格式化。SQL结果集始终是二维结构,即使它包含的数据具有更复杂的关系(如一对多关系)

有几种方法可以实现这一点,我认为最接近您现有模式的一种方法是稍微更改获取行的方式。与其获取行然后立即映射它,不如在获取循环中构建一些逻辑来创建join表达式的嵌套结构,其中
ProductService
是一个由一个r更多对象。然后您将能够修改
mapObject()
方法来处理嵌套
ProductService
对象数组

因此,不要在获取时进行映射,而是创建一个数组,将获取的行附加到该数组上。在每次迭代中,必须检查公共值(那些
GoalChallenge
)是否已更改。如果未更改,则继续为
ProductService
构建一个数组(例如,如果查询返回多个不同的
GoalChallenge
),则启动一个新的外部结构

$result_set=array()

好的,这应该可以修复fetch模式以满足您的需要。另一个问题是让
mapObject()
方法处理产品服务的内部数组。使用循环就足够简单了

public function mapObject(array $row)
{
    $entry = new GoalChallenge();
    $entry->setId($row['id']);
    $entry->setPersonaId($row['persona_id']);
    $entry->setTitle($row['title']);
    $entry->setItemCategory($row['item_category']);
    $entry->setDescription($row['description']);
    $entry->setSolution($row['solution']);
    $entry->SetResearchChecklist($row['research_checklist']);
    $entry->setSubtopics($row['subtopics']);
    $entry->setKeywords($row['keywords']);
    $entry->setStatus($row['status']);

    // Create ProductService objects for each item in the sub-array
    foreach ($row['product_services'] as $ps) {
        $entry->setProductService(new ProductService($ps['psid'], $row['id'], $ps['url'], explode(',', $ps['feature_benefit'])));
    }

    return $entry;
}
最后,将
setProductService()
方法附加到数组中,而不是设置单个属性:

public function setProductService(ProductService $product_service)
{
    // Append onto an array
    $this->product_service[] = $product_service;
}
GoalChallenge::u construct()
参数中,使其接受并默认一个数组,而不是单个
ProductService
对象,更改为
$product\u service=array()


因此,这有点复杂,它说明了为什么通常使用预构建。这种逻辑以一种易于重用的方式为您抽象出来。PDO确实有一种
FETCH_GROUP
方法,但它仅用于对一列进行分组(如
id
)作为外部数组键,所有其他列作为子数组。您的情况是,大多数列属于外部级别,只有与联接的
ProductService
相关的列作为内部子数组,因此这实际上不起作用。

听起来联接查询为相关表返回了许多相同的列值(如一对多关系中所预期的)。请发布查询产生的输出示例,以帮助我们了解重复的内容。您可能需要更复杂的逻辑来对它们进行排序。前端foreach循环的输出代码输出。如您所见,这两个对象除了->product\u service之外是相同的,第一个对象具有查询中的第一个匹配行,然后是一个新的GoalChallenge类包含查询中的第二个匹配行。如果您将查询结果粘贴为SQL客户机的表,而不是从PHP转储,那么它实际上会更有用。好的,我现在正尝试这样做,永远不要使用mysql命令行,所以请容忍我,非常感谢您在获取mysql数据方面提供的帮助ce方法包括在上面-我很感激这是我应该创建数组的地方,但不确定当前如何进行。非常感谢您花时间构建这个答案,非常感激。我认为它就在那里,但我得到了通知:第225行(即$entry->setProductService()中的未定义索引:psid)行和相同的url和feature_方法也有好处,并且在goalChallenge对象中首先返回一个空数组,然后返回一个ProductService对象,但只有goal_挑战id showingOk可以。出于兴趣,$current_id方法是如何工作的?它从不从null更改,那么它怎么会等于$row['id']?不确定我做了什么。它现在就在那里。可能无法解决问题。需要查看
print\r($goal\u challenges)
。好的,我已经添加了print\u r-这是在前端的foreach循环中打印的。真的很抱歉-我在等待别人回复时添加了这个-现在删除,让我看看我得到了什么
Array
(
    [173] => Array
        (
            [id] => 173
            [persona_id] => 14
            [title] => Lead Gen
            [item_category] => Business Challenge
            [description] => 


            [solution] => Advertising
            [research_checklist] => 0,0,0,0,0,0
            [subtopics] => 
            [keywords] => ,,,,
            [status] => 1
            [psid] => 1
            [url] => www.google.com
            [feature_benefit] => good for testing, mobile
            [product_services] => Array
                (
                    [0] => Array
                        (
                            [0] => 1
                            [1] => www.google.com
                            [2] => good for testing, mobile
                        )

                    [1] => Array
                        (
                            [0] => 3
                            [1] => www.test.com
                            [2] => good for searching, well known
                        )

                )

        )

)
// Temp variable to remember what goals_challenges.id is being grouped
$current_id = null;
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // Create a new structure if the id changed
    if($row['id'] !== $current_id) {
       $current_id = $row['id'];
       // Store a new row for goal_challenges, holding all 
       // the common columns in its outer structure
       $goal_challenges[$row['id']] = $row;
       // and it has a sub-array for product services
       $goal_challenges[$row['id']]['product_servies'] = array();
    }
    // Append the product_services columns as an array onto the subarray
    $goal_challenges[$row['id']]['product_services'][] = array('psid'=>$row['psid'], 'url'=>$row['url'], 'feature_benefit'=>$row['feature_benefit']);
}

// Now you can pass each row of the $goal_challenges array
// to mapObject. There should be only one row, but if you 
// use the same pattern for queries that return many rows it
// will work without much modification
$result_set = array();
foreach ($goal_challenges as $gc) {
    $result_set[] = $this->mapObject($gc);
}
// Return the array of results (which probably has only one element)
return $result_set;
public function mapObject(array $row)
{
    $entry = new GoalChallenge();
    $entry->setId($row['id']);
    $entry->setPersonaId($row['persona_id']);
    $entry->setTitle($row['title']);
    $entry->setItemCategory($row['item_category']);
    $entry->setDescription($row['description']);
    $entry->setSolution($row['solution']);
    $entry->SetResearchChecklist($row['research_checklist']);
    $entry->setSubtopics($row['subtopics']);
    $entry->setKeywords($row['keywords']);
    $entry->setStatus($row['status']);

    // Create ProductService objects for each item in the sub-array
    foreach ($row['product_services'] as $ps) {
        $entry->setProductService(new ProductService($ps['psid'], $row['id'], $ps['url'], explode(',', $ps['feature_benefit'])));
    }

    return $entry;
}
public function setProductService(ProductService $product_service)
{
    // Append onto an array
    $this->product_service[] = $product_service;
}