Как решить проблему с Allowed memory size в плагине Worpress?

Ссылка скопирована
PHP
1 ответ

В одном плагине есть вкладка "Логи" при переходе в которую я получаю ошибку нехватки памяти, хотя там всего несколько строк и памяти выделено по максимуму. Как можно оптимизировать код, чтобы не потребляло много памяти?
Ошибка по строке:

$page_counter = 1; 			while( $total_pages > 0 ){  				if( $page_counter === $page ){ 					$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="wpwh-btn wpwh-btn--primary wpwh-btn--sm mr-1">' . $page_counter . '</a>'; 				} else { 					$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="btn--secondary">' . $page_counter . '</a>'; 				} 				 				$page_counter++; 			}

$page_counter = 1; while( $total_pages > 0 ){ if( $page_counter === $page ){ $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="wpwh-btn wpwh-btn--primary wpwh-btn--sm mr-1">' . $page_counter . '</a>'; } else { $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="btn--secondary">' . $page_counter . '</a>'; } $page_counter++; }

Полный код метода:

public function pagination( $args = array() ) { 	  		$per_page = isset( $args['per_page'] ) ? intval( $args['per_page'] ) : 10; 		$page = isset( $args['log_page'] ) ? intval( $args['log_page'] ) : 1;  		$page_counter = 1; 		$log_count = $this->get_log_count(); 		$total_pages = ceil( $log_count / $per_page ); 		$current_url = LOGPLUG()->helpers->get_current_url(false);  		if( $page > $total_pages ){ 			$page = $total_pages; 		}  		if( $page < 1 ){ 			$page = 1; 		}  		$pagination_links_out = array();  		$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 1, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '<<', 'logs' ) . '</a>';  		if( $page <= 1 ){ 			$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 1, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '<', 'logs' ) . '</a>'; 		} else { 			$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => ($page-1), ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '<', 'logs' ) . '</a>'; 		} 		  		if( $total_pages > 3 ){ 			 			 			if( $page === 1 ){ 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 1, ) ) ) . '" class="primary btn--sm mr-1">' . 1 . '</a>'; 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 2, ) ) ) . '" class="secondary btn--sm mr-1">' . 2 . '</a>'; 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 3, ) ) ) . '" class="secondary btn--sm mr-1">' . 3 . '</a>'; 			} elseif( $page >= $total_pages ){ 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page-2, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page-2) . '</a>'; 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page-1, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page-1) . '</a>'; 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page, ) ) ) . '" class="primary btn--sm mr-1">' . $page . '</a>'; 			} else { 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page-1, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page-1) . '</a>'; 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page, ) ) ) . '" class="primary btn--sm mr-1">' . $page . '</a>'; 				$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page+1, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page+1) . '</a>'; 			}  			 			 		} else { 			$page_counter = 1; 			while( $total_pages > 0 ){  				if( $page_counter === $page ){ 					$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="primary btn--sm mr-1">' . $page_counter . '</a>'; 				} else { 					$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="secondary btn--sm mr-1">' . $page_counter . '</a>'; 				} 				 				$page_counter++; 			} 		} 		 		if( $page >= $total_pages ){ 			$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $total_pages, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '>', 'logs' ) . '</a>'; 		} else { 			$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => ($page+1), ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '>', 'logs' ) . '</a>'; 		}  		$pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $total_pages, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '>>', 'logs' ) . '</a>';  		return implode( '', $pagination_links_out ); 	}

public function pagination( $args = array() ) { $per_page = isset( $args['per_page'] ) ? intval( $args['per_page'] ) : 10; $page = isset( $args['log_page'] ) ? intval( $args['log_page'] ) : 1; $page_counter = 1; $log_count = $this->get_log_count(); $total_pages = ceil( $log_count / $per_page ); $current_url = LOGPLUG()->helpers->get_current_url(false); if( $page > $total_pages ){ $page = $total_pages; } if( $page < 1 ){ $page = 1; } $pagination_links_out = array(); $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 1, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '<<', 'logs' ) . '</a>'; if( $page <= 1 ){ $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 1, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '<', 'logs' ) . '</a>'; } else { $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => ($page-1), ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '<', 'logs' ) . '</a>'; } if( $total_pages > 3 ){ if( $page === 1 ){ $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 1, ) ) ) . '" class="primary btn--sm mr-1">' . 1 . '</a>'; $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 2, ) ) ) . '" class="secondary btn--sm mr-1">' . 2 . '</a>'; $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => 3, ) ) ) . '" class="secondary btn--sm mr-1">' . 3 . '</a>'; } elseif( $page >= $total_pages ){ $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page-2, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page-2) . '</a>'; $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page-1, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page-1) . '</a>'; $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page, ) ) ) . '" class="primary btn--sm mr-1">' . $page . '</a>'; } else { $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page-1, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page-1) . '</a>'; $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page, ) ) ) . '" class="primary btn--sm mr-1">' . $page . '</a>'; $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page+1, ) ) ) . '" class="secondary btn--sm mr-1">' . ($page+1) . '</a>'; } } else { $page_counter = 1; while( $total_pages > 0 ){ if( $page_counter === $page ){ $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="primary btn--sm mr-1">' . $page_counter . '</a>'; } else { $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $page_counter, ) ) ) . '" class="secondary btn--sm mr-1">' . $page_counter . '</a>'; } $page_counter++; } } if( $page >= $total_pages ){ $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $total_pages, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '>', 'logs' ) . '</a>'; } else { $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => ($page+1), ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '>', 'logs' ) . '</a>'; } $pagination_links_out[] = '<a href="' . LOGPLUG()->helpers->built_url( $current_url, array_merge( $_GET, array( 'item_count' => $per_page, 'log_page' => $total_pages, ) ) ) . '" class="btn--sm mr-1">' . LOGPLUG()->helpers->translate( '>>', 'logs' ) . '</a>'; return implode( '', $pagination_links_out ); }

Дополнительно:

Ошибка по строке:

Вообще-то ничего не значит. Память кто-то сожрал раньше, просто этой части кода уже не хватило. Только профилированием можно точно найти место утечки. Ну или угадать, загрузив в мозг весь код от начала до места, где память кончилась.

Как решить проблему с Allowed memory size в плагине Worpress?

Страниц на сайте много? Предположу, что проблема в пагинации...
Еще интересный момент в том, что цикл while создает ссылки для каждой страницы.

Я в php не силен, но быстрой гуглежкой нашел вариант логирования. Посмотрите, что будет писать и какое время займет различные части выполнения Вашего кода:
- Пишем сообщение непосредственно в файл журнала ошибок сервера:

error_log('Лог переменной: ' . print_r($var, true));

error_log('Лог переменной: ' . print_r($var, true));

- Получение временных меток перед и после выполнения кода:
microtime(true)

  • благодарю, я как-то не подумал про логирование
  • Minusator, так это первое, что необходимо делать при написание кода, чтобы хотя бы понимать, где ноги протянули ;)
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Игорь Волков Ответ

В показанном фрагменте главная проблема, скорее всего, в цикле пагинации. Если $total_pages большое или считается неправильно, код создаёт огромный массив $pagination_links_out со ссылками на все страницы. Даже если логов несколько строк, ошибка может быть не в логах, а в генерации тысяч или миллионов ссылок.

Сначала проверьте условие цикла. В норме должно быть ограничение по номеру страницы:

$page_counter = 1;
 
while ($page_counter <= $total_pages) {
    // link
    $page_counter++;
}

$page_counter = 1; while ($page_counter <= $total_pages) { // link $page_counter++; }

Если у вас условие выглядит как while ($total_pages > 0), но внутри $total_pages не уменьшается, это бесконечный цикл и память закончится неизбежно.

Вторая проблема — не нужно выводить ссылки на все страницы, если их много. Делайте окно вокруг текущей страницы:

$start = max(1, $page - 2);
$end   = min($total_pages, $page + 2);
 
for ($i = $start; $i <= $end; $i++) {
    $pagination_links_out[] = my_build_log_page_link($i);
}

$start = max(1, $page - 2); $end = min($total_pages, $page + 2); for ($i = $start; $i <= $end; $i++) { $pagination_links_out[] = my_build_log_page_link($i); }

Третье: не используйте весь $_GET без фильтрации. Соберите только разрешённые параметры, иначе можно раздуть URL и получить мусорные ссылки.

И ещё важный момент: логи нельзя грузить целиком в память. Читайте только нужную страницу через SQL LIMIT/OFFSET или построчно из файла. Тогда вкладка “Логи” будет открываться быстро даже при большом количестве записей.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно