Доброго времени суток!
Есть 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);
}
}
}
Самый простой метод попробуйте поставить больше лимита в php файле: например
ini_set('memory_limit', '1024M');
должно помочь в данной ситуации.
Частично помогло, но загрузило только 3000 строк и после выводит следующую ошибку:
Fatal error: Maximum execution time of 30 seconds exceeded
В результате получаю, 504 Gateway Time-out.
Скрипт успевает обходить 3000+ строк и загружать их в бд.
Но в моем случае в тхт документе 140 000+ строк.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Работаю над темой для Drupal 7, основанной на bootstrapСпециальной базовой темы не использую, всё делаю вручную
Здравствуйте, возможно ли преобразовать цикл foreach в страницы? Поможет ли в этом функция array_chunk?