Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

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


Recommended Posts

Все банально и просто, нужно парсить страницы сайта и делать импорт (апдейт) категорий и товаров, уже нереально намучался т.к. при выполнении скрипта дольше около 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() видно что значения правильные.

Надіслати
Поділитися на інших сайтах


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

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

 

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

Надіслати
Поділитися на інших сайтах

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

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

 

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

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

Надіслати
Поділитися на інших сайтах


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

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

Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.