Перейти к содержанию
grd16

Ошибка при длительном выполнении скрипта

Рекомендуемые сообщения

Все банально и просто, нужно парсить страницы сайта и делать импорт (апдейт) категорий и товаров, уже нереально намучался т.к. при выполнении скрипта дольше около 30-35 секунд его работа обрывается и получаю в броузере ошибку "Веб-страница недоступна" (ERR_CONNECTION_RESET). Помогите понять почему такое происходит, все PHP конфиги установлены верно:

max_execution_time = 3600
max_input_time = 3600
memory_limit = 512M
 
На всякий даже в скрипте устанавливаю лимиты:
ini_set("memory_limit","200M");
ini_set("max_execution_time",3600);
set_time_limit(3600);

 

Код контроллера:

<?php

class ControllerToolBrainupdate extends Controller {
    private $error = array();

    public function index() {
        $this->document->setTitle("бла бла бла");
        $this->load->model('tool/brainupdate');
        $res = array();
        if (($this->request->server['REQUEST_METHOD'] == 'POST') && ($this->validate())) {
            if ($this->model_tool_brainupdate->autorization()) {
                $res = $this->model_tool_brainupdate->updateCategories();
                if($res['status']) {
                    $res = $this->model_tool_brainupdate->updateProducts();
                    $this->session->data['success'] = "бла бла бла!";
                    $this->redirect($this->url->link('tool/brainupdate', 'token=' . $this->session->data['token'], 'SSL'));
                } else {
                    $this->error['warning'] = "бла бла бла";
                }
            } else {
                $this->error['warning'] = "бла бла бла :(";
            }
        }

        $this->data['result'] = $res;
        $this->data['action'] = $this->url->link('tool/brainupdate', 'token=' . $this->session->data['token'], 'SSL');

        if (isset($this->error['warning'])) {
            $this->data['error_warning'] = $this->error['warning'];
        } else {
            $this->data['error_warning'] = '';
        }

        if (isset($this->session->data['success'])) {
            $this->data['success'] = $this->session->data['success'];

            unset($this->session->data['success']);
        } else {
            $this->data['success'] = '';
        }

        $this->data['breadcrumbs'] = array();

        $this->data['breadcrumbs'][] = array(
            'text'      => $this->language->get('text_home'),
            'href'      => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'),
            'separator' => FALSE
        );

        $this->data['breadcrumbs'][] = array(
            'text'      => "Обновление цен и категорий с BRAIN",
            'href'      => $this->url->link('tool/brainupdate', 'token=' . $this->session->data['token'], 'SSL'),
            'separator' => ' :: '
        );

        $this->template = 'tool/brainupdate.tpl';
        $this->children = array(
            'common/header',
            'common/footer',
        );
        $this->response->setOutput($this->render());
    }

    private function validate() {
        if (!$this->user->hasPermission('modify', 'tool/brainupdate')) {
            $this->error['warning'] = $this->language->get('error_permission');
        }

        if (!$this->error) {
            return TRUE;
        } else {
            return FALSE;
        }
    }
}

Модель

<?php
include 'simple_html_dom.php';

class ModelToolBrainupdate extends Model {

    const COUNT_BY = 500;
    const START_FROM = 0;

    var $BRAIN_URL = "http://www.бла";
    var $LOGIN =  "бла";
    var $PASSWORD = "бла";

    private static $CATEGORIES = array();
    private static $currentCategoryID = 0;

    function autorization() {
        $data = str_get_html($this->makeGetRequest($this->BRAIN_URL . "/index.php?id=startpage&user=" .
            $this->LOGIN . "&pass=" .
            $this->PASSWORD . "&submit.x=12&submit.y=13&logintype=login&pid=6", true));
        return strcmp($data->find("#rTD #rt_4 .rBlD1 .rBlD3", 1) -> plaintext, $this->LOGIN) == 0;
    }

    function updateCategories() {
        $database =& $this->db;
        //update categories
        $data = str_get_html($this->makeGetRequest($this->BRAIN_URL . "/?id=products_cat&category=first", false));
        $categories = $data->find("#rt_3 .dtree script", 0) -> innertext;
        $categories = substr($categories, strpos($categories, "d.add(0,-1,''); ") + strlen("d.add(0,-1,''); "));
        $categories = trim(str_replace("  document.write(d);", "", $categories));
        $categories = preg_replace("/d.add\((([\d]*),([\d]*),\'(.*?)\',\'(.*?)\')\);/i", "$1\n" , $categories);
        $categories = preg_split("/\n/", $categories);

        foreach ($categories as $category) {
            $categoryID = trim(preg_replace("/([\d]*),([\d]*),\'(.*?)\',\'(.*?)\'/", "$1" , trim($category)));
            $parentCategoryID = trim(preg_replace("/([\d]*),([\d]*),\'(.*?)\',\'(.*?)\'/", "$2" , trim($category)));
            $categoryName = trim(preg_replace("/([\d]*),([\d]*),\'(.*?)\',\'(.*?)\'/", "$3" , trim($category)));
            $categoryURL = trim(preg_replace("/([\d]*),([\d]*),\'(.*?)\',\'(.*?)\'/", "$4" , trim($category)));
            $realCategoryID = preg_split("/\=/", $categoryURL);
            $realCategoryID = $realCategoryID[count($realCategoryID) - 1];
            if (empty($categoryID) || empty($categoryName)) {
                continue;
            }
            self::$CATEGORIES[$realCategoryID] = array(
                'category_id'=> $categoryID,
                'parent_id' => $parentCategoryID,
                'name' => $categoryName);
        }
        return $this->importCategoriesIntoDatabase($database, self::$CATEGORIES);
    }

    function updateProducts() {
        ini_set("memory_limit","200M");
        ini_set("max_execution_time",3600);
        set_time_limit(3600);
        $database =& $this->db;
        $data = str_get_html($this->makeGetRequest($this->BRAIN_URL . "/index.php?3&backPID=3&begin_at=" . self::START_FROM, false));
        $this->importProductsIntoDatabase($database, $this->getProductsList($data));
        $end = $data->find("#informPaneTD #nextPrevCell a");
        unset($data);
        $end = explode("=", end($end) -> getAttribute ("href"));
        $end = end($end);
        //for ($i = 1; $i <= $end / self::COUNT_BY; $i++) {

        for ($i = 1; $i <= 2; $i++) {
            $data = str_get_html($this->makeGetRequest($this->BRAIN_URL . "/index.php?3&backPID=3&begin_at=" . (self::COUNT_BY * $i), false));
            $this->importProductsIntoDatabase($database, $this->getProductsList($data));
            //sleep(2);
        }
        return TRUE;
    }

    function getProductsList(&$data) {
        $products = array();
        $elements = $data->find("#informPaneTD #newsCell tr td.prT, #informPaneTD #newsCell tr td.prTl");
        foreach ($elements as $element) {
            if (strcmp($element -> attr["class"], "prT") == 0) {
                $categoryID = explode("=",$element -> find("#n1 a", 0) -> getAttribute("href"));
                self::$currentCategoryID = end($categoryID);
                if(!array_key_exists (self::$currentCategoryID, self::$CATEGORIES)) {
                    self::$currentCategoryID = 0;
                }
            } else if (strcmp($element -> attr["class"], "prTl") == 0) {
                if (self::$currentCategoryID == 0) {
                    continue;
                } else {
                    $productID = explode("=", $element -> find("a", 0) -> getAttribute ("href"));
                    array_push($products, array(
                        'product_id'=> end($productID),
                        'name' => $element -> find("#n2", 0) -> plaintext,
                        'category_id' => self::$CATEGORIES[self::$currentCategoryID]["category_id"],
                        'quantity' => 100,
                        'price' => $element -> find("#n3", 0) -> plaintext,
                        'stock_status_id' => 7));
                }
            }
        }
        return $products;
    }

