• DONATE to NULLED!
    Форуму и его команде можно помочь, мотивировать модераторов разделов.
    Помогите модератору этого раздела killoff лично.

Использование json_encode вместо serialize в кэш DLE

Горбушка

Ищу её...
Регистрация
2 Май 2008
Сообщения
3.444
Реакции
2.524
Всем привет.

Ковырялся я в очередной раз в коде DLE и заметил... DLE использует способ хранение кэша через json_encode.
И вот тут я оказался в ступоре.

Беглое тестирование показало, что serialize примерно на 10% быстрее, чем json_encode. По крайней мере, так показала PHP 7.1 под Windows.

Причём, это используется только для системного кэша, т.е.:
PHP:
function set_vars($file, $data) {
	
	$file = totranslit($file, true, false);
	
	if ( is_array($data) OR is_int($data) ) {
		
		file_put_contents (ENGINE_DIR . '/cache/system/' . $file . '.php', json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ), LOCK_EX);
		@chmod( ENGINE_DIR . '/cache/system/' . $file . '.php', 0666 );
		
	}
}
Если мы посмотрим на кэш для модулей и т.д., то там окажется вообще нет способа хранения, он хранит текст ровно так, как его туда отправили О_о. Т.е. сохранить массив в кэше не получится от слова совсем:
PHP:
function create_cache($prefix, $cache_text, $cache_id = false, $member_prefix = false) {
	global $config, $is_logged, $member_id, $mcache;
	
	if( !$config['allow_cache'] ) return false;
	
	if( $is_logged ) $end_file = $member_id['user_group'];
	else $end_file = "0";
	
	if( ! $cache_id ) {
		
		$key = $prefix;
		
	} else {
		
		$cache_id = md5( $cache_id );
		
		if( $member_prefix ) $key = $prefix . "_" . $cache_id . "_" . $end_file;
		else $key = $prefix . "_" . $cache_id;
	
	}
	
	if($cache_text === false) $cache_text = '';

	if( $config['cache_type'] ) {
		if( $mcache->connection > 0 ) {
			$mcache->set( $key, $cache_text );
			return true;
		}
	}

	file_put_contents (ENGINE_DIR . "/cache/" . $key . ".tmp", $cache_text, LOCK_EX);
	@chmod( ENGINE_DIR . "/cache/" . $key . ".tmp", 0666 );
	
	return true;
	
}
Нет, конечно можно сначала использовать json_encode или serialize к массиву, а уже потом это пихать в кэш, но мне всегда казалось, что кэш должен сам заботиться об этом, хотя, я могу и ошибаться...

Собственно, так оно и есть, вот так мы отправляем в кэш данные по комментариям, например:
PHP:
if ( $allow_cache ) create_cache ( "comm_".$allow_cache, json_encode($rows, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ), $this->query );

Может кто-нибудь объяснить, почему DLE использует такой подход к кэшу? Почему используется более долгий по времени вариант? Почему не используется json/serialize при записи обычного кэша?
Даже если мы захотим записать строку/текст, а не массив - сериализация всё равно ж выполнится, нет?

Ну и как всегда, сам спросил - сам отвечаю...

Для просмотра ссылки Войди или Зарегистрируйся
Для просмотра ссылки Войди или Зарегистрируйся

Если вкратце, serialize имела кучу уязвимостей и на нормальных хостингах отключена.
json_encode при этом безопаснее как для программиста, так и для сервера, при этом 10% скорости не критично на столь быстрых операциях.

Если ещё проще, то ЦелСофт здесь молодец.
 
Последнее редактирование модератором:
Если мы посмотрим на кэш для модулей и т.д., то там окажется вообще нет способа хранения, он хранит текст ровно так, как его туда отправили О_о. Т.е. сохранить массив в кэше не получится от слова совсем:
Memcache кажется сериализует и сохраняет как строку, в 2к18 пора бы юзать мемкеш, а не ***но файловое медленное
 
Memcache кажется сериализует и сохраняет как строку, в 2к18 пора бы юзать мемкеш, а не ***но файловое медленное
Оптимально давать выбор юзерам.
- Кэш файлов
- Memcache
- Redis
- Xcache
.....
 
Оптимально давать выбор юзерам.
- Кэш файлов
- Memcache
- Redis
- Xcache
Дать выбор это хорошо, но надо давать из хорошего. А файловый кеш на фоне редис того же, это прошлый век, как относительно недавно был обычный mysql вместо mysqli, а еще лучше было, если бы там был pdo
 
А мемкеш уже подружили с авторизацией? Лет 5 назад 100% не было...

Атака элементарная:
Сайт А пишет что-то в мемкэш
Сайт Б на том же сервере читает это из мемкэша, получаем приватные данные

Для того же DLE, например, атака ещё интереснее
Сайт Б пишет в мемкеш группе пользователей права админа
На сайте А все пользователи получают полный доступ в админку

Redis - тут дела чуть лучше, но это уже база данных своеобразная, не поддающаяся кластеризации, насколько я смог с ним разобраться.
Если у тебя 2 App сервера, то файлы они смогут читать оба (дисковая полка общая), а вот редис будет только на 1 сервере. Умирает он - умирает весь кэш - умирает сайт, ибо летят варнинги подключения к кэшу...

XCache... А его в PHP 7 забыли завезти...

В общем, у каждого кэша свои плюсы, свои минусы... Говорить "Это круче" - как минимум глупо...
 
А мемкеш уже подружили с авторизацией? Лет 5 назад 100% не было...

Атака элементарная:
Сайт А пишет что-то в мемкэш
Сайт Б на том же сервере читает это из мемкэша, получаем приватные данные

Для того же DLE, например, атака ещё интереснее
Сайт Б пишет в мемкеш группе пользователей права админа
На сайте А все пользователи получают полный доступ в админку

Redis - тут дела чуть лучше, но это уже база данных своеобразная, не поддающаяся кластеризации, насколько я смог с ним разобраться.
Если у тебя 2 App сервера, то файлы они смогут читать оба (дисковая полка общая), а вот редис будет только на 1 сервере. Умирает он - умирает весь кэш - умирает сайт, ибо летят варнинги подключения к кэшу...

XCache... А его в PHP 7 забыли завезти...

В общем, у каждого кэша свои плюсы, свои минусы... Говорить "Это круче" - как минимум глупо...
DLE пишет права в файловый кэш. Так что никаких таких атак быть не может.

И да, на крайняк можно поднять мемч на два разных порта и подключаться к ним а не на один. Ибо это как-то глупо.
 
Последнее редактирование модератором:
Назад
Сверху