Мой цикл PHP foreach правильно выводит print_r, но не file_put_contents

Я использую simple_html_dom для анализа страницы и возврата содержимого.

Когда я пытаюсь вывести содержимое с помощью print_r в цикле foreach, он возвращает все элементы. Однако, если я попытаюсь вывести содержимое в текстовый файл, он выведет только последний элемент. Что я делаю не так?

Вот мой пример кода:

include 'simple_html_dom.php';

$partlist_file = $_SERVER['DOCUMENT_ROOT'].'/partlist.txt';

$partlist = file('knn-partnumberlist.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

$stock = '';

    $output_first = '';
    foreach($partlist as $parts => $part) {

        $html = file_get_html('search/product.aspx?prod=' . $part);
        $ret = $html->find('span#cph_lb_stock_buy'); 

        foreach($ret as $element) {
            $stock = $element->plaintext;
            $stock = preg_replace(array('/\\n/','/\\r/'),'',$stock);
            $stock = trim($stock);
            if($stock == 'Not in stock.') {
                $stock = '0';
            } elseif($stock == 'In Stock & Ready to Ship!') {
                $stock = '6';
            }



        $output = 'K33' . $part . ',' . $stock . "\n";
        print_r ($output); // returns all elements
        file_put_contents($partlist_file, $output); // only returns last element

        }
    }

Пример вывода print_r:

K3300283,6
K3301518,6
K3301988,6
K3303351,6
K3303365,6

Пример вывода file_put_contents:

K3303365,6

person Mike    schedule 30.07.2015    source источник


Ответы (2)


Вам нужно объединить $ output для каждой итерации, без простой перезаписи

 $output .= 'K33' . $part . ',' . $stock . "\n";
        print_r ($output);
        file_put_contents($partlist_file, $output);

. — оператор конкатенации

person Mihai    schedule 30.07.2015
comment
спасибо, это то, что я использовал. Но с print_r на экране получается что-то другое. Однако это хорошо работает для file_put_contents. Почему это дает разные результаты для print_r? - person Mike; 30.07.2015
comment
@Mike print_r вызывается для каждой итерации цикла, поэтому вы видите его на экране, в то время как в $output он перезаписывается для каждой итерации, поэтому вы получаете только последнее значение. - person Mihai; 30.07.2015
comment
хорошо, что мне нужно сделать, чтобы увидеть его на экране с помощью print_r так же, как он выводит в текстовый файл? - person Mike; 30.07.2015
comment
Также переместите вызовы print_r и file_put_contents за пределы цикла, в котором вы перезаписываете файл 5 раз. - person Orangepill; 30.07.2015
comment
@Orangepill, о да, спасибо, что поймал это для меня. - person Mike; 30.07.2015
comment
Что происходит в вашем коде, так это то, что каждый раз в цикле он записывает один элемент в выходной буфер и создает файл с одной строкой в ​​нем. Каждый раз при переходе к массиву выходной буфер добавляется, но файл перезаписывается. - person Orangepill; 30.07.2015

Функция print_r имеет логическую опцию, которая позволяет возвращать ее как строковую переменную, а не выводить ее на экран. Его использование выглядит примерно так:

$myVar = print_r($otherVar, true);

Это позволит вам собирать значение, а не печатать его непосредственно в выходной буфер (например, на экран). Это оказалось бы полезным, поскольку теперь вы можете манипулировать значением по мере необходимости или по желанию.

Кроме того, у file_put_contents также есть опция, которая позволяет добавлять в файл, а не перезаписывать его текущее содержимое. Опять же, использование будет выглядеть так:

$dummy = file_put_contents('путь/к/файлу', $varToSave, FILE_APPEND);

Этот последний параметр представляет собой целочисленный битовый флаг (я не знаю его фактического значения), который указывает PHP добавить новые данные в конец файла вместо замены текущего содержимого новыми данными. Использование обеих этих опций в исходном коде будет выглядеть так:

include 'simple_html_dom.php';

$partlist_file = $_SERVER['DOCUMENT_ROOT'].'/partlist.txt';

$partlist = файл('knn-partnumberlist.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

$ акции = '';

$output_first = '';
foreach($partlist as $parts => $part) {

    $html = file_get_html('search/product.aspx?prod=' . $part);
    $ret = $html->find('span#cph_lb_stock_buy'); 

    foreach($ret as $element) {
        $stock = $element->plaintext;
        $stock = preg_replace(array('/\\n/','/\\r/'),'',$stock);
        $stock = trim($stock);
        if($stock == 'Not in stock.') {
            $stock = '0';
        } elseif($stock == 'In Stock & Ready to Ship!') {
            $stock = '6';
        }



    $output = 'K33' . $part . ',' . $stock . "\n";
    $display = print_r ($output, true);
    // you can manipulate $display here, like so:
    $display = str_replace("\n", "\r\n", $display);
    echo $display; // returns all elements (one at a time)
    file_put_contents($partlist_file, $display, FILE_APPEND); // now stores all values of $output in the file

    }
}

Конечно, похоже, что вам не нужно манипулировать значением $output в вашем скрипте, но чтобы проиллюстрировать полезность опции в print_r, я добавил строку кода, которая заменяет символы новой строки Linux (\n ) с новыми строками Windows (\r\n), чтобы такие программы, как Блокнот, могли правильно отображать текст (функция PHP print_r помещает \n новых строк в вывод только на компьютерах с Windows, поэтому я нашел этот пост. Я пытался найти способ исправить такое поведение). Это может оказаться бесполезным для вас в настоящее время, но может оказаться полезным позже и может оказаться полезным для других, кто сталкивается с этим вопросом. Надеюсь, это поможет. :)

person Dave Morton    schedule 29.02.2016