    private function importProductsIntoDatabase( &$database, $products )
    {
        $res = array('status' => false,
            'prod_add' => 0, 'prod_update' => 0);

        // find the default language id
        $languageId = $languageId = '1';

        // start transaction, remove products
        $sql = "START TRANSACTION;\n";
        $sql.= "UPDATE `".DB_PREFIX."product` SET `stock_status_id`=5, `quantity`=0, `status`=0;\n";
        $this->multiquery( $database, $sql );

        // generate and execute SQL for storing the products
        foreach ($products as $product) {
            $sql = "SELECT product_id FROM `".DB_PREFIX."product` WHERE `product_id`=\"".$product['product_id']."\";";
            $result = $database->query( $sql );
            if ($result->rows) {
                $sql = "UPDATE  `".DB_PREFIX."product` SET `status`=1, `stock_status_id`=".$product['stock_status_id'].", `quantity`=".$product['quantity'].", `price`=".trim($product['price'])." WHERE `product_id`=\"".$product['product_id']."\";";
                $database->query($sql);
                $res['prod_update']++;
            } else {
                $productId = $product['product_id'];
                $productName = $database->escape($product['name']);
                $categoryId = $product['category_id'];
                $quantity = $product['quantity'];
                $model = $database->escape($product['name']);
                $price = trim($product['price']);
                $stockStatusId = $product['stock_status_id'];

                $dateAdded = date("y-m-d");
                $dateModified = date("y-m-d H:i:s");
                $dateAvailable = date("y-m-d H:i:s");

                $productDescription = '';
                $manufacturerId = '0';
                $imageName = '';
                $shipping = '1';
                $points = '0';
                $weight = '0';
                $weightClassId = '0';
                $status = '1';
                $taxClassId = '0';
                $viewed = '0';
                $meta_description = '';
                $length = '0.0';
                $width = '0.0';
                $height = '0.0';
                $seo_title = '';
                $seo_h1 = '';
                $lengthClassId = '1';
                $sku = '';
                $upc = '';
                $ean = '';
                $jan = '';
                $isbn = '';
                $mpn = '';
                $location = '';
                $storeId = '0';
                $subtract = '1';
                $minimum = '1';
                $meta_keywords = '';
                $tags = '';
                $sort_order = '1';

                $sql  = "INSERT INTO `".DB_PREFIX."product` (`product_id`,`quantity`,`sku`,`upc`,`ean`,`jan`,`isbn`,`mpn`,`location`,";
                $sql .= "`stock_status_id`,`model`,`manufacturer_id`,`image`,`shipping`,`price`,`points`,`date_added`,`date_modified`,`date_available`,`weight`,`weight_class_id`,`status`,";
                $sql .= "`tax_class_id`,`viewed`,`length`,`width`,`height`,`length_class_id`,`sort_order`,`subtract`,`minimum`) VALUES ";
                $sql .= "($productId,$quantity,'$sku','$upc','$ean','$jan','$isbn','$mpn','$location',";
                $sql .= "$stockStatusId,'$model',$manufacturerId,'$imageName',$shipping,$price,$points,";
                $sql .= ($dateAdded=='NOW()') ? "$dateAdded," : "'$dateAdded',";
                $sql .= ($dateModified=='NOW()') ? "$dateModified," : "'$dateModified',";
                $sql .= ($dateAvailable=='NOW()') ? "$dateAvailable," : "'$dateAvailable',";
                $sql .= "$weight,$weightClassId,$status,";
                $sql .= "$taxClassId,$viewed,$length,$width,$height,'$lengthClassId','$sort_order','$subtract','$minimum');";
                $sql2 = "INSERT INTO `".DB_PREFIX."product_description` (`product_id`,`language_id`,`name`,`description`,`meta_description`,`meta_keyword`,`tag`,`seo_title`,`seo_h1`) VALUES ";
                $sql2 .= "($productId,$languageId,'$productName','$productDescription','$meta_description','$meta_keywords','$tags','$seo_title','$seo_h1');";
                $sql3 = "INSERT INTO `".DB_PREFIX."product_to_category` (`product_id`,`category_id`) VALUES ($productId,$categoryId)";
                $sql4 = "INSERT INTO `".DB_PREFIX."product_to_store` (`product_id`,`store_id`) VALUES ($productId,$storeId);";
                $database->query($sql);
                $database->query($sql2);
                $database->query($sql3);
                $database->query($sql4);
                $res['prod_add']++;
            }
        }

        // final commit
        $database->query("COMMIT;");
        $res['status'] = true;
        return $res;
    }

    private function importCategoriesIntoDatabase( &$database, &$categories )
    {
        $res = array('status' => false,
            'cat_add' => 0, 'cat_update' => 0);
        // start transaction, remove categories
        $sql = "START TRANSACTION;\n";
        $sql.= "UPDATE `".DB_PREFIX."category` SET `status`=0;\n";
        $this->multiquery( $database, $sql );

        // generate and execute SQL for inserting the categories
        foreach ($categories as $category) {
            $sql = "SELECT category_id FROM `".DB_PREFIX."category` WHERE `category_id`=\"".$category['category_id']."\";";
            $result = $database->query( $sql );
            if ($result->rows) {
                $sql = "UPDATE  `".DB_PREFIX."category` SET `status`=1 WHERE `category_id`=\"".$category['category_id']."\";";
                $database->query($sql);
                $res['cat_update']++;
            } else {
                $categoryId = $category['category_id'];
                $parentId = $category['parent_id'];
                $name = $database->escape($category['name']);

                $dateAdded = date("y-m-d H:i:s");
                $dateModified = date("y-m-d H:i:s");

                $languageId = '1';
                $imageName = '';
                $top = '0';
                $columns = '1';
                $sortOrder = '0';
                $description = '';
                $meta_description = '';
                $meta_keywords = '';
                $seo_title = '';
                $seo_h1 = '';
                $storeId = '0';
                $status = '1';
                $sql2 = "INSERT INTO `".DB_PREFIX."category` (`category_id`, `image`, `parent_id`, `top`, `column`, `sort_order`, `date_added`, `date_modified`, `status`) VALUES ";
                $sql2 .= "( $categoryId, '$imageName', $parentId, $top, $columns, $sortOrder, ";
                $sql2 .= ($dateAdded=='NOW()') ? "$dateAdded," : "'$dateAdded',";
                $sql2 .= ($dateModified=='NOW()') ? "$dateModified," : "'$dateModified',";
                $sql2 .= " $status);";
                $database->query( $sql2 );
                $sql3 = "INSERT INTO `".DB_PREFIX."category_description` (`category_id`, `language_id`, `name`, `description`, `meta_description`, `meta_keyword`, `seo_title`, `seo_h1`) VALUES ";
                $sql3 .= "( $categoryId, $languageId, '$name', '$description', '$meta_description', '$meta_keywords', '$seo_title', '$seo_h1' );";
                $database->query( $sql3 );
                $sql4 = "INSERT INTO `".DB_PREFIX."category_to_store` (`category_id`,`store_id`) VALUES ($categoryId,$storeId);";
                $database->query($sql4);
                $res['cat_add']++;
            }
        }

        // final commit
        $database->query( "COMMIT;" );
        $res['status'] = true;
        return $res;
    }

