使用foreach循环从数组创建2D数组

时间:2010-02-03 11:09:02

标签: php foreach multidimensional-array

抱歉这个模糊的标题。我正在使用simple_html_dom从表中提取一些数据,如下所示。我想要做的是将数据插入到2D数组(?)中,其中第一个字段的值是订阅的名称,其余的是与该订阅相关的数据。

<td><a href="/subname/index.jsp">SubName</a></td> <!-- This is the name of the subscription -->
<td>Comment regarding the subscription</td><!-- Comment -->        
<td><strong>0,-</strong></td><!-- Monthly fee -->
<td>0,49</td><!-- Price per minute -->
<td>0,49</td><!-- Price per SMS -->
<td>1,99</td><!-- Price per MMS -->

到目前为止,我的工作正常,但它将所有值都放入常规数组中。 我已经尝试过阅读阵列并尝试不同的解决方案,但我似乎无法绕过它。

我想要的是:

  

阵       (       [SubName1] =&gt;排列       (           [0] =&gt;评论           [1] =&gt;月租费           [2] =&gt;每分钟价格           [3] =&gt;每条短信的价格           [4] =&gt;每个MMS的价格       )       [SubName2] =&gt;排列       (..)

这是我的代码:

function getData($uri) {
try {
$html = file_get_html($uri); // Fetch source code
$data = array();
foreach($html->find('td') as $td) { // Fetch all <td>-elements

foreach($td->find('a') as $a) { // Fetch all <a>-elements to remove links
     $data[] = $a->innertext; // This returns the names of the subscriptions
}
foreach($td->find('strong') as $strong) { // Fetch all <strong>-elements to remove bold text
   $data[] = $strong->innertext;
}
if(!preg_match('/<strong>/', $td->innertext) && !preg_match('/<a/', $td->innertext)) { // Skip all <td>-elements that contains <strong> and <a>, since we already have them 
    $data[] = $td->innertext;
}
}

/* Logic for database insertion goes here */

unset($data); // Deletes array
$html->clear(); // Clear to free up memory
unset($html);
} catch (Exception $e) {
echo 'Failed to fetch prices from'.$uri.'.<br />'.$e->getMessage();
}
}

提前致谢。

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,你应该这样做。

首先,我建议您捕获每一行而不是单个单元格,然后单独解析每一行。

因此,在此示例中,我假设您的行包含在tr标记中:

<tr>
<td><a href="/subname/index.jsp">SubName</a></td> <!-- This is the name of the subscription -->
<td>Comment regarding the subscription</td><!-- Comment -->        
<td><strong>0,-</strong></td><!-- Monthly fee -->
<td>0,49</td><!-- Price per minute -->
<td>0,49</td><!-- Price per SMS -->
<td>1,99</td><!-- Price per MMS -->
</tr>

如果在开头或结尾有更多单元格,则只需相应地调整索引。此外,我还没有测试过这段代码,所以可能会有一些错误,但一般的想法应该没问题。

//here we will store parsed values
$data = array();

// you may want to filter this a bit if you want some rows to be skipped
foreach ($html->find('tr') as $tr) {
    // we get first cell in the row, find a element inside and take it's inner text and so on
    $name = $tr->children(1)->find('a')->innertext;
    $comment = $tr->children(2)->innertext;
    $monthyFee = $tr->children(3)->find('strong')->innertext;
    $pricePerMin = $tr->children(4)->innertext;
    $pricePerSms = $tr->children(5)->innertext;
    $pricePerMms = $tr->children(6)->innertext;

    // create new entry in $data array formatted as you wanted it
    $data[$name] = array($comment, $monthlyFee, $pricePerMin, $pricePerSms, $pricePerMms);
}

重要说明 - 如果您的名字不是唯一的,这不会阻止您覆盖某些数据,因此您必须确定它是否真的存在。这是因为关联数组不能有多个具有相同值的键。