Тайм-аут запроса PHP для простой функции

У меня есть эта функция, которая вычисляет балансовую стоимость основных средств с использованием данных из таблицы амортизации, Ii отлично работает на локальном хосте, но когда я пытался продолжить производство, я получаю `` тайм-аут запроса '' после долгой загрузки, я Думаю, я испортил цикл или что-то в этом роде, и будет здорово, если кто-нибудь предложит оптимизацию кода или взлом, чтобы сделать эту функцию быстрее.

Я попытался ограничить количество записей в цикле, и это сработало, но, к сожалению, мне нужно обработать более 20 000 данных.

    $cat = null;
    $total_a = null;
    $assets = $this->Depreciation->get_all();

    if (!empty($assets)) {
        foreach ($assets as $asset) {

            $cost = $asset->cost + $asset->add_cost + $asset->adj_cost;
            $salve = $asset->salvage_value;
            $life = $asset->life;
            $life_t = 0;
            $counter = 0;
            $date1 = date('Y-12-31');
            $date2 = $asset->in_service;

            $diff = abs(strtotime($date2) - strtotime($date1));

            $years = floor($diff / (365 * 60 * 60 * 24));
            $months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));

            $in_service_d = date('Y-12-31');


            if ($asset->rev > 0) {
                $cost = $asset->rev;
            }


            $dep1 = ($cost - $salve) / $life * ($months / 12);
            $dep = ($cost - $salve) / $life;


            $total = 0;
            $year = 1;


            for (; $cost > $salve;) {
                if ($year == 1 && $months < 12) {
                    $life_t++;
                    $year++;
                    $cost = $cost - $dep1;
                    $counter++;
                    $total = $dep1 + $total;

                    if ($in_service_d == date('Y-12-31')){
                        $total_a = $total_a + $cost;
                    }

                    $in_service_d = date('Y-12-31', strtotime("+12 months", strtotime($in_service_d)));


                } elseif ($year != 1) {
                    $life_t++;
                    if ($life_t > $life) {
                        $dep = $dep - $dep1;
                    }
                    $cost = $cost - $dep;
                    $counter++;
                    $total = $dep + $total;

                    if ($in_service_d == date('Y-12-31')){
                        $total_a = $total_a + $cost;
                    }

                    $in_service_d = date('Y-12-31', strtotime("+12 months", strtotime($in_service_d)));

                }

            }

        }

    }

     return $total_a;

Если не задействованы никакие операции с базой данных, 20 000 строк не являются особенно большим набором данных. Я еще не изучил всю логику программы, но цикл выполняется до тех пор, пока $cost больше, чем $salve. Вы уверены, что либо $cost выходит из строя, либо $salve поднимается на всех итерациях?

Koala Yeung 30.08.2018 12:21

Один совет: логика вашей программы слишком сложна для тестирования. Я бы порекомендовал вам разбить вашу логику на более мелкие функции и протестировать каждую из них. Таким образом у вас будет больше уверенности в том, что делает каждая часть.

Koala Yeung 30.08.2018 12:24

Стоимость снижается $cost = $cost - $dep1; или $cost = $cost - $dep; в зависимости от «$ Year» на каждой итерации.

Sayd Fuad 30.08.2018 12:25

Подозреваю, что проблема в цикле, но я не могу понять, как этот цикл занимает так много времени всего на 21 запись.

Sayd Fuad 30.08.2018 12:29

Можно ли получить данные для примера $asset? Трудно понять логику вашей программы.

Koala Yeung 30.08.2018 12:38

Кроме того, это помогает, если вы используете var_dump для некоторых ключевых переменных в вашем цикле. Обычно это помогает отследить причину проблемы. Бьюсь об заклад, $cost не так, как вы ожидали.

Koala Yeung 30.08.2018 12:41

Вы имеете в виду так: unsee.cc/ffb26821

Sayd Fuad 30.08.2018 12:52

Я попробовал одно из ваших данных и запустил его 20000 раз. И это заканчивается за 8 секунд. Так что я не думаю, что это безумно долгое вычисление. Я думаю, что, вероятно, есть одна конкретная строка, которая вызвала проблему. Я бы посоветовал вам поместить var_dump($asset->a_id); в начало вашего цикла foreach. Затем запустите и посмотрите, какой актив вас застрял.

Koala Yeung 30.08.2018 15:01

Нашел одну логическую проблему. Цикл for будет продолжаться вечно, если $months больше 12. Не уверен, действительно ли это происходит, ты.

Koala Yeung 30.08.2018 15:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
9
43
1

Ответы 1

Ваш друг - функция set_time_limit().

У меня был аналогичный сценарий экспорта отформатированного файла Excel из большой базы данных. У сценария всегда не хватало времени, если он превышал 1000 строк.

В разделе моей логики loop я установил следующее:

set_time_limit(30);

Что увеличило бы разрешенное время для бега еще на 30 секунд с этого момента.

У меня заканчивается время всего с 21 записью. Когда вы добавляете эту функцию, как насчет пользовательского опыта? Я думаю, что пользователю придется подождать некоторое время для завершения операции, и, к сожалению, эта функция запускается сразу после входа в мое приложение.

Sayd Fuad 30.08.2018 12:34

Мое требование заключалось в сценарии загрузки, поэтому от пользователя было четкое предупреждение, что им придется немного подождать. Вы уверены, что ваш скрипт завершится после 21 записи? Но на локальном хосте он работает нормально? Какой тайм-аут скрипта на сервере? И каков размер полного набора данных, который необходимо обработать? Может быть проблема с объемом памяти?

Nyamul 30.08.2018 15:27

Другие вопросы по теме