    private function multiquery( &$database, $sql ) {
        foreach (explode(";\n", $sql) as $sql) {
            $sql = trim($sql);
            if ($sql) {
                $database->query($sql);
            }
        }
    }

    private function makeGetRequest($URL, $saveCookie) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $URL ); // отправляем на
        curl_setopt($ch, CURLOPT_HEADER, 0); // пустые заголовки
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул сервер
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректами
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);// таймаут
        if ($saveCookie) {
            curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER['DOCUMENT_ROOT'] . '/cookie.txt'); // сохранять куки в файл
        } else {
            curl_setopt($ch, CURLOPT_COOKIEFILE,  $_SERVER['DOCUMENT_ROOT'] . '/cookie.txt');
        }
        $html = iconv("windows-1251", "utf-8", curl_exec($ch));
        curl_close($ch);
        return $html;
    }
}

при входе в цикл for ($i = 1; $i <= 2; $i++) происходит это разъединение, ни каких ошибок в логах нет, ни в системном логе openCart-а, ни в логах Апача

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Случайно не Львовский Brain Computers парсите? :) Я когда с ними работал (года 2 назад) они свой оптовый прайс предоставляли для оптовых покупателей, я тогда парсил готовый прайс, а картинки брал с сайта по вроде артикулу, уже не помню. 

 

ПО сабжу, возможно действительно памяти не хватает. Попробуйте время выполнения изменить в php.ini - того что в /etc, а не в к корне сайта. Так как если скрипт запускается на хостинге то возможно хостинг блокирует изменение этого параметра, так как иначе каждый пользователь сможет себе выставить время выполнения 3 часа и положит сервер..

Или если нету доступа до сервера то попробуйте на локалхосте, там время можно хоть сутки выставить.. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Случайно не Львовский Brain Computers парсите? :) Я когда с ними работал (года 2 назад) они свой оптовый прайс предоставляли для оптовых покупателей, я тогда парсил готовый прайс, а картинки брал с сайта по вроде артикулу, уже не помню. 

 

ПО сабжу, возможно действительно памяти не хватает. Попробуйте время выполнения изменить в php.ini - того что в /etc, а не в к корне сайта. Так как если скрипт запускается на хостинге то возможно хостинг блокирует изменение этого параметра, так как иначе каждый пользователь сможет себе выставить время выполнения 3 часа и положит сервер..

Или если нету доступа до сервера то попробуйте на локалхосте, там время можно хоть сутки выставить.. 

нужно парсить именно с сайта, пока что выполняется локально, max_execution_time = 3600, в phpinfo() видно что значения правильные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может есть хоть какие - то догадки?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что нам ваше "Веб-страница недоступна" ?

это "пояснение статуса ответа сервера / заголовка".

 

логи смотрите - там все расписано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что нам ваше "Веб-страница недоступна" ?

это "пояснение статуса ответа сервера / заголовка".

 

логи смотрите - там все расписано.

в логах - пустота, писал об этом выше

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

m$форточки стоят?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

m$форточки стоят?

ага, выполняется локально

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

по ERR_CONNECTION_RESET "гоша" шлет (в основном) на virusinfo за диагнозом и таблетками.

может быть и проблема с драйверами, и провайдер, и вирусы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×

Важная информация

На нашем сайте используются файлы cookie и происходит обработка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфиденциальности.