Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Tablica w cookie a przepełnienie ciasteczka
Forum PHP.pl > Forum > Przedszkole
flaa
Witam

Chcę zrobić ciastko zawierające tablicę, jednak nie wiem jak bardzo mogę te ciastko zapchać.
Tablica będzie zawierała liczby, maksymalnie trzycyfrowe (np [12, 321, 5,...]). Ciastko natomiast może ważyć najwięcej 4 kilobajty. Pytanie więc jak długa może być ta tablica, by nie przepełnić ciastka? Na przykład tablica czterystu liczb całkowitych (maksymalnie 3-cyfrowych) będzie ważyła mniej niż 4 kilobajty? A może mogę sobie pozwolić na jeszcze większą tablicę?

pozdrawiam
flaa
wizu
Jeśli obawiasz się przepełnienie ciasteczka, to może lepiej tablicę zapisz sobie w zmiennej sesyjnej, a w ciasteczku zapisuj tylko ID sesji?
flaa
Myślę, że póki co nie ma takiej potrzeby - jeśli uda się oszacować maksymalną długość tablicy, to zupełnie mi to wystarczy. Tym bardziej, że już cały skrypt mam gotowy, brakuje mi jedynie tej bezpiecznej długości tablicy ;)
Damonsson
Na moje oko te 400 będzie bezpieczną liczbą dla tablicy 3 cyfrowej.
flaa
Problem rozwiązany, jakby ktoś kiedyś trafił tu przez google z podobnym pytaniem, to napiszę: ciastko nie trawi więcej niż tablicy 138 liczb trzycyfrowych. Jak się okazało same liczby zajmują mało miejsca - o wiele więcej zajmuje reszta tekstu, który pojawia się po serializacji tablicy do postaci akceptowanej przez ciastko. No cóż, to i tak dobra opcja - afaik jedna witryna może wysłać max 300 ciastek, więc trzy takie tablice pomieszczą więcej, niż 300 ciastek z pojedynczymi liczbami :)
croc
Cytat(wizu @ 1.11.2011, 13:14:30 ) *
Jeśli obawiasz się przepełnienie ciasteczka, to może lepiej tablicę zapisz sobie w zmiennej sesyjnej, a w ciasteczku zapisuj tylko ID sesji?

thumbsdownsmileyanim.gif

Możesz zapisywać liczby w string np. "10,99,123,32" i oddzielać je funkcją explode. Jeśli masz 4 kB do dyspozycji, to na pewno zmieścisz minimum 1024 liczby podane w taki sposób. Zmieścisz Jednak ja na wszelki wypadek przechowywałbym te liczby w bazie danych. Jeśli nie trzeba być zalogowanym, to możesz zapisywać je wraz z id sesji w bazie.
wNogachSpisz
Skorzystaj z json_encode, upewnij się że przed enkapsulacją typy danych w tablicy są prawidowe (int lub float), dzięki temu nie zostaną dodane zbędne znaki cudzysłowia.
Nastepnie skompresuj przy uzyciu funkcji gzdeflate, koniecznie tej, nie pomyl z gzcompress ktore dopisuje niepotrzebny naglowek do kazdego wyprodukowanego ciagu i nie daje wyzszego poziomu kompresjo przy tak małej ilości danych.
Na koniec użyj kodowania ascii85 zwanego rowniez base85.
Takiego potworka walnij do cookie, przypisując do jednoznakowego klucza.

Lepiej się nie da.

Pozdrawiam
croc
A po co JSON? Jak już tak walczymy o każdy bajt, to lepiej oddzielać jednym znakiem. Jeśli nie przeważają liczby jednocyfrowe, to nawet można pokusić się o zapis: AAABBBCCCDDDEEEFFFGGG itd., czyli np. 042099123001004 i potem rozdzielenie tego przez:
  1. $array = str_split($string, 3);

No i skompresować taki ciąg.
wNogachSpisz
Cytat(croc @ 3.11.2011, 09:59:49 ) *
A po co JSON?

Dla wygody, całość będzie o 2 bajty dłuższa (bez kompresji, po kompresji pewnie mniej).
croc
Nie wiem czy dodanie jednej linii kodu dla zamiany danych na array to taka niewygoda...
wNogachSpisz
Jeśli chcesz przechowywać tylko i wyłącznie zbiór trzycyfrowych liczb, to spoko.
Tylko kto tak robi i po co? Z regóły do sesji trafiają różnorakie dane
JSON jest najlepszą metodą enkapsulacji, bo narzuca namnijeszą ramkę.
Chcę to podkreślić by ktoś kto trafi na ten wątek mógł wykorzystać mój pomysł w jakimś bardziej życiiowym problemie.

