我遇到了一些构建相当复杂阵列的问题。我做了4个不同的API调用,每个调用都返回了simpleXML数据 将在下面显示。
通过一次API调用,我基本上得到了一堆潜在客户。对于每个潜在客户,我需要收集该潜在客户的任何数据。 这是潜在客户的示例回复。
SimpleXMLElement {#289 ▼
+"Leads": SimpleXMLElement {#297 ▼
+"Lead": array:12 [▼
0 => SimpleXMLElement {#300 ▼
+"ID": "1266283"
+"State": "Current"
+"Name": "Test project"
+"Description": "Test project"
+"EstimatedValue": "2.00"
+"Date": "2016-05-26T00:00:00"
+"Client": SimpleXMLElement {#316 ▼
+"ID": "8549201"
+"Name": "Test Client"
}
}
]
}
}
然后我有一堆客户端XML数据。我需要将Lead链接到客户端并收集一些客户端数据。这是客户端的示例数据部分。
SimpleXMLElement {#290 ▼
+"Clients": SimpleXMLElement {#298 ▼
+"Client": array:41 [▼
34 => SimpleXMLElement {#335 ▼
+"ID": "8549201"
+"Name": "Test Client"
+"IsProspect": "No"
+"BusinessStructure": "IT"
}
]
}
}
所以在这一点上,我有Leads并且我已将正确的客户端与Lead匹配并获得有关该客户端的数据。嵌套两个API调用引用引号。 一个API调用返回所有当前行情。另一个API调用返回草稿引号。
这是当前报价
的示例SimpleXMLElement {#291 ▼
+"Quotes": SimpleXMLElement {#299 ▼
+"Quote": array:24 [▼
0 => SimpleXMLElement {#302 ▼
+"ID": "Q12415"
+"Type": "Quote"
+"State": "Issued"
+"Name": "Test Quote"
+"LeadID": "1266283"
+"Date": "2016-05-20T00:00:00"
+"Amount": "6100.00"
+"AmountTax": "1220.00"
+"AmountIncludingTax": "7320.00"
+"Client": SimpleXMLElement {#331 ▼
+"ID": "8549201"
+"Name": "Test Client"
}
}
]
}
}
这是草稿报价
的示例SimpleXMLElement {#292 ▼
+"Quotes": SimpleXMLElement {#300 ▼
+"Quote": SimpleXMLElement {#303 ▼
+"ID": "Q12456"
+"Type": "Quote"
+"State": "Draft"
+"Name": "Test project"
+"LeadID": "1266283"
+"Date": "2016-05-26T00:00:00"
+"Amount": "2000.00"
+"AmountTax": "400.00"
+"AmountIncludingTax": "2400.00"
+"Client": SimpleXMLElement {#305 ▼
+"ID": "8549201"
+"Name": "Test Client"
}
}
}
}
无论如何,这就是我目前所拥有的
public function getForecastReportForLeads() {
$getCurrentLeads = Helper::getCurrentLeads();
$currentLeadsXML = new \SimpleXMLElement($getCurrentLeads);
$getCurrentClients = Helper::getClientList();
$currentClientsXML = new \SimpleXMLElement($getCurrentClients);
$getCurrentQuotes = Helper::getCurrentQuotes();
$currentQuotesXML = new \SimpleXMLElement($getCurrentQuotes);
$getDraftQuotes = Helper::getDraftQuotes();
$draftQuotesXML = new \SimpleXMLElement($getDraftQuotes);
$forecastArray = array();
$iterator = 0;
foreach($currentLeadsXML->Leads->Lead as $lead) {
$seconditerator = 0;
$thirditerator = 0;
$fourthiterator = 0;
$dateIdentified = date("d/m/Y", strtotime($lead->Date));
$forecastArray[$iterator]["leadData"] = array(
'LeadID' => (string)$lead->ID,
'DateIdentified' => $dateIdentified,
'Client' => (string)$lead->Client->Name,
'LeadName' => (string)$lead->Name,
'Owner' => (string)$lead->Owner->Name,
'Category' => (string)$lead->Category
);
foreach ($currentClientsXML->Clients->Client as $client) {
if((string)$lead->Client->Name == $client->Name) {
$forecastArray[$iterator]["clientData"] = array(
'BusinessStructure' => (string)$client->BusinessStructure,
'IsProspect' => (string)$client->IsProspect
);
$seconditerator++;
}
}
foreach ($currentQuotesXML->Quotes->Quote as $quote) {
if ((string)$lead->ID == (string)$quote->LeadID) {
$forecastArray[$iterator]["quoteDataIssued"] = array(
'QuoteID' => (string)$quote->ID,
'ProjectName' => (string)$quote->Name,
'Amount' => (string)$quote->Amount,
'AmountTax' => (string)$quote->AmountTax,
'AmountIncludingTax' => (string)$quote->AmountIncludingTax
);
$thirditerator++;
}
}
foreach ($draftQuotesXML->Quotes->Quote as $draftQuote) {
if ((string)$lead->ID == (string)$draftQuote->LeadID) {
$forecastArray[$iterator]["quoteDataDraft"] = array(
'QuoteID' => (string)$draftQuote->ID,
'ProjectName' => (string)$draftQuote->Name,
'Amount' => (string)$draftQuote->Amount,
'AmountTax' => (string)$draftQuote->AmountTax,
'AmountIncludingTax' => (string)$draftQuote->AmountIncludingTax
);
$fourthiterator++;
}
}
$iterator++;
}
return $forecastArray;
}
有一点需要注意的是,有时报价没有LeadID。如果是这种情况,可以忽略Quote,这是我目前没有处理的事情。
另一件需要注意的事情是,如果与潜在客户相关的客户端的IsProspect值为“否”,我只想获取此数据。这是我正在努力实现的其他方面。
任何有关根据我的要求正确使用此建议的建议,或我如何 非常感谢我对当前代码的改进。
非常感谢
答案 0 :(得分:1)
摆脱计数器,代码将更具可读性:
function getForecastReportForLeads()
{
/* ... */
$forecastArray = array();
foreach($currentLeadsXML->Leads->Lead as $lead) {
$reportItem = array;
$dateIdentified = date("d/m/Y", strtotime($lead->Date));
$reportItem["leadData"] = array(/* ... */);
foreach ($currentClientsXML->Clients->Client as $client) {
if((string)$lead->Client->Name == $client->Name) {
$reportItem["clientData"] = array(/* ... */);
if ('No' != (string)$client->IsProspect) {
continue;
}
}
}
foreach ($currentQuotesXML->Quotes->Quote as $quote) {
if ((string)$lead->ID == (string)$quote->LeadID) {
$forecastArray["quoteDataIssued"][] = array(/* ... */);
}
}
foreach ($draftQuotesXML->Quotes->Quote as $draftQuote) {
if ((string)$lead->ID == (string)$draftQuote->LeadID) {
$reportItem["quoteDataDraft"][] = array(/* ... */);
}
}
$forecastArray[] = $reportItem;
}
return $forecastArray;
}
要省略prospect!=No
客户端,请转到:
if ('No' != (string)$client->IsProspect) {
continue;
}
如上所示。只要每个潜在客户都有一个客户端,这将有效。
第二种选择。要改进该代码,您可以尝试移动逻辑,负责遍历XML并将XML转换为数组以分离类。每个数据集合一个类。所以这里有可能的类结构:
class LeadsCollection
{
function __construct(\SimpleXMLElement $leads){}
/**
* Returns list of leads in form of assoc arrays.
*
* @return array
*/
function asArray(){}
}
class ClientsCollection
{
function __construct(\SimpleXMLElement $clients){}
/**
* @return array
*/
function getClientByName($name){}
/**
* retub bool
*/
function isProspect($name){}
}
class QuotesCollection
{
function __construct(\SimpleXMLElement $quotes){}
/**
* @retun array|null - list of quotes related with given lead
*/
function getQuotesByLeadId($leadId){}
}
class DraftQuotesCollection
{
function __construct(\SimpleXMLElement $draftQuotes){}
/**
* @retun array|null - list of draft quotes related with given lead
*/
function getDraftQuotesByLeadId($leadId){}
}
然后你的数组创建代码将更清晰,更简洁:
function getForecastReportForLeads() {
$leads = new LeadsCollection(new \SimpleXMLElement(Helper::getCurrentLeads()));
$clients = new ClientsCollection(new \SimpleXMLElement(Helper::getClientList());
$quotes = new QuotesCollection(new \SimpleXMLElement(Helper::getCurrentQuotes()));
$draftQuotes = new DraftQuotesCollection(Helper::getDraftQuotes(new \SimpleXMLElement(Helper::getDraftQuotes())));
$report = array();
foreach ($leads->asArray() as $lead) {
if ($clients->isProspect($lead['Client'])) {
continue;
}
$clientData = $clients->getClientByName($lead['Client']);
$quotesData = $quotes->getQuotesByLeadId($lead['LeadId']);
$draftQuotesData = $draftQuotes->getDraftQuotesByLeadId($lead['LeadId']);
$reportItem = array(
'leadData' => $lead,
'clientData' => $clientData,
);
empty($quotesData) || $reportItem['quoteDataIssued'] = $quotesData;
empty($draftQuotesData) || $reportItem['quoteDataDraft'] = $draftQuotesData;
$report[] = $reportItem;
}
return $report;
}
如果出于任何原因,您不想将4个新类放入项目中,那么您可以尝试将monolith方法分解为几个私有方法。您甚至可以关注" design"以上建议,但您可以将所有方法都放在单个类中,而不是有4个类。不是最干净的解决方案,但仍然比在风格方法中有一个大的程序。如果您知道不需要在系统的任何其他位置重用该代码,那么这是有意义的。
根据数据的大小,您一次又一次地遍历整个数据集的方法可能不是最有效的:
foreach ($currentClientsXML->Clients->Client as $client) {
if((string)$lead->Client->Name == $client->Name) {
/* ... */
如果您根据要访问的变量重新排列/分组潜在客户和引号,可能会获得回报,因此leadId
也是如此。和client name
。