Создание 2D-массива из массива с помощью foreach-циклов - PullRequest
0 голосов
/ 03 февраля 2010

извините за смутное название. Я извлекаю некоторые данные из таблицы с настройкой, как указано ниже, используя 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] => Массив ( [0] => Комментарий [1] => Ежемесячная плата [2] => Цена за минуту [3] => Цена за SMS [4] => Цена за MMS ) [SubName2] => Массив (..)

Это мой код:

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 голосов
/ 03 февраля 2010

Если я правильно понимаю вашу проблему, это то, как вы должны это сделать.

Прежде всего, я предлагаю вам перехватить каждую строку вместо отдельных ячеек, а затем проанализировать каждую строку независимо.

Так что в этом примере я предполагаю, что ваша строка заключена в теги 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);
}

Важное замечание: это не помешает вам перезаписать некоторые данные, если ваше имя не уникально, поэтому вы должны быть уверены, что оно действительно так. Это связано с тем, что ассоциативные массивы не могут иметь несколько ключей с одинаковым значением.

...