Jump to content
Sign in to follow this  
grd16

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

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-а, ни в логах Апача

Share this post


Link to post
Share on other sites

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

 

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

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

Share this post


Link to post
Share on other sites

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

 

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

 

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

Share this post


Link to post
Share on other sites

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

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

 

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
You are posting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×

Important Information

On our site, cookies are used and personal data is processed to improve the user interface. To find out what and what personal data we are processing, please go to the link. If you click "I agree," it means that you understand and accept all the conditions specified in this Privacy Notice.