Autor | Zpráva | ||
---|---|---|---|
majja01 Profil |
#1 · Zasláno: 19. 8. 2013, 11:16:22
Dobrý den,
dělám takový jednoduchý e-shop který nepotřebuje registraci (budu ukládat do databáze ip) zkončil jsem u funkce která kontroluje zda je ip v databázi a podle toho se rozhodne jestli přidat do seznamu k objednání nebo registraci a přidání. Jenže nevím v jaké formě to má být . mám script který podle tru nebo false vykonává přidání nebo registraci+přidání $uzjeuzivatel = true; if ($uzjeuzivatel) { // tady je kod pro přidání zboží do databáze } else { // tady pro registraci a přidání zboží } ?> Jednoduše řečeno potřebuju funkci na prohledání databáze která by dávala bud true nebo flase do prommené $uzjeuzivatel Doufám že jste to pochopily diky majja01 |
||
juriad Profil |
majja01:
Věz, že IP adresa není unikátní (často je sdílená v paneláku či vesnici). Co se stane, když na eshop přijdou dva lidé se stejnou IP adresou a budou chtít nakoupit? Budou si nejspíš přepisovat údaje a košík pod rukama. Měl bys vymyslet lepší způsob (cookies). Není nutné se podepisovat a není nutné dělat pravopisné chyby (pochopily, chybějící čárky) |
||
Micruss Profil |
jestli to máš podle IP tedy tak takhle
$ip = $_SERVER['REMOTE_ADDR']; $najdi_uziv = mysql_query("SELECT * FROM tvoje_tabulka WHERE ip = '$ip'"); if(mysql_num_rows($najdi_uziv)!=0) $uzjeuzivatel=true; else $uzjeuzivatel=false; ale kontrolovat uživatele podle ip je blbost jak už psal juriad |
||
Jan Tvrdík Profil |
#4 · Zasláno: 19. 8. 2013, 11:28:12
Micruss:
Doplním, že uvedené řešení není atomické, protože mezi ověřením, zda je uživatel již „registrovaný“ a operací, která na tom závisí, může proběhnout další registrace. |
||
Amunak Profil |
#5 · Zasláno: 19. 8. 2013, 12:01:36
Jan Tvrdík:
To mě přivádí na myšlenku, jak vlastně udělat atomickou registraci? Jak to řeší servery, kde k tomuto problému skutečně může dojít? Může se stát, že se dva lidé ve stejnou dobu pokusí zaregistrovat (účet u Googlu). A vyberou si stejné jméno. Může se stát, že dojde ke konfliktu až při běhu skriptu. Pokud je na sloupci v databázi primární klíč (nebo je unikátní), vyhodí chybu sama databáze, a s tím už se nějak dá pracovat. Jde to udělat nějak lépe? |
||
Taps Profil |
#6 · Zasláno: 19. 8. 2013, 12:05:22
Amunak:
pro inspiraci: http://doc.nette.org/cs/atomicity |
||
Jan Tvrdík Profil |
#7 · Zasláno: 19. 8. 2013, 12:08:59
Amunak:
Můžeš použít například zámky nad určitými tabulkami databáze. Případně to můžeš zkusit, nechat selhat na unikátním indexu a zpracovat korektně tu vzniklou chybu. |
||
Amunak Profil |
#8 · Zasláno: 19. 8. 2013, 13:44:01
Jan Tvrdík:
Zámek mě napadl, ale ten taky zabrání v registraci třeba další stovce uživatelů, která by s tím jinak neměla problém. Taps: Vím, že to Nette umí, ale snad nikde jsem se nedočetl, co se tedy vlastně stane, když dojde ke konfliktu. Funkce prostě vyhodí výjimku? |
||
majja01 Profil |
juriad:
promiňte za pravopis bylo to psáno rychle Micruss: díky ale použiji tedy cookies jak říkal juriad Amunak, Jan Tvrdík: atomickou? Použiju tedy cookies četl jsem si o tom na linuxsoft.cz co jsem tam pochopil bylo jak přidávat. <? SetCookie ("nazev_cookie", "hodnota", time()+10*60); echo "Tato stránka Vám poslala cookie!"; ?> mohl bych udělat například toto? ]<? SetCookie ("uzivatel", "$_GET["jmeno"]", time()+10*60); ?> edit: a můž ještě to zboží psát taky do cookies? Abych nemusel pužít databázi? Pak by se jenom vymazalo po dokončení objednávky ne? |
||
juriad Profil |
majja01:
Timi cookies jsem myslel SESSION (cookies jsou jen fyzický prostředek jak toho dosáhnout; přečti si o tom něco. V kostce: na začátek každého souboru přidej session_start. Ta funkce se postará o to, že každý uživatel (určený podle cookies, do které ukládá náhodně vygenerované ID platné omezenou dobu) dostane svoje pole $_SESSION, které můžeš přímo číst a měnit. Session může obsahovat veškerá data (třeba idéčka a počty položek v košíku), což v případě, že uživatel není registrován je asi nejvhodnější varianta. Nebo, pokud je uživatel registrován, bude session obsahovat jen skutečné ID uživatele a veškerá data budou v databázi. Demonstrace přidávání položky do košíku. Zkus si to v několika prohlížečích zároveň (každý košík bude samostatně). kosik.php: <?php session_start(); if(!isset($_SESSION['kosik'])) { $_SESSION['kosik'] = array(); } print_r($_SESSION['kosik']); ?> <form action="pridej_polozku.php" method="post"> <input type="text" name="polozka"> <input type="submit" value="Přidej položku"> </form> pridej_polozku.php: <?php session_start(); if(!empty($_POST['polozka'])) { $_SESSION['kosik'][] = $_POST['polozka']; } header("Location: kosik.php"); exit; |
||
Jan Tvrdík Profil |
#11 · Zasláno: 19. 8. 2013, 20:24:35
Amunak:
„Zámek mě napadl, ale ten taky zabrání v registraci třeba další stovce uživatelů, která by s tím jinak neměla problém.“ To je velmi hypotetická situace, reálně se ti nestává, že by se během 1 sekundy registrovalo 100 lidí zároveň. Ale jinak ano, zámek ti způsobí, že operace neproběhne paralelně, ale sériově. „ale snad nikde jsem se nedočetl, co se tedy vlastně stane, když dojde ke konfliktu. Funkce prostě vyhodí výjimku?“ Když se pokusíš získat exkluzivní zámek nad objektem, který je už uzamčen, tak se skript zastaví a čeká, až bude zámek uvolněn a bude si ho tak moci získat pro sebe. Většina implementací zároveň přidává nějaký timeout, tzn. že když se čeká příliš dlouho, tak se operace prohlásí za neúspěšnou (např. flock vrátí FALSE ).
majja01: „atomickou?“ Viz např. php.vrana.cz/atomicita-operaci.php. |
||
Amunak Profil |
#12 · Zasláno: 20. 8. 2013, 00:48:57
Jan Tvrdík:
Děkuji, tohle je dost poučné. Měl jsem v hlavě, že když nejde získat zámek, skript se přeruší (vyhodí se výjimka nebo tak něco). |
||
majja01 Profil |
#13 · Zasláno: 20. 8. 2013, 12:21:27
juriad:
aha takže vůbec nemusím ukládat nějaké ůdaje o uživatelích stačí prostě uložit idéčka zboží a ty pak vyčtu z databáze. Jestli jsem to dobře pochopil, tak u každého zboží budu mít formulář který přidá zboží do session? A ty pak vypíšu pomocí print_r ? Amunak, Jan Tvrdík: Nechápu o čem se tu bavíte ;-) |
||
juriad Profil |
#14 · Zasláno: 20. 8. 2013, 12:42:09
majja01:
Ano, každý produkt u sebe bude mít formulář (pokud se bude přidávat produkt přes $_POST), nebo klidně i odkaz <a href="pridej_polozku.php?polozka=123">Přidat do košíku</a> (musíš změnit přístup na z $_POST na $_GET).
Produkty v košíku si vypíšeš jakýmkoli způsobem, který znáš, třeba do tabulky. $_SESSION['kosik'] obsahuje úplně obyčejné pole. Já jsem použil print_r jen jako demonstraci principu.
Teoreticky nemusíš uživatele a košíky ukládat do databáze vůbec, ale session se automaticky zruší po několika minutách (výchozí nastavení je tuším 1440 sekund -- lze nastavit, hledej). V databázi ale naopak data zůstávají neomezeně dlouho, pokud jednou uživatel uloží něco do košíku, tak to v něm zůstane i když obchod už nikdy nenavštíví. Proto se oba přístupy kombinují a spouští se pravidelně čištění databáze od takových zastaralých dat (košíků). Amunak a Jan Tvrdík se baví v podstatě o tom, že když máš posloupnost příkazů: $dostupne = zjisti_zda_je_zbozi_dostupne(); if($dostupne) { odecti_jednicku_od_dostupneho_zbozi(); proved_objednavku(); } Je to šíleně nepravděpodobné a u málo navštěvovaného obchodu se to "nikdy" nestane. |
||
majja01 Profil |
#15 · Zasláno: 20. 8. 2013, 13:20:35
juriad:
Udělal jsem toto: do detail.php (to je detail zboží) jsem dal toto: <form method="post" style="width:300px; float:left;" action="additem.php"> <input style="width:50px;" placeholder="ks" id="spinner" name="ks" /> <input type="hidden" value="<? echo $vyrobek["id"];?>" name="id"> <input class="button" type="submit" value="přidat do košíku"> </form> do additem.php toto: <? session_start(); if(!empty($_POST['id'])) { $_SESSION['kosik'][] = $_POST['id']; } header("Location: objednavka.php"); exit; ?> tady bych s echtěl zeptat jestli jde v session kosik dát dvě hodnoty id a ks? a na seriálu linuxsoft.cz je ještě příkaz ten se tam dávat nemusí? <?php session_start(); if(!isset($_SESSION['kosik'])) { $_SESSION['kosik'] = array(); } print_r($_SESSION['kosik']); ?> Array ( [0] => 1 ) vím že v té hranaté závorce je pořadí a ta 1 je id
takže to funguje asi bych to mohl zapsal do databáze ale nevím jak udělat unikátní id uživatele? nejlepší by bylo abych nastavil čas zrušení na nulu tím by se to zrušilo jen když zavřu prohlížeč nebo pokud bych dal session_destroy();
ale nevím jestli to jde nastavit na hostingu endora :-( |
||
juriad Profil |
#16 · Zasláno: 20. 8. 2013, 13:30:04
majja01:
Linuxsoft je sice kvalitní zdroj, ale je poněkud starší, session-register už dávno není třeba. Dokonce dokumentace povídá: This function has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0. S tím košíkem si dělej co chceš. Klidně může ten additem.php vypadat takto: <?php session_start(); if(!empty($_POST['id']) && isset($_POST['pocet']) && is_numeric($_POST['pocet'])) { $id = $_POST['id']; $ pocet = (int) $_POST['pocet']; $_SESSION['kosik'][$id] = $pocet; # klíčem v poli je id produktu; hodnotou je počet } header("Location: objednavka.php"); exit; |
||
majja01 Profil |
#17 · Zasláno: 20. 8. 2013, 14:39:05
juriad:
moc díky těd už to funguje parádně :D jenom bych potřeboval aby se z toho array Array ( [0] => 1 [1] => 5 [5] => 4 [11] => 3 )
udělali 2 promenné abych je mohl vyhledat v databázi. Toť poslední otázka :D |
||
juriad Profil |
#18 · Zasláno: 20. 8. 2013, 14:48:37
$ids = array_keys($_SESSION['kosik']); if(count($ids)>0) { $sql = "SELECT * FROM produkt WHERE id IN (" . implode(', ', $ids) . ")"; ... položení dotazu do databáze ... while ($row = ...) { $id = $row['id']; $pocet = $_SESSION['kosik'][$id]; echo ... } } |
||
majja01 Profil |
#19 · Zasláno: 20. 8. 2013, 15:07:22
juriad:
aha tak to není poslední otázka udělal jsem toto: <? mysql_connect("127.0.0.1", "root", ""); mysql_select_db("mak"); mysql_query("SET CHARACTER SET utf8"); mysql_set_charset('utf8'); session_start(); $ids = array_keys($_SESSION['kosik']); if(count($ids)>0) { $sql = mysql_query("SELECT * FROM zbozi WHERE id = '$ids'"); while ($vyrobek=MySQL_Fetch_Array($sql)) { $id = $vyrobek['id']; $ks = $_SESSION['kosik'][$id]; echo $vyrobek["name"]; } } ?> |
||
juriad Profil |
#20 · Zasláno: 20. 8. 2013, 15:22:09
majja01:
Ta má konstrukce s IN a implode má nějaký význam :) Uprav svůj 8. řádek. Pokud $ids bude obsahovat víc produktů napřiklad array(1,2,3,5), tak se sestaví sql dotaz s podmínkou "... id IN (1, 2, 3, 5)" |
||
majja01 Profil |
#21 · Zasláno: 20. 8. 2013, 17:29:32
juriad:
jo ale to skončí chybou Warning: mysql_fetch_array() expects parameter 1 to be resource, string given in D:\phpvirtual\mak\objednavka.php on line 29 |
||
juriad Profil |
Každý holt nazýváme $sql něco jiného: já dotaz, ty výsledek dotazu.
$sql = "SELECT * FROM zbozi WHERE id IN (" . implode(', ', $ids) . ")"; $vysledek = mysql_query($sql); while ($vyrobek=MySQL_Fetch_Array($vysledek)) |
||
majja01 Profil |
#23 · Zasláno: 20. 8. 2013, 20:33:49
juriad:
aha :D fakt moc díky už to funguje |
||
Časová prodleva: 11 let
|
0