@Borysenko

Зависает код на PHP, цикл перестаёт отрабатывать?

Есть XML файл на 3000 товаров. В нём есть таблица с категориями, у каждой есть свой id и parent_id. К каждому товару приписан category_id и category_name. Но у товаров написана только их текущая категория без иерархии родительских. И я написал такой код на выходе которого получаем у каждого товара в категории категория > под_категория > под_под категория и тп. Всё это дело работает. Но проблема в том что работает только с небольшим файлом а когда пытаюсь взять весь или даже половину оно доходит % до 30 и тупо виснет. Страничка продолжает загружаться а код не исполняется

<?php
set_time_limit(0);                   // ignore php timeout
ignore_user_abort(true);             // keep on going even if user pulls the plug*
while(ob_get_level())ob_end_clean(); // remove output buffers
ob_implicit_flush(true);             // output stuff directly

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


if (isset($_FILES['uploadedFile']) && $_FILES['uploadedFile']['error'] === UPLOAD_ERR_OK) {
    $fileTmpPath = $_FILES['uploadedFile']['tmp_name'];
    $fileName = $_FILES['uploadedFile']['name'];
    $fileSize = $_FILES['uploadedFile']['size'];
    $fileType = $_FILES['uploadedFile']['type'];
    $fileNameCmps = explode(".", $fileName);
    $fileExtension = strtolower(end($fileNameCmps));

    $newFileName = md5(time() . $fileName) . '.' . $fileExtension;

    $uploadFileDir = './uploaded_files/';
    $dest_path = $uploadFileDir . $newFileName;
    
    if(move_uploaded_file($fileTmpPath, $dest_path))
    {
        $message ='File is successfully uploaded.';

        $file = fopen($dest_path, 'r');

        $xmlstr = file_get_contents($dest_path);
        unlink($dest_path);

        $products_list = new SimpleXMLElement($xmlstr);

        echo "<pre>";
        
        $categories = [];
        foreach($products_list->xpath('categories') as $category):
            foreach($category->xpath('category') as $category):
                $categories[] = $category;
            endforeach;
        endforeach;
        var_dump(count($products_list->products_list->product));
        $processed = 0;
        $progress = 0;
        foreach ($products_list->xpath('products_list') as $product) :
            $products = $product->xpath('product');
            $all_count = count($products) ;
            foreach ($products as $product) :

                $cats = [];

                $parent_category = intval($product->category_id);
                
                while($parent_category != 0):
                    
                    foreach($categories as $category):
                        
                        if(intval($category->id) == $parent_category):
                            $cats[] = trim(strval($category->name));
                            $parent_category = intval($category->parent_id);
                        endif;
                        
                    endforeach;
                endwhile;

                $categories_output = "";
                $i = count($cats);
                while($i >= 0){
                    $categories_output.= $cats[$i];
                    if($i != 0 && $i != count($cats)): $categories_output.=" > "; endif;
                    $i--;
                }
                $product->category_name = $categories_output;
                // echo $categories_output ."<br>";
                $processed++;
                $cur_progress = intval($processed/$all_count * 100);
                if($progress !=  intval($cur_progress)){
                    $progress = intval($cur_progress);
                    echo $progress."%<br>";
                }  
                // var_dump($progress);
                // die();
             
            endforeach;
            
        endforeach;
        
        echo "</pre>";
                $file = "list-2.xml";
                
                if ($products_list->asXML($file)) {
                    echo 'Saved!<br>';
                } else {
                    echo 'Unable to save to file :(';
                };   
        // // Открываем файл в нужном нам режиме. Нам же, нужно его создать и что то записать.
        // $file = "sks_list-2.xml";
        
        // if ($products_list->asXML($file)) {
        //     echo 'Saved!';
        // } else {
        //     echo 'Unable to save to file :(';
        // };
    }
    else
    {
      $message = 'There was some error moving the file to upload directory. Please make sure the upload directory is writable by web server.';
    }
}


Вот мой код обработки. Выставил в php.ini 4000M и таймаут 9999 но все равно виснет. Подскажите что с этим поделать
  • Вопрос задан
  • 87 просмотров
Решения вопроса 4
Adamos
@Adamos
SimpleXML не годится для больших файлов. Для них лучше использовать XMLReader, который не строит в памяти все дерево, а читает узлы по одному. Вычитываете из файла категории и продукты, потом уже сопоставляете одно другому на чистом Пыхе.
Ответ написан
AleksandrB
@AleksandrB
Совсем недавно вывел "Hello world"
Перестаньте колдовать с лимитами и читайте файл в цикле построчно
Ответ написан
glaphire
@glaphire Куратор тега PHP
PHP developer
Длительные задачи нужно запускать консольным скриптом (потому что у консольного пхп нет ограничений по времени), или событием с фронтенда создавать задачу в очередь сообщений, которая отработает в фоне.
Ответ написан
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Во первых - как отче наш первым делом включаем вывод ошибок, гадание на хрустальном шаре не наш метод. Во вторых - читайте ответ Adamos, ридер попроще функционалом, но работает быстрее и памяти ест в разы меньше.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы