Jump to content

Recommended Posts

49 минут назад, Yesvik сказал:

То что product не надо в файловый кеш писать - всё правильно.

 

Основная идея SEO_PRO в наличии основной категории, а остальное у меня давно переписано )

Вот эта часть кода упрощена...

  Показать контент


		switch ($route) {
			case 'product/product':
				if (isset($data['product_id'])) {
					$tmp = $data;
					$data = array();
					if ($this->config->get('config_seo_url_include_path')) {
						$data['path'] = $this->getPathByProduct($tmp['product_id']);
						if (!$data['path']) return $link;
					}
					$data['product_id'] = $tmp['product_id'];
					$seo_pro_utm = preg_replace('~\r?\n~', "\n", $this->config->get('config_seo_pro_utm'));
					$allowed_parameters = explode("\n", $seo_pro_utm);
					foreach($allowed_parameters as $ap) {
						if (isset($tmp[trim($ap)])) {
							$data[trim($ap)] = $tmp[trim($ap)];
						}
					}
				}
				break;

			case 'product/category':
				if (isset($data['path'])) {
					$category = explode('_', $data['path']);
					$category = end($category);
					$data['path'] = $this->getPathByCategory($category);
					if (!$data['path']) return $link;
				}
				break;

			case 'product/product/review':
			case 'information/information/agree':
				return $link;
				break;

			default:
				break;
		}

		if ($component['scheme'] == 'https') {
			$link = $this->config->get('config_ssl');
		} else {
			$link = $this->config->get('config_url');
		}

		$link .= 'index.php?route=' . $route;

		if (count($data)) {
			$link .= '&' . urldecode(http_build_query($data, '', '&'));
		}

		$queries = array();
		if(!in_array($route, array('product/search'))) {
		foreach ($data as $key => $value) {
				switch ($key) {
					case 'product_id':
					case 'manufacturer_id':
					case 'category_id':
					case 'information_id':
					case 'order_id':
						$queries[] = $key . '=' . $value;
						unset($data[$key]);
						$postfix = 1;
						break;

					case 'path':
						$categories = explode('_', $value);
						foreach ($categories as $category) {
							$queries[] = 'category_id=' . $category;
						}
						unset($data[$key]);
						break;

					default:
						break;
				}
			}
		}


		if(empty($queries)) {
			$queries[] = $route;
		}

		$rows = array();
		foreach($queries as $query) {
			if(isset($this->cache_data['queries'][$query])) {
				$rows[] = array('query' => $query, 'keyword' => $this->cache_data['queries'][$query]);
			}
		}

		if(count($rows) == count($queries)) {
			$aliases = array();
			foreach($rows as $row) {
				$aliases[$row['query']] = $row['keyword'];
			}
			foreach($queries as $query) {
				$seo_url .= '/' . rawurlencode($aliases[$query]);
			}
		}

 

 

... потому что:

Одним запросом выполняется выборка готового seo_url товара, т.е. на выходе строка category/subcategory/subsubcategory/product

 

Одним запросом выполняется выборка готовых seo_url для всех категорий, причем в виде одной json_encode строки...

Сейчас объясню для чего такой изврат

Во первых БД возвращает 1 строку быстрее (и пофиг что она большая)

Для сравнения:

выборка одной json_encode строкой 1200 категорий с соответствующими им path в виде

image.thumb.png.b5a228e50a2d8106741cc629fa882121.png

и простая выборка category_id по индексу, для тех же 1200 категорий, вот таким запросом: SELECT `category_id` FROM `oc_category`

image.png.7823f3e628c092b8e3fa3061a494c8cc.png

Выборка json_encode строки в 7,5 раз быстрее ;)

 

Во вторых получив много строк - нарываемся на цикл в system/library/db/mysql.php


while ($result = mysql_fetch_assoc($resource)) {
	$data[$i] = $result;
	$i++;
}

В третьих вынуждены ещё раз обойти в цикле все записи для формирования массива в виде 'category_id' => 'готовый seo_url', что-то типа такого:


$data = array();
foreach ($query->rows as $row) {
	$data[$row['category_id']] = $row['seo_url'];
}

Вместо всех этих циклов просто $data = json_decode($query->row['data']) и массив готов, его можно кидать в кеш на очень долго... кеш будет актуален пока не изменишь категорию... а при изменении категории кеш удалится.

 

Времени не хватает допилить возможность использовать одинаковые алиасы в разных ветках категорий... допилю - выложу

а чего Данила Хер это не пропустит, (не исключаю тот факт , что это всё ему уже предлогали)
чем он это  оправдывает?
например если для огромного количества товаров сделать допом отключение кэша и наоборот. или нафиг его для продукт вообще.. хз..
Это из того что я слышал про сеопро когда он сталкивается с большим кол-вом товаров - тупо автоматом переключать на без кэшье)) когда товаров уже столько-то и\или категорий и т.д.
..
чего он упирается то?
и давно бы эта битва закончилась
 

Share this post


Link to post
Share on other sites
8 часов назад, esculapra сказал:

я разработчик и знаю, что получу шнягу

Извини, не удержался вырвать из контекста )

 

Не всё выводится через view и response... есть модуль который пишет фид в файл - как будешь рерайтить?

 

$array_categories = explode('_', $value);
foreach ($array_categories as $category_id) {
	if (isset($this->settings["category_id=" . $category_id]))
		$url .= $this->settings["category_id=" . $category_id] . '/';
	else
		$url = '';
}

Допустим у нас &path=11_22_33, для категории 22 не задан алиас, какой будет url?

 

case 'product_id':
	$query	 = $this->db->query("SELECT * FROM `" . DB_PREFIX . "url_alias` WHERE `query`='" . $this->db->escape('product_id=' . (int) $value) . "'");
	if ($query->num_rows && $query->row['keyword'])
		$url	 .= $query->row['keyword'];
	unset($data['product_id']);
break;

Если в линке задан path, но для товара не задан алиас - какой будет url?

 

Многие модули генерят линки на товары вот так: $this->url->link('product/product', 'product_id=' . $result['product_id'])

Как будешь path строить?

 

А будет модуль редиректить на правильную ссылку?

Например товар из категории 11111/2222 перенесли в категорию 33333/4444 - будет редиректить?

 

SEO_PRO это не рерайтер, точнее рерайт это второстепенный функционал.

 

  • +1 1

Share this post


Link to post
Share on other sites
3 часа назад, AWARO сказал:

например если для огромного количества товаров сделать допом отключение кэша и наоборот. или нафиг его для продукт вообще

там проблема не  в количестве товаров, просто при большом количестве товаров проблема явно видна... при малом количестве товара и большом трафике тоже будут проблемы... как говорится нефиг в файловый кеш дописывать )

  • +1 1

Share this post


Link to post
Share on other sites
4 часа назад, AWARO сказал:

а чего Данила Хер это не пропустит,

Ему предлагали в 11 году, но он во первых упрямый, а во вторых - что такое Яндекс он вообще не знал, и ему пофиг что в Яше были проблемы.

  • +1 1

Share this post


Link to post
Share on other sites
В 23.09.2019 в 23:26, Yesvik сказал:

Времени не хватает допилить возможность использовать одинаковые алиасы в разных ветках категорий... допилю - выложу

Да, ты прав, но не уловил саму идею

Я беру массив ссылок на этапе респонсера регуляркой $regexp='/(index.php\?route){1}(;|\s|\w|\d|=|\'|\/|\.|-|&|_|\?)++(")/sUi'; Потом удаляю дубли $matches[0] = array_unique($matches[0]); и делаю реврайт. В результе я переделываю все ссылки, что не получается при использовании стандарта.

Share this post


Link to post
Share on other sites
В 24.09.2019 в 04:00, Yesvik сказал:

Многие модули генерят линки на товары вот так: $this->url->link('product/product', 'product_id=' . $result['product_id'])

Как будешь path строить?

А мой сделает, даже если этот мод не схавает.

Share this post


Link to post
Share on other sites
В 24.09.2019 в 04:00, Yesvik сказал:

Например товар из категории 11111/2222 перенесли в категорию 33333/4444 - будет редиректить?

проверяется алиас по product_idт - остальное на севести хозяина.

Share this post


Link to post
Share on other sites
В 24.09.2019 в 04:00, Yesvik сказал:

Допустим у нас &path=11_22_33, для категории 22 не задан алиас, какой будет url?

Мой мод вернет ориджинал, но могу подключить транслит, а зачем? В аджминке все легко - там транслит уже все делает - остается только зафиксировать. не указанный алиас отображается красным.

sef_manafer.jpg

Share this post


Link to post
Share on other sites
2 минуты назад, esculapra сказал:

 

 

нафига по умолчанию префикс страниц  html ?
во дворе 19 на носу 20й

Share this post


Link to post
Share on other sites

у меня в изначалке был предусмотрен выбор (html, mhtml, asp. php и т.п.)

Share this post


Link to post
Share on other sites
33 минуты назад, esculapra сказал:

Я беру массив ссылок на этапе респонсера регуляркой

ну-ну

Share this post


Link to post
Share on other sites
9 часов назад, esculapra сказал:

А мой сделает, даже если этот мод не схавает.

В коде, который ты выложил, я не вижу алгоритма построения категорий для товаров если в линке не указан path. Рассказать чем это чревато?

Share this post


Link to post
Share on other sites
9 часов назад, esculapra сказал:
В 24.09.2019 в 04:00, Yesvik сказал:

Допустим у нас &path=11_22_33, для категории 22 не задан алиас, какой будет url?

Мой мод вернет ориджинал, но могу подключить транслит, а зачем? В аджминке все легко - там транслит уже все делает - остается только зафиксировать. не указанный алиас отображается красным. 

Объясняю что и как делает твой код...

Есть категория с category_id=11, подкатегория с category_id=22 и подподкатегория с category_id=33.

Для category_id=11 задан алиас category

Для category_id=22 не задан алиас

Для category_id=33 задан алиас subcategory

Твой алгоритм построит subcategory и это не правильно

 

Описываю вариант когда для категории 33 не задан алиас

Для category_id=11 задан алиас category

Для category_id=22 задан алиас subcategory

Для category_id=33 не задан алиас

Твой алгоритм построит пустую строку!

 

А в случае когда у товара нет алиаса твой алгоритм, в лучшем случае, построит ссылку на категорию, а не на товар.

 

Share this post


Link to post
Share on other sites
10 часов назад, esculapra сказал:

Да, ты прав, но не уловил саму идею

Я беру массив ссылок на этапе респонсера регуляркой $regexp='/(index.php\?route){1}(;|\s|\w|\d|=|\'|\/|\.|-|&|_|\?)++(")/sUi'; Потом удаляю дубли $matches[0] = array_unique($matches[0]); и делаю реврайт. В результе я переделываю все ссылки, что не получается при использовании стандарта.

Я прекрасно понял твою идею, поэтому и спросил: как будешь рерайтить линки если нет вьюхи и вывод идёт мимо респонз, например пишешь в файл...

Share this post


Link to post
Share on other sites

удалил

Share this post


Link to post
Share on other sites
В 23.09.2019 в 23:26, Yesvik сказал:

То что product не надо в файловый кеш писать - всё правильно.

 

Основная идея SEO_PRO в наличии основной категории, а остальное у меня давно переписано )

Вот эта часть кода упрощена...

  Показать контент


		switch ($route) {
			case 'product/product':
				if (isset($data['product_id'])) {
					$tmp = $data;
					$data = array();
					if ($this->config->get('config_seo_url_include_path')) {
						$data['path'] = $this->getPathByProduct($tmp['product_id']);
						if (!$data['path']) return $link;
					}
					$data['product_id'] = $tmp['product_id'];
					$seo_pro_utm = preg_replace('~\r?\n~', "\n", $this->config->get('config_seo_pro_utm'));
					$allowed_parameters = explode("\n", $seo_pro_utm);
					foreach($allowed_parameters as $ap) {
						if (isset($tmp[trim($ap)])) {
							$data[trim($ap)] = $tmp[trim($ap)];
						}
					}
				}
				break;

			case 'product/category':
				if (isset($data['path'])) {
					$category = explode('_', $data['path']);
					$category = end($category);
					$data['path'] = $this->getPathByCategory($category);
					if (!$data['path']) return $link;
				}
				break;

			case 'product/product/review':
			case 'information/information/agree':
				return $link;
				break;

			default:
				break;
		}

		if ($component['scheme'] == 'https') {
			$link = $this->config->get('config_ssl');
		} else {
			$link = $this->config->get('config_url');
		}

		$link .= 'index.php?route=' . $route;

		if (count($data)) {
			$link .= '&' . urldecode(http_build_query($data, '', '&'));
		}

		$queries = array();
		if(!in_array($route, array('product/search'))) {
		foreach ($data as $key => $value) {
				switch ($key) {
					case 'product_id':
					case 'manufacturer_id':
					case 'category_id':
					case 'information_id':
					case 'order_id':
						$queries[] = $key . '=' . $value;
						unset($data[$key]);
						$postfix = 1;
						break;

					case 'path':
						$categories = explode('_', $value);
						foreach ($categories as $category) {
							$queries[] = 'category_id=' . $category;
						}
						unset($data[$key]);
						break;

					default:
						break;
				}
			}
		}


		if(empty($queries)) {
			$queries[] = $route;
		}

		$rows = array();
		foreach($queries as $query) {
			if(isset($this->cache_data['queries'][$query])) {
				$rows[] = array('query' => $query, 'keyword' => $this->cache_data['queries'][$query]);
			}
		}

		if(count($rows) == count($queries)) {
			$aliases = array();
			foreach($rows as $row) {
				$aliases[$row['query']] = $row['keyword'];
			}
			foreach($queries as $query) {
				$seo_url .= '/' . rawurlencode($aliases[$query]);
			}
		}

 

 

... потому что:

Одним запросом выполняется выборка готового seo_url товара, т.е. на выходе строка category/subcategory/subsubcategory/product

 

Одним запросом выполняется выборка готовых seo_url для всех категорий, причем в виде одной json_encode строки...

Сейчас объясню для чего такой изврат

Во первых БД возвращает 1 строку быстрее (и пофиг что она большая)

Для сравнения:

выборка одной json_encode строкой 1200 категорий с соответствующими им path в виде

image.thumb.png.b5a228e50a2d8106741cc629fa882121.png

и простая выборка category_id по индексу, для тех же 1200 категорий, вот таким запросом: SELECT `category_id` FROM `oc_category`

image.png.7823f3e628c092b8e3fa3061a494c8cc.png

Выборка json_encode строки в 7,5 раз быстрее ;)

 

Во вторых получив много строк - нарываемся на цикл в system/library/db/mysql.php


while ($result = mysql_fetch_assoc($resource)) {
	$data[$i] = $result;
	$i++;
}

В третьих вынуждены ещё раз обойти в цикле все записи для формирования массива в виде 'category_id' => 'готовый seo_url', что-то типа такого:


$data = array();
foreach ($query->rows as $row) {
	$data[$row['category_id']] = $row['seo_url'];
}

Вместо всех этих циклов просто $data = json_decode($query->row['data']) и массив готов, его можно кидать в кеш на очень долго... кеш будет актуален пока не изменишь категорию... а при изменении категории кеш удалится.

 

Времени не хватает допилить возможность использовать одинаковые алиасы в разных ветках категорий... допилю - выложу

А если протестируете с parse_ini_file то удивитесь скорости.

Share this post


Link to post
Share on other sites
10 минут назад, Vladzimir сказал:

А если протестируете с parse_ini_file то удивитесь скорости.

Не поверите, а если в кеш сбросить еще и php массив, то скорость еще возрастет

Share this post


Link to post
Share on other sites
23 часа назад, chukcha сказал:

Не поверите, а если в кеш сбросить еще и php массив, то скорость еще возрастет

Кеш в виде php-массива проигрывает parse_ini_file.

Share this post


Link to post
Share on other sites
В 30.09.2019 в 13:55, Vladzimir сказал:

А если протестируете с parse_ini_file то удивитесь скорости.

 

2 часа назад, Vladzimir сказал:

Кеш в виде php-массива проигрывает parse_ini_file.

1000 итераций
PHP: 0.59930419921875 сек.
JSON:0.61789894104004 сек.
INI: 0.6460587978363 сек.

В прикреплённом архиве файлы для самостоятельного тестирования.

Тестируй и удивляйся...

$max_index = 1000;
echo "<pre>1000 итераций\n";

Timer::start();
for ($index = 0; $index < $max_index; $index++) {
	include 'cache.php';
}
echo "PHP: ", Timer::finish(), " сек.\n";

Timer::start();
for ($index = 0; $index < $max_index; $index++) {
	$cache = json_decode(file_get_contents('cache.json'));
}
echo "JSON:", Timer::finish(), " сек.\n";

Timer::start();
for ($index = 0; $index < $max_index; $index++) {
	$cache = parse_ini_file('cache.ini', true);;
}
echo "INI: ", Timer::finish(), " сек.\n";

 

test.zip

Share this post


Link to post
Share on other sites
8 минут назад, Yesvik сказал:

1000 итераций
PHP: 0.59930419921875 сек.
JSON:0.61789894104004 сек.
INI: 0.6460587978363 сек.

 

А какая версия php?

У меня на 7.2:

1000 итераций
PHP: 0.052600145339966 сек.
JSON:0.1798620223999 сек.
INI: 0.20039200782776 сек.

Share this post


Link to post
Share on other sites
15 минут назад, dexion сказал:

А какая версия php?

У меня на 7.2:

5.6.38

Мои цифры это на ноуте с обычным HDD, поэтому такая разница. Но суть не в абсолютных значениях, а в соотношении...

Share this post


Link to post
Share on other sites

Всё это не имеет отношения к обсуждаемой теме, но раз пошла такая пьянка - хочу видеть ini-файл в котором микс из объектов и массивов. После этого поговорим что быстрее с учетом накладных расходов на обслуживание.

  • +1 1

Share this post


Link to post
Share on other sites

Я сравнивал json и serialize
Упаковка и распаковка
Тоже интересные эффекты на разных хостах  и разных версиях

Share this post


Link to post
Share on other sites
Только что, chukcha сказал:

Я сравнивал json и serialize

У меня на php7.2 serialize выигрывал json

На старых php вроде было наоборот

Отсюда не понял почему в опенкарте serialize заменили на json. Буду рад, если объясните.)

Share this post


Link to post
Share on other sites
49 минут назад, dexion сказал:

У меня на php7.2 serialize выигрывал json

На старых php вроде было наоборот

Отсюда не понял почему в опенкарте serialize заменили на json. Буду рад, если объясните.)

На больших объёмах json выигрывал.

Какая ситуация в 7.2 я не тестил. Надо заморачиваться и сравнивать кодирование/декодирование на разных объёмах, с простыми и ассоциативными массивами, с ASCII и UTF-8

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.


  • 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.