Diskuze: Problém s pamětí
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 22 zpráv z 22.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Možno sa mýlim ale je hlúposť písať takúto hru v PHP ... Sú na to omnoho krajšie jazyky ale ako študijnú výzvu to beriem
nemáš to prostě jen někde zacyklený? Generování mapy nemůže být nic složitého. Do pole náhodně rozmístit miny a pak v okolí 1 pole načteš +1 tam kde jsou miny vedle sebe se pak automaticky změní z 1 na 2 a výše. A ty když pak hledáš v prozkoumáváš jen okolí 1 pole kolem sebe se pak zobrazí čísla (ale je asi zbytečné rozepisovat princip hry) koukni na podmínky, tam bude zakopaný pes.
Jo ale teď koukám, že to možná bude v SESSION ty nejsou tak velké jak si představuješ... myslím si že je to kolem 4kB Možná ještě méně... já chtěl jednou přes session přenášet velký formulář a vždy se mi dařilo přečíst jen půlku, tak dlouho jsem nad tím špekuloval, až jsem si uvědomil. že se mi vrací vždy konkrétní velikost formuláře. Tedy, změň způsob ukládání mapy.
Já právě ty čísla počítám až při kliknutí, ale to si nemyslím,
že by mělo ovlivnit paměť (jestli počítat na začátku nebo při
hře).
S těmi SESSION jsem si myslel taky, ale já už je při vytváření pole
zaplňuji takže pokud by byl problém s tím, tak to bude hlásit chybu už
při vytváření mapy...
// vytvoří pole podle nastavení a zakryje ho
for ($i = 0; $i < $this->vyska; $i++) {
for ($j = 0; $j < $this->sirka; $j++) {
$_SESSION['pole'][$i][$j] = 0; // obsahuje 0 (prázdné) nebo miny
$_SESSION['mapa'][$i][$j] = false; // překrytí - pokud je false je zakryté, pokud true, odkryté
$_SESSION['oznaceni'][$i][$j] = ''; // zde se ukládá umístění vlajek (označení min)
}
}
$_SESSION['vlajky'] = $this->pocet;
// náhodně vloží bomby
for ($i = 0; $i < $this->pocet; $i++) {
$this->vlozMinu();
}
private function vlozMinu() {
$x = rand(0, $this->vyska - 1); //j
$y = rand(0, $this->sirka - 1); //i
if ($_SESSION['pole'][$x][$y] . '' == $this->mina) {
$this->vlozMinu(); // pokud mina na daném poli již je, vloží ji znovu
} else {
$_SESSION['pole'][$x][$y] = $this->mina;
}
}
Máš pravdu, například Java nebo C#, jedná se o studijní výzvu.
Co se týče vzhledu, vše řeším přes ajax takže to alespoň působí jako
hra než web.
Pro jistotu jsem vyzkoušel i výpočet čísel už při generování mapy, ale i přesto je pořád problém s pamětí pokud se klikne na na prázdné pole. Jiná pole se odkryjí v pořádku.
A na řádku, který hlásí chyba (183) se nachází právě rekurze:
if ($x != 0) { //podmínka jestli není na konci mapy
$this->sectiCisla($x - 1, $y); //sečte počet min kolem pole
$_SESSION['mapa'][$x - 1][$y] = true; //zviditelní pole
if ($_SESSION['pole'][$x - 1][$y] == 0) { //pokud je zviditelnění pole prázdné
$this->oznacPoleOkolo($x - 1, $y);//znovu označí vše kolem ------- řádek 183, zde má být chyba podle PHP
}
}
v tom případě jsi to prostě zacyklil a do zblbnutí ti to zaplňuje paměť až do naplnění a pak to spadne. Obávám se, že bez nakouknutí do kodu se lepší odpovědi nedočkáš...
To zda je lepší řešení, nebo není by asi bylo na lepší prostudování.
Každopádně v nastavení php.ini si nastav větší alokaci paměti a problém máš vyřešený. Pakliže to nenajdeš, pošli mi zprávu a napíšu ti přesně o které položky se jedná. (Nejsem teď na PC kde bych to komfortně zjistil).
Lze nastavovat velikost session a dalších funkcí. Osobně jsem ukládal dost velké data do session i bitovou kopii obrázků v řádově desítkách MB.
Pakliže nemáš možnost se dostat k php.ini což na webhostingu se nedostaneš, tak bych doporučil zjistit jakou kapacitu ti hosting umožňuje. Standardně by mělo být dnes 32MB a víc, ale to je na hostingu. V opačném případě to vyžaduje buď změnu hostingu a nebo optimalizovat tvojí "aplikaci".
Jak jsem již psal, upravení php.ini bych bral jako poslední možnost.
Podle mě se to pravděpodobně opravdu někde zacykluje, bohužel nedokáži
přijít na to kde.
Když budu mít čas a budu to stíhat, zkusím udělat také miny.
Každopádně mi přijde zbytečné tohle vše ukládat
Osobně mám představu, že si dle navolené velikosti vytvořím čtverec,
který bude mít xxx čtverečků a budou očíslované. A tak si budu muset
pamatovat velikost. Následně náhodně dle čísel dosadit miny, to si
určitě zapamatovat. A každou na kliknutou pozici bych si taky pamatoval a
zbytek již jen dopočítal. Nepotřebuješ si pamatovat úplně všechno.
Aspoň takhle to vidím já, možná až to budu programovat, najdu chybu v mé teorii
Data můžeš ukládat do neviditelného inputu, nebo i do souboru... Možností je spousta.
Řekl bych, že zacyklení je v odkrývání prázdného pole a rekurze. Jedno pole vyvolá odkrývání toho vedle a to vedle vyvolá odkrývání původního..? Zas tak poctivě jsem to nečetl, ale toto mne napadlo.
katrincsak to už je po několikáté co tu radíš hovadiny, proč to
děláš?
David Hynek to si asi pleteš s cookies, sessions ve standartu nemají
limit, jsou limitované pouze maximální alokovanou pamětí skriptu
Do toho limitu co to překročilo by se vešlo několik běžících eshopů, zvyšování je hovadina, vzhledem k tomu že to je zacyklený tak to ani nemůže pomoct.
Autor to musí prijet debuggerem, případně ručně dumpovat obsah a zjistit důvod zacyklení, jiné řešení není.
Jak píše [me|]13944[/me|]
Do metody oznacPoleOkolo si musíš přidat kontrolu, zda to pole už není "zviditelněné" (abych použil tvoji terminologii )
Takhle se oznacPoleokolo pořád volá dokola na stejná pole, až dojde pamět, php asi nemá nijak omezený stack (prostě pro něj používá celou paměť), takže místo stackoverflow dostaneš nedostatek paměti.
Nad tím jsem se teď zapřemýšlel, ale v metodě sectiCisla hned na začátku mám ověření, že se čísla sečtou jen v případě, že je pole zakryté (není ještě zviditelněné):
if (!$_SESSION['mapa'][$x][$y]) {
Můžeš mi přesněji vysvětlit co píšu za hovadinu ? A možná by mě zajímalo i v jakém dalším případě, vzhledem k tomu že bych se rád napravil z nějaké chyby
A vůbec nebudu překvapený, když odpověď na to nedostanu :/
Samozřejmě že dostaneš.
Jak konkrétně se vyřeší problém zacyklený rekurze, která nikdy nekončí
a při každým průchodu zabírá další pamět zvýšením limitu paměti?
Nijak, jenom mu to reportne chybu s větší hodnotou alokované paměti,
případně pokud tý paměti na serveru má opravdu hodně, tak to narazí na
time limit.
A druhý bod taky sedí. Jsi si vědom toho jak a kde se obsah session ukládá,
kdy a proč? Pokud ano, tak by tě taková věc nenapadla.
Další případy si teď nevybavím, ale mám tvůj nick spojený s tagama
"php, hovadiny".
PS. Dáš link na ten projekt v ostrým provozu kde používáš tyhle
techniky?
Odpovědi si určitě cením
Ano, mohu dát link. Je to web, který jsem psal od A do Z a prakticky se na
tom naučil OOP. Grafika není ideální, ale hold nejsem grafik. I tak to
považuji zatím za svou nejlepší a nejčistší práci .
Každopádně budu rád za feedback
Proces na ukládání fotek do session najdeš v přidání nového
inzerátu.
http://ebazar.eu
Jednoduchý sortící algoritmus na 10 000 000 prvků, ti v PHP sežere 2,5GB paměti, zatímco v jiném nedebiilním jazyku 80MB, To říkám proto, abych ti dal naději, že si to nenaimplementoval špatně, ale pouze autoři PHP již 10 let přemýšlejí pr**lí - Chci říct.. že to, že ti něco dost primitivního permamentně v PHP memory leakuje, nemusí být tvoje chyba, ale hodně špatného nástroje, který používáš.
A jiné řešení jsem pro ukládání nenašel, potřebuji, aby se fotka zmenšila již na straně klienta a zároveň mít 100% přehled o tom co se nahrává a dostat informace tam kam potřebuji.
foreach ($_SESSION['fotky']['baseID1'] as $foto){
$filteredData=substr($foto, strpos($foto, ",")+1);
$decocedData = base64_decode($filteredData);
$fp = fopen('b'.$i++.'.png', 'wb');
fwrite($fp, $decocedData);
fclose($fp );
}
Zobrazeno 22 zpráv z 22.