/edit
Aha, no i nie zapomnijmy co się stanie gdy ktoś zacznie grzebać w takim cookie, nie wiadomo jaki błąd to spowoduje.
Natomiast w przypadku JSON nie powiedzie się dekapsulacja i już.
croc
No przecież jak będą same jednocyfrowe tam to też zadziała. W przedziale liczb < 1000 najwięcej jest 3-cyfrowych i zakładam, że mamy tu równy rozkład. Jak będą same dwucyfrowe w danym przypadku, to efekt będzie taki sam jak rozdzielnie ich przecinkiem. Dla większości 3-cyfrowych to już jest spora oszczędność miejsca.
wNogachSpisz
Cytat(croc @ 3.11.2011, 10:31:24 ) *
No przecież jak będą same jednocyfrowe tam to też zadziała.

Nigdzie nie napisałem że nie zadziałą.

// edit

Zrobiłem kilka testów.

Podczas korzystania z JSON, kompresji i enkapsujacji base85
w 4000 bajtowym cookie można zmieścić ok. 1740 losowych, trzycyfrowych liczb.

Podczas korzystania ze string_split(), kompresji i enkapsujacji base85
w 4000 bajtowym cookie można zmieścić ok. 2100 losowych, trzycyfrowych liczb.

Mowa o totalnie losowych liczbach, jeśli byłyby one z jakiś powodów podobne, algorytm kompresji pokaże swoją siłę i te wyniki bedą jeszcze lepsze!

Cytat(Damonsson @ 1.11.2011, 15:15:13 ) *
Na moje oko te 400 będzie bezpieczną liczbą dla tablicy 3 cyfrowej.

Hihihihihihihihi, zrobiło sie z tego 2100, czyli 5 razy więcej ;-]
croc
Cytat(wNogachSpisz @ 3.11.2011, 10:51:59 ) *
Podczas korzystania ze string_split()

? Masz na myśli explode?
wNogachSpisz
Cytat(croc @ 3.11.2011, 10:52:30 ) *
? Masz na myśli explode?

Nie...
flaa
Prawdę mówiąc dopiero poznaję PHP i nie pomyślałem nawet, że tablicę można wepchać do ciastka innym sposobem niż serializacją. Dzięki wielkie za podpowiedzi, szczególnie panu wNogachSpisz - genialne rozwiązanie, już sobie sprawdziłem działanie tych funkcji i zaraz będę to wprowadzał na moją stronę. Nie do końca jednak rozumiem na czym ma polegać użycie kodowania ascii85 - z tym tematem spotykam się po raz pierwszy i nic konkretnego nie wyszukałem w googlach. Mimo wszystko myślę, że kompresja przy użyciu reszty wymienionych przez Ciebie funkcji się sprawdzi, bo nie potrzebuję tutaj aż tak super-optymalnej tablicy w ciastku. Przeszkadzało mi jedynie, że przeglądarka po stworzeniu 300 ciastek zacznie usuwać te najstarsze, więc nawet 1000 wartości w jednym cookie jest dużą zmianą :)

#edit

oho, jednak bez tego kodowania nie jest tak kolorowo - wyjaśniłbyś na czym to dokładnie polega? :P
wNogachSpisz
1 bajt to 8 bitów
8 bitów to 256 kombinacji

kiedyś stosowano 7 bitowy bajt
7 bajtów to 128 kombinacji

128 kombinacji świetnie nadaje się do reprezentacji alfabetu łacińskiego (angielskiego/arabskiego)
wraz z cyframi (arabskimi) oraz spacja przecinkiem i innymi znakami tj, przecinakim kropka, procentem itp.

W definicji ASCII czytamy
Cytat
ASCII [aski] (ang. American Standard Code for Information Interchange) - 7-bitowy kod przyporządkowujący liczby z zakresu 0-127: literom (alfabetu angielskiego), cyfrom, znakom przestankowym i innym symbolom oraz poleceniom sterującym


dzisiaj komputery operuja na 8 a nie 7 bitowym bajcie, powstało wiele kodowań (stron kodowych) ktore zagospodarywaly pozsostale 128 kombinacji na potrzeby różnych alfabetów.
teraz mamy juz utf8 ktore jest o tyle zajebiste, ze obsluguje kazdy alfabet swiata przez kodowanie kazdej litery w 8, 16, 32 i 64 bitach...

Wracając do tematu.
W cooke mozna uzyc 85 znaków.
kodowanie base85/ascii85 jest w stanie zawrzec kazdy 8 bajtowy ciag znakow (256 kombinacji) w 85 znakach (85 kombinacji).
efektem jest zwiekszenie wyjsciowego ciagu znakow ok 3 krotnie..

Base85 lepiej niż base64 nadaje sie do kodowania danych przeznaczonych do umieszczenia w cookie, poniewaz wykorzysuje 85 zamiast 64 znakow
dzieki czemu ciag jest o te 30% krotszy.

jedyny minus to to, ze php nie posiada funkcji do kodowania w base85 wbudowanej w jadro, a kodowanie przy pomocy zewnetrznych bilitek pochlania duzo czasu procesora..
flaa
Okej, to już wszystko wiem, wielkie dzięki za wyjaśnienie ;)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.