Чтение txt документа и выгрузка в mysql

299
23 января 2017, 21:39

Доброго времени суток!
Есть txt файл с большим количеством строк, размер документа 15 - 30 мб.

Проблема:
Когда в файле не много строк все работает как положенно, но в случае когда мы имеем большое количество строк получаем ошибку:

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 72 bytes).

Как лучше обойти данную проблему, на ум приходит поставить счетчик и загружать данные к примеру по n количеству строк. Хотелось бы узнать какие решения вы используете.

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

function file_processing ($upload_dir, $file) {
    // File propertie
    $file_name = $file['name'];
    $file_tmp = $file['tmp_name'];
    $file_size = $file['size'];
    $file_error = $file['error'];
    // Work out the file xxtention
    $file_ext = explode('.', $file_name);
    $file_ext = strtolower(end($file_ext));
    $allowed = array('txt');
    if (in_array($file_ext, $allowed)) {
        if ($file_error === 0) {

                $file_name_new = $file_name;
                $file_destination = $upload_dir . '' . $file_name_new;
                if (move_uploaded_file($file_tmp, $file_destination)) {
                    $file = fopen($file_destination, "r") or die ("Unable to open file!");
                    $fp = file($file_destination);
                    $array = [];
                    foreach ($fp as $key) {
                        $tmp_mass = explode("\";\"", $key);
                        array_push($array, $tmp_mass);
                    }
                    fclose($file);
                    unlink($file_destination);
                    return $array;
                } else {
                    echo "Please select only text file (.txt file is recomendet)!";
                }
        }
    }
}

Функция которая загружает данные массива в бд mysql:

function post_integration($arr, $array) {
    global $wpdb;
    $cat = $array['category'];
    $manufacturer = $array['manufacturer'];
    $return_status = $array['return_status'];
    $markup = $array['markup'];
    for ( $i = 1; $i < count($arr); $i++ )
    {
        $vendor_code = ( iconv ("CP1251", "UTF-8", $arr[$i][0]) );
        $vendor_code = substr($vendor_code, 1);
        $product_name = ( iconv ("CP1251", "UTF-8", $arr[$i][1]) );
        $price = ( iconv ("CP1251", "UTF-8", $arr[$i][2]) );
        $rabat_group = ( iconv ("CP1251", "UTF-8", $arr[$i][3]) );
        $product_desc = ( iconv ("CP1251", "UTF-8", $arr[$i][4]) );
        $mortgage_value = ( iconv ("CP1251", "UTF-8", $arr[$i][5]) );
        $netto_weight = ( iconv ("CP1251", "UTF-8", $arr[$i][6]) );
        $netto_weight = substr($netto_weight, 0, -1);
        $price = str_replace(",",".",$price);
        $this_price =  ( ($markup / 100) * $price) + $price;
        $end_price = round($this_price, 2);

        $query="SELECT vendor_code.meta_value AS \"vendor_code\", p.ID AS \"ID\" FROM wp_posts p
        JOIN wp_postmeta vendor_code ON p.ID = vendor_code.post_id AND vendor_code.meta_key = 'vendor_code'
        WHERE post_status = 'publish' AND post_type = 'post' AND vendor_code.meta_value = $vendor_code";
        $rabrt_id_query = "SELECT id FROM `wp_rabat_list` WHERE name_rabat = '$manufacturer'";
        $result_data = $wpdb->get_results($query);
        $rabat_data = $wpdb->get_results($rabrt_id_query);
        $rabat_id = $rabat_data[0]->id;
        $result_id = $result_data[0]->ID;
        $result_vendor = $result_data[0]->vendor_code;
        if(isset($result_vendor)) {
            $my_post = array();
            $my_post['ID'] = intval($result_id);
            $my_post['post_title'] = wp_strip_all_tags($product_name);
            $my_post['post_content'] = $product_desc;
            $my_post['post_category'] = array($cat);
            wp_update_post($my_post);
            update_post_meta($my_post['ID'], 'vendor_code', $vendor_code);
            update_post_meta($my_post['ID'], 'price', $end_price);
            update_post_meta($my_post['ID'], 'manufacturer', $manufacturer);
            update_post_meta($my_post['ID'], 'mortgage_value', $mortgage_value);
            update_post_meta($my_post['ID'], 'netto_weight', $netto_weight);
            // update_post_meta($my_post['ID'], 'availability', $article);
            update_post_meta($my_post['ID'], 'return_goods', $return_status);
            update_post_meta($my_post['ID'], 'discount_group_id', $rabat_id);
            update_post_meta($my_post['ID'], 'mark_up', $markup);

        }
        else
        {
            $post_data = array(
              'post_title'    => wp_strip_all_tags( $product_name ),
              'post_content'  => $product_desc,
              'post_status'   => 'publish',
              'post_author'   => 1,
              'post_category' => array($cat)
            );
            //Вставляем запись в базу данных
            $post_id = wp_insert_post( $post_data );
            add_post_meta($post_id, 'vendor_code', $vendor_code);
            add_post_meta($post_id, 'price', $end_price);
            add_post_meta($post_id, 'manufacturer', $manufacturer);
            add_post_meta($post_id, 'mortgage_value', $mortgage_value);
            add_post_meta($post_id, 'netto_weight', $netto_weight);
            // add_post_meta($post_id, 'availability', $article);
            add_post_meta($post_id, 'return_goods', $return_status);
            add_post_meta($post_id, 'discount_group_id', $rabat_id);
            update_post_meta($my_post['ID'], 'mark_up', $markup);
        }

    }
}
Answer 1

Самый простой метод попробуйте поставить больше лимита в php файле: например

ini_set('memory_limit', '1024M');

должно помочь в данной ситуации.

Answer 2

Частично помогло, но загрузило только 3000 строк и после выводит следующую ошибку:
Fatal error: Maximum execution time of 30 seconds exceeded

Answer 3

В результате получаю, 504 Gateway Time-out.
Скрипт успевает обходить 3000+ строк и загружать их в бд.
Но в моем случае в тхт документе 140 000+ строк.

READ ALSO
Как добавить в пункт меню drupal 7 html код?

Как добавить в пункт меню drupal 7 html код?

Работаю над темой для Drupal 7, основанной на bootstrapСпециальной базовой темы не использую, всё делаю вручную

362
Как преобразовать цикл foreach в страницы? [требует правки]

Как преобразовать цикл foreach в страницы? [требует правки]

Здравствуйте, возможно ли преобразовать цикл foreach в страницы? Поможет ли в этом функция array_chunk?

276