Kam uložit seznam zemí, regionů a měst? – PHP – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Kam uložit seznam zemí, regionů a měst? – PHP – Fórum – Programujte.comKam uložit seznam zemí, regionů a měst? – PHP – Fórum – Programujte.com

 

Vlákno bylo úspěšně vloženo.
Pokud sám přijdeš na řešení, nezapomeň ho sem přidat!
oxidián0
Grafoman
5. 4. 2016   #1
-
0
-

Mám těch seznamů víc, mám to všechno v polích přímo v aplikaci a prý to není správné řešení. Měl bych to uložit mimo php. Což dává docela smysl. Ovšem mysql na webzdarma je pomalé. Dát to do sqlite? uživatel se bude např. registrovat, a musím provést výpis zemí. Když vybere zemi, tak provést výpis regionů a když vybere region tak výpis města. To je spousta dat. Načítání tak velkého souboru je vlastně zbytečné. Ale při těchto výběrech si myslím že SQL je docela neeffektivní. Co třeba místo toho abych ukládal jednotlivá města do db, udělat to tak, že bych uložil celý řetězec a oddělil bych ho středníkama? Select mi vrátí celý text a ten si rozparsuju a myslím že to bude rychlejší než spouštět smyčku s mysql_fetch_array (které časem nahradím za PDO). Které řešení je nejméně náročné? Návrh pro tabulku by mohl vypadat takto:

id INT(3), lang CHAR (2), typ INT (3) string (VARCHAR), txt (TEXT)

třeba u položky "gender" bych zadal dotaz "SELECT txt FROM options WHERE lang='cs' AND typ = '1'  a měl bych dostat "muž;žena". To bych si rozparsoval. Zde je ale nevýhoda, že toto rozvržení se nehodí pro regiony a města. Tam by se mi zase hodily jiné údaje např.

id INT(4), lang CHAR (2), typ INT (3), parent INT (3), child INT (3), string (VARCHAR), txt (TEXT)

tak třeba pro ČR bych měl tyto hodnoty:

000, 'cs', 0, null, null, 'Česká Republika,Slovensko,Polsko,Německo,Rakousko,Maďarsko', null

001, 'en', 0, null, null, 'Czech Republic,Slovakia,Poland,Germany,Austria,Hungary', null

006, 'cs', 1, 000, 017, 'Česká Republika', null

017, 'cs', 2, 006, null, 'Praha;Jižní Čechy;Severní Čechy;Jižní Morava;Severní Morava;', null

300, 'cs', 3, 017, 500, 'Severní Morava', null

500, 'cs', 3, 300, null, null, 'Opava;Ostrava;Český Těšín;Frýdek Místek;Vsetín...'

Takže pro výpisy zemí budu vracet jen jeden string s id 000, pro výpis regionů budu vracet string s id 017, pro výpisy měst vracet string s id 500 (poté co vyberu kraj SM).

Případně je výhoda že mohu pracovat i s rodičem pokud bych potřeboval vrátit seznam zemí ze kterých jsem vybíral.

Je to tak schůdné nebo byste doporučili něco jiného? Další varianta je parsovat soubor txt.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 4. 2016   #2
-
0
-

#1 oxidián
Těch variant je hodně, každá má jiné výhody.

  1. Formát INI. PHP ho umí načíst funkcí parse_ini_file().
  2. Formát CSV. PHP ho umí načítat po řádcích do pole funkcí fgetcsv().
  3. Formát XML. PHP s ním umí pracovat na mnoho způsobů včetně XSLT a XPath.
  4. Databáze SQLite. Pro podobné číselníky je to skvělá volba.

A teď si vyber, co je ti bližší. Osobně bych dal přednost XML, protože XSLT ho umí přímo (bez účasti PHP) vložit do výsledného HTML třeba jako seznam či rolovací menu, umí je filtrovat a řadit. Bez XSLT však tyto výhody nevyužiješ.

Formát INI je dobrý z toho důvodu, že se velmi snadno pořizuje. Klíč, rovnítko, hodnota, nový řádek. Hodí se do cca tisíce položek.

Formát CSV je vhodný pro více strukturované záznamy. Údržba opět textovým editorem.

Databáze SQLite je vhodná i pro případy, kdy budeš chtít data adminovat z webu.

SQL je efektivní i pro výběr mnoha záznamů, pokud k tomu použiješ jeden SQL dotaz. Dotazování po jednom záznamu (také to občas u někoho vidím) je však silně neefektivní.

Edit: ID 000, 017 atd. mi vůbec nedávají smysl. Takovou denormalizaci si ta databáze snad ani nezaslouží.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 4. 2016   #3
-
0
-

#2 Kit
ID 000, 017 atd. mi vůbec nedávají smysl. Takovou denormalizaci si ta databáze snad ani nezaslouží.

Co tím myslíš?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 4. 2016   #4
-
0
-

#3 oxidián
1NF nepřipouští více datových položek v jednom záznamu.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 4. 2016   #5
-
0
-

Nevím co znamená 1NF ale 000 je parent a 017 je child. parent 000 říká že položka byla vybrána ze seznamu číslo 000. child 017 říká že položku lze rozbalit a obsahuje seznam číslo 017. Je to tak jasné?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 4. 2016   #6
-
0
-

#5 oxidián
Takovému kódování se snažím vyhnout. Je z toho však patrná hierarchie, kterou se snažíš vpašovat do relační databáze. Tohle spolu prostě nekamarádí.

Dá se to však udělat jinak: V jedné tabulce budeš mít státy, ve druhé kraje a ve třetí města. Jako sekundární klíč použiješ jazyk. Každá tabulka bude tedy mít ID záznamu, 2 vyhledávací sloupce (ID rodiče + jazyk) a název lokality.

Alternativně se to dá nacpat hierarchicky do jednoho souboru XML a místo SQL vyhledávat přes XPath.

BTW: Zajímavé. Na heslo "1NF" mi Google našel plnou stránku správných výsledků.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 4. 2016   #7
-
0
-

#6 Kit
Já jsem použil google hned ale nerozuměl jsem tomu ani slovo. To řešení na tři tabulky je právě to neefektivní řešení, kdy výpis 20 měst budeš mít na 20 cyklů mysql_fetch_array.

A ještě mám jeden dotaz. Co když budu mít seznam VŠECH měst ČR a zip a x,y souřadnic na mapě. To by bylo šílenství vše parsovat. Dejme tomu, že osoba klikne na mapu, mapa vrátí souřadnice a měl bych vyhledat město. Na to by musela být všechny města v db jednotlivě, asi bych musel mít na to extra tabulku.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 4. 2016   #8
-
0
-

#7 oxidián
Na výpis 20 měst použiji jeden $pdo->fetchAll();

Na seznam všech měst je samozřejmě lepší databáze SQL než XML.

Prostě do tabulky "mesto" přidáš sloupečky se souřadnicemi. Ovšem místo souřadnic můžeš mít na mapě ID toho města - bude to hledat mnohem rychleji.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
6. 4. 2016   #9
-
0
-

Nevím jak bych realizoval id místo souřadnic na mapě. Pro hledání lze použít sloupce x, y. Bude se to mnohem jednodušeji vykreslovat. O realizaci mapky jsem ještě nepřemýšlel je to ještě daleko. Teď připravuji data.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
6. 4. 2016   #10
-
0
-

#9 oxidián
Když budeš město vykreslovat na mapě, použiješ souřadnice x, y pro umístění klikacího kruhu, ale v URL použiješ ID města a v atributu title budeš mít jeho název, takže při najetí myší se ten název objeví v bublině.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
peter
~ Anonymní uživatel
3981 příspěvků
6. 4. 2016   #11
-
0
-

Databaze mest i s GPS jsou verejne dostupne. Da se najit googlem. Tusim posta nebo geodezie nebo statisticky urad nebo tak.

500, 'cs', 3, 300, null, null, 'Opava;Ostrava;Český Těšín;Frýdek Místek;
Zalezi na pouziti. Tento zapis se da pouzit pro vypsani seznamu mest v kraji. Ale uz nebude rychly, pokud budes ke kazdemu mestu potrebovat dohledat souradnice. Lepsi je mit zvlast tabulky s mesty, okresy, kraji, staty.

- mesta -
1, Ostrava

- kraje -
1, moravskoslezsky
2, pardubicky

- stat -
1, ceska republika

stat_kraje // tabulka propojeni
1, 1 -- cr + mor-slez
1, 2 -- cr + pardubicky

kraje_mesta // tabulka propojeni
...
Mozna z toho bude dlouhy select, ale ciselne ID se vyhledava rychleji nez text. Treba
id = 1234
text = ostrava = 256^7 = 72057594037927936 // 256 na sedmou
Tak to je zhlediska rychlosti zpracovani zatracene rozdil hledat 100% shodu na 4 cifry a 17 cifer. Ale mohl bys zapnout fulltextove hledani na sloupci, kdybys to potreboval urychlit. Stale by ale bylo id rychlejsi. Treba jako se dela hledani v obsahu clanku.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:cd45:2e...–
oxidián0
Grafoman
6. 4. 2016   #12
-
0
-

#10 Kit

Našel jsem fajnou stránku odkad se dá všechno zkopírovat

http://www.statnisprava.cz/rstsp/redakce.nsf/i/kraje_okresy_obce

Jenže tomu přestávám rozumět. Na české wikipedii jsem našel pro vysočinu tyto města:

// Vysočina
$options->districts[] = array(
'Bílina',
'Děčín',
'Chomutov',
'Kadaň',
'Litoměřice',
'Litvínov',
'Louny',
'Lovosice',
'Most',
'Podbořany',
'Roudnice nad Labem',
'Rumburk',
'Teplice',
'Ústí nad Labem',
'Varnsdorf',
'Žatec'
);

Ale na státní správě jich je jen několik:

http://www.statnisprava.cz/rstsp/ciselniky.nsf/i/CZ063

Havlíčkův Brod, Jihlava, Pelhřimov, Třebíč, Žďár nad Sázavou

Teď nevím jakým zdrojem se mám řídit. Chci tam dát jen ty okresy (kraje už mám zadané).

Edit: Tak opravuji to podle té státní správy a mám toto:

http://paste.ofcode.org/g7SQdJewHv3xm7DeRvre7i

Když tak se na to mrkněte jestli se vám to zdá OK.

Nahlásit jako SPAM
IP: 78.45.87.–
KIIV
~ Moderátor
+43
God of flame
6. 4. 2016   #13
-
0
-

#12 oxidián
ta "vysocina" ma nejak podezrele stejne nazvy mest, jako ustecky kraj :) Zatec sice na jihlavsku je, ale je to mala vesnicka.

Nahlásit jako SPAM
IP: 94.113.92.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Kit+15
Guru
6. 4. 2016   #14
-
0
-

#12 oxidián
Místo indexů bych v $options->districts raději použil název kraje.

Skutečně to jsou kraje Slovenska? :)

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
6. 4. 2016   #15
-
0
-

KIIV: už jsem to opravil

To byly české kraje. Zatím to jen připravuju do souborů php. Pak to naimportuju do db.

Teď dělám Polské. Zase jsem narazil na problém - kraj slezský (vejvodství):

https://pl.wikipedia.org/wiki/Podzia%C5%82_administracyjny_Polski#wojew.C3.B3dztwo_.C5.9Bl.C4.85skie

Jsou tam dvě skupiny. Jedna jsou okresy a druhé jsou města s právy okresu. Například Katowice.

https://pl.wikipedia.org/wiki/Katowice

A teď nevím jestli ty to města mám taky zahrnout mezi "okresy"?

Mapka:

https://upload.wikimedia.org/wikipedia/commons/8/88/%C5%9Al%C4%85skie_administracja.png

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
6. 4. 2016   #16
-
0
-

Ještě mě napadlo jiné možné řešení. Místo toho abych dával každý překlad na samostatný řádek mohu uvést na jeden řádek překlady toho Kraje... Jen přidám sloupce s jazyky a varchar pro každý jazyk.

php by pak vypadalo takto:

polsko.cz.php:

$options->regions['cz'] = array('Celé Polsko',
'Dolnoslezské',
'Kujavsko-pomořské',
'Lodžské',
'Lublinské',
'Lubušské',
'Malopolské',
'Mazovské',
'Opolské',
'Podkarpatské',
'Podleské',
'Pomořské',
'Slezské',
'Svatokřížské',
'Varmijsko-mazurské',
'Velkopolské',
'Západopomořanské'
);

$options->districts['pl'] = array(
);

// Dolnoslezské - dolnośląskie  
$options->districts['pl'][0] = array(
...

pod daným jazykem překlad toho samého souboru který mi dal google

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
6. 4. 2016   #17
-
0
-

#11 peter
Já nechtěl dělat hledání na základě textu. Hledání na základě čísel, ten text tam je jen pro vrácení toho co se má zobrazit. Taky nechci pracovat se souřadnicemi geologickými ale se souřadnicemi google:

http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/

což mě přivádí k myšlence, že na souřadnice budu potřebovat samostatnou tabulku

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
6. 4. 2016   #18
-
0
-

#16 oxidián
"cz" není Polsko. Máš to nějaké pomotané.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
6. 4. 2016   #19
-
0
-

#18 Kit
cz je překlad odpovídající danému jazyku.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
6. 4. 2016   #20
-
0
-

#19 oxidián
"cz" je Česká republika.

"cs" je český jazyk.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
6. 4. 2016   #21
-
0
-
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
6. 4. 2016   #22
-
0
-

Tak přehledné to je, ale vzhledem k tomu kolik tam je položek se mi to nechce editovat do xmls. Určitě by to šlo přes nějakou funkci ale nechce se mi osvěžovat paměť takže teď to udělám pro mysql a pak to vyexportuju jako SQL.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
6. 4. 2016   #23
-
0
-

Co to udělat takto:

/** Type -1 "unselected"
    Type -2 "select all"
    Type -3 "any"
    Type -4 "search all"    
    Type 0 - country or federation
    Type 1 - region/department/state or country of federation
    Type 2 - district
    Type 3 - city/town/village
    Type 10 - list of countries 
    Type 11 - list of regions 
    Type 12 - list of districts 
    Type 13 - list of towns
    
    Country:
    0 - cz
    1 - sk
    2 - pl
    3 - en
    4 - fr
    5 - de
    6 - au
    7 - hu
   
 **/

@mysql_query("DROP TABLE ".MT::OPTIONS_TERRITORIES);
$folders = array('cs','sk','pl','en','fr','de','au','hu');
$sql = "CREATE TABLE ".MT::OPTIONS_TERRITORIES." (
  id int unsigned NOT NULL auto_increment,
  type tinyint signed NOT NULL default '2',
  country tinyint unsigned NOT NULL default '0',
  cs varchar NOT NULL default '',
  sk varchar NOT NULL default '',
  pl varchar NOT NULL default '',
  en varchar NOT NULL default '',
  fr varchar NOT NULL default '',
  de varchar NOT NULL default '',
  au varchar NOT NULL default '',
  hu varchar NOT NULL default ''
)";
if(mysql_query($sql)) echo "DONE.</BR>";
else echo "ERROR: ".mysql_error()."</BR>";

Nejdříve dám vybrat list_of_něco ... např. list_of_regions pro určitou zemi. vrátí mi to string, který si rozprsuju. V seznamu zemí (tag options) budou unikátní id té země. Uživatel si zvolí, zaregistruje si id. Relaci není třeba řešit. A pokud nějakou relaici, tak měst v tabulce se souřadnicemi. Kromě měst okresních bude možnost vkládat další města a tudíž tam bude třeba vytvořit relaci k okresu.

Předpokládám, že když uživatel bude chtít vložit jakousi vesnici Dolní Hanou, tak budu kontrolovat jestli Dolní Haná už neexistuje v seznamu vesnic z daného okresu...

Mám funkci, která sestavuje options a jede od 0 po n. Ve formulářích 0 odpovídá obvykle "nevybráno".

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
7. 4. 2016   #24
-
0
-
Nahlásit jako SPAM
IP: 2001:718:2601:26c:8525:bf...–
peter
~ Anonymní uživatel
3981 příspěvků
7. 4. 2016   #25
-
0
-

Mimochodem, ty muzes udelat to, ze to flaknes do db a pomoci php z ni pak vygenerujes txt soubory, ktere pak uz dal budes vyuzivat v programu, treba pro javascript. Jakoze ted ty soubory delas rucne.
Ten XLS se da otevrit v excelu a prekonvertovat na csv a ten by se dal vlozit do db, tak, jak je, mozna. Nestahoval jsem to.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:8525:bf...–
oxidián0
Grafoman
7. 4. 2016   #26
-
0
-

@peter: Neumím hledat tak jako ty. Našel jsem jen tu státní správu pro ČR. Přes wiki se taky dají zjistit  města pod jednotlivé okresy. Co by mě však zajímalo ze všeho nejvíc jestli někde na webu nejsou taky google souřadnice k těm městům nebo regionům ale silně pochybuju. Podle mě se to tam bude muset zadat ručně.

Edit:

S tím google translatorem to není tak jednoduché, on při překladu narušil syntaxy php

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 4. 2016   #27
-
0
-

Naimportovat to by byla maličkost, ale jak to přeložit. Ten google translator je úplně blbej. Nezvládne přeložit php tak aby nenarušil syntaxy.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
7. 4. 2016   #28
-
0
-

#27 oxidián
Proto se data oddělují od aplikace. Pokud se ti nelíbí XML, můžeš použít třeba JSON, který umí PHP také nacucnout.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
7. 4. 2016   #29
-
0
-

#28 Kit
Dyď on ani to XML nepřeloží správně. Sice to bylo lepší ale z kraje jihomoravského udělal moravu...

Hodím tam třeba

'Burgenland',
'Dolní Rakousko',
'Horní Rakousko',
'Korutany',
'Salcbursko',
'Štýrsko',
'Tyrolsko',
'Vídeň',
'Vorarlbersko'

a

on z toho udělá toto:

"Burgenland"
"Dolna Austria"
"Górna Austria"
'Karyntia "
"Salzburg"
"Styria"
"Tyrol"
"Vienna"
"Vorarlberg"

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 4. 2016   #30
-
0
-
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
7. 4. 2016   #31
-
0
-

#30 oxidián
Proč tam máš "d_i_s_t_r_i_c_t" místo "district"? Takové značky se blbě čtou.

Proč vlastně nenecháš názvy měst a správních celků v originálním jazyce?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
7. 4. 2016   #32
-
0
-

Protože Google translator je blbej, musel jsem tam dát podtržítka aby nepřeložil atributy.

Protože to budu používat v php kde potřebuju tyhle názvy v angličtině.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 4. 2016   #33
-
0
-

Jak zpřístupnit toto?

SimpleXMLElement Object ( [0] => Jihočeský )

    $districts = $this->xml_data[$land]->r_e_g_i_o_n_s->d_i_s_t_r_i_c_t;
    foreach($districts->attributes() as $attr):
      print_r($attr);
      die();      
    endforeach;

Je na to funkce?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
7. 4. 2016   #34
-
0
-

#33 oxidián
Nevím, co v tom XML máš, takže od pasu: Zkus to přetypovat na string.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
7. 4. 2016   #35
-
0
-

#34 Kit
Tak to díky, to pomohlo.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 4. 2016   #36
-
0
-

A toto?

    $districts = $this->xml_data[$land]->r_e_g_i_o_n_s->d_i_s_t_r_i_c_t;
    $title = (string) $districts->attributes();
    foreach($this->xml_data[$land]->r_e_g_i_o_n_s as $v):
      print_r($v);
      die;
    endforeach;


Vypisuje:

SimpleXMLElement Object
(
    [d_i_s_t_r_i_c_t] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Jihočeský
                        )

                )

            [1] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Jihomoravský
                        )

                )

            [2] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Karlovarský
                        )

                )

            [3] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Královéhradecký
                        )

                )

            [4] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Liberecký
                        )

                )

            [5] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Moravskoslezský
                        )

                )

            [6] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Olomoucký
                        )

                )

            [7] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Pardubický
                        )

                )

            [8] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Plzeňský
                        )

                )

            [9] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Praha
                        )

                )

            [10] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Středočeský
                        )

                )

            [11] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Ústecký
                        )

                )

            [12] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Vysočina
                        )

                )

            [13] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Zlínský
                        )

                )

        )

)


$districts je pole s regiony. A když ho strčím do foreach tak mi to zase vypíše pole, místo aby $a byl element pole
 

print_r($districts);
SimpleXMLElement Object
(
    [d_i_s_t_r_i_c_t] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Jihočeský
                        )

                )

            [1] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Jihomoravský
                        )

                )

            [2] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Karlovarský
                        )

                )

            [3] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Královéhradecký
                        )

                )

            [4] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Liberecký
                        )

                )

            [5] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Moravskoslezský
                        )

                )

            [6] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Olomoucký
                        )

                )

            [7] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Pardubický
                        )

                )

            [8] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Plzeňský
                        )

                )

            [9] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Praha
                        )

                )

            [10] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Středočeský
                        )

                )

            [11] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Ústecký
                        )

                )

            [12] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Vysočina
                        )

                )

            [13] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [t_i_t_l_e] => Zlínský
                        )

                )

        )

)
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
7. 4. 2016   #37
-
0
-

#36 oxidián
Co já vím? Zkusil bych $v['d_i_s_t_r_i_c_t']. Tu třídu nepoužívám - bez dat a zdrojáku se mi to těžko zkouší, tak to cucám z prstu.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
7. 4. 2016   #38
-
0
-

Je to šílený. V obou případech to ukazovalo stejný typ - před smyčkou i uvnitř smyčky.

$districts = $this->xml_data[$land]->r_e_g_i_o_n_s; // ->d_i_s_t_r_i_c_t
$title = (string) $districts->attributes();
foreach($districts[0] as $k => $v):


Vyřešilo to až když jsem tam dal $districts[0] to ale nedává smysl proč to tam musí být.
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
7. 4. 2016   #39
-
0
-

#38 oxidián
Dává to smysl. Těch elementů districts může být za sebou víc. Je to seznam.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
7. 4. 2016   #40
-
0
-

Teď bych chtěl přidat města. Ale uvědomil jsem si že vlastně nevím jak řešit hlavní města. Praha je uvedena jako kraj a přitom není okres a dělí se rovnou na městské části. Já uvedl městské části jako okresy ale tak by to nejspíš být nemělo. Mám tedy předstírat že městské části jsou okresy? To by pak vypadalo takhle: vyber Region: ... vybereš Praha, ... další políčko... vyber okres: vybereš městskou část... není to divné? Jak bys to řešil ty? Chci totiž umožnit výběr města přes větší celky od regionů, přes okresy až po města, ale přitom je to nepovinný údaj. Takže bylo by možno vybrat jen region nebo region+okresní město, nebo vše.

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
11. 4. 2016   #41
-
0
-

Jen jsem chtel rici, ze bys mel pouzivat oficialni zdroje, jako statni sprava, posta, geodezie a pod. Wiki a jine muzou mit chybne informace.

Proc to chces prekladat pres translator? Arab precte arabstinu. Cech to asi hledat nebude. Ale je to moznost, to jo. Nicmene, opet bych sel pres oficialni zdroje a ne translator nebo si zaplatil prekladatele.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:9938:70...–
oxidián0
Grafoman
13. 4. 2016   #42
-
0
-

#41 peter
To bych se nedoplatil vždyď jsou tam tisíce měst. ČR má kolem přes 6000 měst. SR má asi o polovinu méně. Dohledávat každé město je nemožné. Přes oficiální zdroje nejdu na mě je to moc složité, wiki je nejjednodušší způsob. To není pro firmu nebudu to prodávat tak o co jde?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
13. 4. 2016   #43
-
0
-

#42 oxidián
Ze státní správy si můžeš stáhnout kompletní seznam krajů, okresů, měst, obcí, ulic i adres. Zadarmo.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:cf4:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
13. 4. 2016   #44
-
0
-

Myslíš ten link co jsem používal? Ale to je jen v jednom jazyce ne? Já to kopíroval odsud http://www.statnisprava.cz/rstsp/redakce.nsf/i/kraje_okresy_obce

Však ČR a SR mám hotové. Ale problém u slovanských jazyků je ten že mají koncovky krajů které angličtina nepoužívá, takže pro anglický jazyk to musím přejmenovat.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
13. 4. 2016   #45
-
0
-
Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:cf4:5...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
13. 4. 2016   #46
-
0
-

Měl bych překládat položky jako

Č.Budějovice 7 Střelecký ostrov, Linecké předměstí, Rožnov

do angličtiny takto?

Ceske Budejovice 7 Shooter's Island, a suburb of Linz, Rožnov

nebo

spíš takto

Ceske Budejovice 7 Střelecký Island, a suburb of Linec, Rožnov

co je vhodnější?

Velmi často se objevují obce Horní ... Dolní ... překládat to třeba Upper Lhota? Není to divné nebo to lze považovat za normální?

Případně (a teď to myslím jako recesi) Horní Lhota se dá přeložit jako Upper Time a Dolní Lhota jako Lower Time.

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
13. 4. 2016   #47
-
0
-

Nazvy ulic se tusim neprekladaji. To bys nemohl adresovat dopisy. :) Nepamatuji se, ze by nas anglictinarka ucila ceske nazvy v anglictine.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:a87a:e0...–
oxidián0
Grafoman
13. 4. 2016   #48
-
0
-

#47 peter
Některé názvy krajů se ale do angličtiny překládají. Například: Bohemian, Selesian, Moravian - Český, Slezský, Moravský a takových příkladů bude určitě víc. Znáš anglický název pro Prahu nebo Plzeň? Myslím že určitě. Věci jako Nádražní ulice, náměstí, předměstí, nové město a staré město se přeložit dají v pohodě. Warszaw či Varšava se překládá jako Warshaw. Je možné že je to kvůli výslovnosti aby angličtináři věděli jak to vyslovovat. Kdybys přijel do polska a ptal se na kraj Ciechanow tak to asi nebudeš vyslovovat tak jak se to píše, ale spíš Čechánov... nebo Čiechánov. Nebo Nowy Dwór Mazowiecki můžu přeložit do češtiny jako Nový Dvůr Mazovský. Polski Czieszin nebo jak se to píše se u nás běžně říká Polský Těšín. Oświęcim - Osvětim. Používají se úplně běžně.

Tohle není kvůli adresování dopisů, ale kvůli tomu aby člověk mluvící anglicky uměl najít daný kraj.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
13. 4. 2016   #49
-
0
-

#48 oxidián
V takovém případě by ty názvy měly být uvedeny duálně, např. cs: Wien (Vídeň) nebo en: Praha (Prague), tedy nejprve originální název a za ním v závorce přeložený, pokud nějaký překlad existuje. Jinak pouze originální název.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
13. 4. 2016   #50
-
0
-

Udělám to tak, že v češtině bude provizorní překlad polských názvů okresních měst a ve slovenštině bude název okresních měst v originálu. Kromě Hlavního města ten bude přeložen. Hlavní sloupec by měl být default a v něm bude originální znění pro tu konkrétní zemi. Maďarské názvy určitě překládat nebudu. Německé jen pár základních jako jsou Drážďany. Uživatel kterému vadí čeština by mohl mít v nastavení nepřekládat polské názvy, tím pádem by se to tahalo z originálu i když by nepoužíval Slovenštinu.

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
14. 4. 2016   #51
-
0
-

Zanasis si do toho zbytecne bordel, kdyz nektere z mest prelozis a jine ne.
Mimochodem, ja mluvil o nazvech ulic, protoze ses na nazvy ulic ptal. Mesta a kraje se samozrejme prekladaji.

Jo, pokud to nepotrebujes v db, tak si to muzes ulozit jako textovy soubor, treba pro js. Ono, stahnout 20k se vsim nebo obrazek 20k, to je prohlizeci celkem jedno.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:7dd6:2f...–
oxidián0
Grafoman
14. 4. 2016   #52
-
0
-

#51 peter
Já se neptal na ulice s těmi nepracuju.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
14. 4. 2016   #53
-
0
-

#45 Kit
Díval jsem se na ten soubor xml. Návzvy ulic tam jsou velkými písmeny to je dost blbý. Pokud bych to chtěl automaticky zpracovat a převést na normální velikost písmen tak je to problém. JEREMENKOVO NÁMĚSTÍ by mělo být správně Jeremnekovo náměstí, ale nemohu dát všechny první písmena automaticky velká, Jeremenkovo Náměstí vypadá blbě.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
14. 4. 2016   #54
-
0
-

#53 oxidián
Ten soubor byl vydán za účelem automatického ověřování adres, např. u zásilkových služeb. V takovém případě velká písmena nevadí.

Dodatečně se ještě dají udělat substituce typu "s/Náměstí/náměstí/"

Tak velký soubor se však v případě PHP hodí spíš nacucnout do databáze. Pro Javu je však možné ponechat formát XML, protože se načítá jen jednou při startu aplikace.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
17. 4. 2016   #55
-
0
-

#54 Kit
No v db to bude určitě. Ale jak říkám když se tam nerozlišuje velikost písmen tak je mi to k ničemu.

Tabulku relací přece nepotřebuju. Uživatel si vybere ze seznamu zemi, která ho zajímá, pak region, pak okres apod. Tím pádem získám potřebná data pro select dotaz.

Rozhodl jsem se ukládat do tabulky dva typy, které mi řeknou co je daná položka zač. Tím mi tabulka poslouží nejen k ukládání zemí, regionů, okresů, měst, obvodů, případně čtvrtí a ulic, ale i k překladu dodatečných položek voleb ve formuláři.

Když to shrnu jedna země/region/okres/město/obvod má mít vždy jen jeden řádek, sloupec default bude obsahovat překlad pro danou zemi a další sloupce případné varianty překladu pro jiné jazyky.

Zkopíruju sem svůj komentář.

    LTYPE:
    LOCATION TYPE:
    Type 0 - is special text, not a location
                                
    bitmask meaning:
             bit:
             1. - is street           ... x >= 1
             2. - is neighborhood     ... x >= 2
             3. - is borough (správní obvod města) ... x >= 4
             4. - is town             ... x >= 8
             5. - is district (okres) ... x >= 16
             6. - is region  ... x >= 32
             7. - is state   ... x >= 64
             8. - is country ... x >= 128
 
    TTYPE:
    ... Text type when LTYPE is 0

    TTYPE 0 - not selected
    TTYPE 1 - select any
    TTYPE 2 - jakýkoliv jazyk  / language
    TTYPE 3 - jakákoliv země   / country
    TTYPE 4 - jakýkoliv region / region
    TTYPE 5 - jakýkoliv okres / district
    TTYPE 6 - jakékoliv město / town
    TTYPE 7 - jakýkoliv obvod / bourough
    TTYPE 8 - jakákoliv čtvrť / neighbourhood
    TTYPE 10 - jakákoliv ulice / street
    TTYPE 11 - add text after district...
    
    TTYPE 101 - countries string
    TTYPE 102 - regions string (present in country)
    TTYPE 103 - districts string (present in region of country)
    TTYPE 104 - boroughs string (present in district of region of country)
    TTYPE 105 - neighboroughs string  (present in borough of district of region of country)
    TTYPE 106 - streets string (present in neighbourough of borough of district of region of country)    

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
17. 4. 2016   #56
-
0
-

#55 oxidián
Kde budeš mít ten seznam zemí, regionů a okresů? Odněkud musíš ten seznam vzít, abys ho mohl uživateli vložit do formuláře, ze kterého bude vybírat. Zřejmě v databázi.

Abychom si to ujasnili: Každá databázová tabulka v relační databázi je množinou relací. Výrok: "Tabulku relací přece nepotřebuji" je tedy zcela chybný.

To, co předvádíš na následujících řádcích, se označuje zkratkou EAV. Všichni tvůrci databázových aplikací jsou před tím důrazně varováni - má to smysl jen v určitém typu aplikací. Dotazy do takové databáze bývají složité a výkon tragický.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:519d:...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
18. 4. 2016   #57
-
0
-

#56 Kit
Všechno v jedné tabulce. Nechápu proč by to mělo mít nižší výkon? Když bude třeba vypsat Zemi, region, kraj, město na stránce s profilem tak se použije něco jak toto:

SELECT FROM TABLE LOCATIONS pl,default WHERE id=28231 OR id=28238 OR id=28142 OR id=2867

Seznamy zemí, regionů, okresů i měst budou v téže tabulce:

SELECT FROM TABLE LOCATIONS pl,default WHERE id>28200 AND country=2 AND TTYPE>101 AND TTYPE<105 AND (LTYPE | 56 )

Těmi dvěma dotazy bych dostal 3 a 3 řádků se dvěma sloupci*. Mám zato že když zadám id tak bude hledat od určitého id a tím přeskočí země které jsou před ním.

LTYPE | 56 má najít pouze ty řádky kde jsou nastaveny tři bity - region, okres, město - to vrátí seznamy.

Fungovalo by to jako tabulka s překlady. Chtěl jsem podobným způsobem udělat i překlad různých hlášek, které by měly být více jazykové. Ve většině případů člověk potřebuje jen jednu nebo dvě hlášky, ale např. u registračního formuláře kde máš 30 kategorií, je třeba těch hlášek až 30... zase bych ale dodával přímo konkrétní ID, žádné složité dotazování jen dlouhý řetězec podmínek s ID=x1 OR ID=x2 OR ... atd

*Poznámka - ve skutečnosti se bude provádět jednodušší dotaz, protože když vybíráš z formuláře a obsluhuje to AJAX, tak nejdříve vybereš zemi. Následně se spustí dotaz na tabulku, že chceš vrátit seznam regionů (string)

SELECT FROM TABLE LOCATIONS pl,default WHERE id>28200 AND country=2 AND TTYPE==102 AND (LTYPE & 32 )

nebo takto:

SELECT FROM TABLE LOCATIONS pl,default WHERE id>28200 AND country=2 AND (LTYPE & 32 )

mělo by tö mít stejný výsledek

Pak tedy vybereš region a AJAX odešle dotaz na výběr seznamu okresů:

SELECT FROM TABLE LOCATIONS pl,default WHERE id>28200 AND country=2 AND (LTYPE & 16 )

To se dá ještě urychlit tím že místo 28200 zadám id předchozího nalezeného záznamu.

Výsledek by byl jeden řádek

podmínku country=2 by taky bylo možno vypustit pokud vím od kterého řádku země začíná...

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
18. 4. 2016   #58
-
0
-

Ještě dotaz. Když bych data nainportoval do sqlite a pak chtěl udělat update wampu tak data musím nejdříve vyexportovat? Je to stejné jak u mysql že při změně mysql se nedostanu ke starým datům?

Teď jsem si uvědomil že ty seznamy měst musím dát do jiné tabulky protože obsahují odlišný typ - TEXT místo VARCHAR. V tom máš pravdu že kdyby to bylo dohromady tak bude větší částe sloupce TEXT nevyužitá. ALE u  jazykových variací typu VARCHAR mi to nevadí. Výhodou je kratší seznam a přehledněji se v tom budu orientovat.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
18. 4. 2016   #59
-
0
-

#57 oxidián
Kde vezmeš id 28231, 28238, 28142 nebo 2867? Ze vstupního formuláře návštěvníka?

Proč požaduješ výsledek dotazu na 3 řádky, když to můžeš mít na jednom?

Proč používáš číselné kódy LTYPE, TTYPE? Vždyť se to blbě čte. Používej jména a výčty.

Používání porovnávání < a > na id je nesmyslné. Vždy se dělají testy pouze na rovnost. Co když se ti mezi ta id vpašuje obec z jiného okresu nebo naopak nová obec bude někde na konci?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
18. 4. 2016   #60
-
+1
-
Zajímavé

#58 oxidián
SQLite nemá s WAMPem mnoho společného - týká se pouze PHP.

SQLite3 (aktuální) bude navždy SQLite3, tedy alespoň co se týká zachování vnitřního formátu databáze a použité implementace jazyka SQL. Totéž se týká stále platné verze SQLite2 i nejnovější verze SQLite4. Dokud tedy budeš používat SQLite3, nemusíš při upgrade PHP exporty řešit.

MySQL to řeší obdobným způsobem, také zachovává vnitřní formát dat.

K tomu bych dodal, že doporučuji dělat pravidelné exporty databáze. Ne kvůli upgrade, ale proto, že zálohování toho nejcennějšího (dat) je prostě velmi dobrý zvyk.

Typ VARCHAR je do max. 255 znaků, ale kratší řetězce ukládá úsporněji (x+1). Totéž platí pro typ TEXT, ve kterém string "ahoj lidi" zabere 11 bajtů (9+2). Rozdíl je tedy pouze v jednom bajtu. Pro název obce však doporučuji VARCHAR pro MySQL nebo TEXT pro SQLite (pro string má jen ten jeden typ).

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
18. 4. 2016   #61
-
0
-

#59 Kit
Kde vezmeš id 28231, 28238, 28142 nebo 2867?

Ze záznamu, které mám uživateli v tabulce users. Tohle patří k prohlížení profilu ne k registračnímu formuláři.

To porovnávání id jsem tam dal proto, že bych chtěl urychlit to hledání, aby neprocházel třeba 180000 záznamů ale skočil rovnou na místo kde začíná sekce pro danou zemi třeba rakousko někde id 80000 záznamu jako příklad.

Jak bych mohl mít na jednom řádku tři výsledky, když ty data jsou pod stejným sloupcem na třech různých řádcích?

Proč používáš číselné kódy LTYPE, TTYPE? Vždyť se to blbě čte. Používej jména a výčty.

Myslíš jako kde v tabulce nebo v PHP kódu? Nevím co myslíš výčtem.

To id porovnávalo pouze zemi. Prostě do dadabáze se bude vkládat nejdříve jedna země (se všechemi údaji - země, rgion, okres, město, obvod), potom druhá potom, třetí atd. Není tedy možné aby nastalo to co si popsal.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
18. 4. 2016   #62
-
0
-

#61 oxidián

Jak bych mohl mít na jednom řádku tři výsledky, když ty data jsou pod stejným sloupcem na třech různých řádcích?

Velmi snadno. Používá se na to JOIN, který sice v případě tabulky EAV vypadá poněkud kostrbatě, ale funguje. Právě proto doporučuji samostatné tabulky pro různé správní celky. V tabulce users pak budeš mít pouze jedno ID.

Tím "urychlováním" ID to pouze zpomalíš. Představ si, že na ID se používají indexy...

Výčet je v SQL reprezentován jako ENUM(), tedy v tabulce. Vazba s PHP je pak mnohem jednodušší, neboť PHP v takovém případě nepotřebuje žádný vnitřní číselník pro vstupy a výstupy - vše je v databázi.

Jak vyřešíš, když budeš dodatečně některé ze zemí přidávat obec či okres? Jejich ID bude nutně na konci.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
18. 4. 2016   #63
-
0
-

#62 Kit
No však ID myslím index. Číslo které si databáze automaticky navyšuje sama pro danou tabulku. Když znáš přesnou velikost řádku a přesnou polohu řádku (číslo n), tak se dá snadno spočítat kde v datovém prostoru má program hledat - tudíž by db měla být schopna skočit na konkrétní řádek a od něj začít hledat. Ne že bude porovnávat od id=1. A více tabulkám se snažím vyhnout protože těch tabulek tam bude celkově už tak dost a to mi pak přijde nepřehledné aby jen kvůli téhle maličkosti existovalo třeba 3-6 tabulek. Sem si myslel že asi myslíš ENUM jenže ENUM v php udělat nejde pokud nevytvoříš třídu. Jenže toto je záležitost jiného kódu na vytahování dat z db, který ještě nepíšu ten teprve budu psát až budu implementovat třídu. Čísla která jsem použil byly pro stručnost a jednoduchost. Výhoda ENUM v C/C++ je jasná, tady v PHP mi ale vadí že to není tak čisté jako v C/C++. O ENUM v rámci db však slyším poprvé. Viděl jsem použití SET na toto, ale já mám právě radši takovéto řešení, víc programátorské. Jinými slovy mi zase říkáš, abych vytvořil další tabulku :(.

Tvoje poslední otázka je správná. Na to celou dobu myslím. Importovací script a databáze mají sloužit čistě k tomu, že pokud se rozhodnu k něčemu takovému tak budu muset začít odpiky s čistým štítem anebo vyexportovat stará data do nové tabulky, vytvořit novou tabulku a podle těchto dvou tabulek přečíslovat existující záznamy vycházející ze staré tabulky na hodnoty nové. Víš, já počítám celkem se dvěma projekty. Jeden je testovycí pro menší komunitu a na té se ukáže jak to bude fungovat a pak uvidím jestli budu rozšiřovat třeba obvody. Bude to záležet až na tom jestli se stránka ujme a jestli bude zájem o toto. Pokud by byl zájem pak mohu přidat. Jde taky o to že mně se ani rozšiřovat nechce,protože dá to dost práce kopírovat všechny ty obvody, je to spousta měst a žádnou ucelenou db s case sensitive daty nemám. Pokud bych měl tak to teda naimportuju hned a pak už nemusím nic rozšiřovat.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
18. 4. 2016   #64
-
0
-

#63 oxidián
ENUM a SET jsou standardními datovými typy v MySQL. V PHP se s nimi pracuje jako se stringy, ale v databázi je to uloženo ve formě čísla (1-2 bajty). Konverzi si dělá databáze sama při překladu SQL dotazu, není to žádná tabulka navíc - naopak je občas o nějakou tabulku méně.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:7c54:...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
18. 4. 2016   #65
-
0
-

Když se podíváš na různá fora a komunitní weby, klikneš na profil uživatele tak často tam mají přímo v profilu věci jako seznam oblíbených uživatelů, seznam návštěv, seznam posledních vytvořených topiců, seznam posledních příspěvků. Při tom všem se dělá klasický SELECT a následně fetching v PHP  (myslím mysql-fetch-array). Takže to vytěžování db je úplně běžné. Ale jinak tedy chápu co myslíš, prostě když chci vypsat příslušné položky tak budu místo jednoho fetche volat třeba 5 fetchů. Ano to je blbý, ale zase třeba pokud by si uživatel vytvořil např. cestopis - seznam měst, kam chce v létě cestovat na dovolenou, tak musíš ten seznam měst stejně vypsat klasickým fetchem. Chápu ten fetch tak jako že je to vlastně další SQL dotaz, který pokračuje v předchozím SQL dotazu... tím že se to nějak "napojí" na původní výsledek. Tím by bylo logické že by zpracování zabralo místo 0.00030-0.00050s 5x více času. Tedy max 0.0025 pro mysql (nevím zda sqlite bude rychlejší, ještě jsem neměril). Možná ale naopak fetch bude rychlejší protože výsledek je už vastně nalezen. Tak či tak, snad se dostanu na nějakých 0,001s což je stále krásné číslo. Byď na sdíleném serveru to pojede než z mě pomaleji to je nejspíš fakt. Taky si myslím že tím JOINováním se to trochu zpomalí protože prochází 4-5 tabulek místo jedné. Takže to je složitější a má toho víc co musí zpracovat. Vnitřní kód na obsluhu takové věci musí být docela složitý, teď nemyslím kód na straně webmastera, ale na straně programátora databáze.

No a co když budu používat tabulku na překlad slovíček na stránce, jakékoliv popisky, odkazy, menu, všechny popisky na formulářích, options apod. Stejným způsobem, vytáhnu třeba 100 položek z databáze, zpomalí se to výrazně? Bude to znát? Aktuálně mám tyto věci v php souboru jako pole. Takže to jede rychle. Na běžné stránce může být tak 30 řádků, na registračním formuláři třeba i 200.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
18. 4. 2016   #66
-
0
-

#65 oxidián
Nepoužívám klasicky 5×fetch(), ale pouze jednou fetchAll(). Ale to jsem už psal...

I těch 5 fetchů je stále jen jeden SQL dotaz. Databáze je zpravidla pošle naráz a netrápí se tím, že PHP si to vezme 5× v cyklu. Řeší se to zpravidla až tehdy, pokud je počet vybíraných záznamů v miliónech, pak je to nutné vybírat po skupinách, ale to je úplně jiný level.

JOIN je rychlejší a šetrnější k databázi, než samostatný výběr z několika tabulek a následné spojování v PHP.

Na překlad slovíček se databáze také hodí a také je to rychlé.

Popisky, odkazy a menu, které jsou trvalého charakteru, mívám ve výstupní šabloně, resp. v přidruženém XML, do kterého si ta šablona sama umí sáhnout.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
19. 4. 2016   #67
-
0
-

Myslel jsem popisky menu a odkazú, zbytek se vygeneruje programem

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
19. 4. 2016   #68
-
0
-

#67 oxidián
Viz poslední odstavec mého předchozího příspěvku.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
19. 4. 2016   #69
-
0
-

Dá se použít proměnná $dataCountry na ukládání dat do $this->data[$countryID][$lang]? Mě to nefunguje.

    $dataCountry =& $this->data[$countryID][$lang];

    $dataCountry->id = $attribs['id'];  

Když dám echo

echo "this->data[$countryID]['sk']->id: ".$this->data[$countryID]['sk']->id."<br>";
echo "dataCountry->id: $dataCountry->id";

tak první řádek nevytiskne hodnotu, druhý jo. Tzn. že se to uložilo pod $dataCountry místo pod
$this->data. Jak řešit zkrácení zápisu abych všude nemusel opakovat ten dlouhý kód?
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
19. 4. 2016   #70
-
0
-

#69 oxidián
Takové věci dělám objektově - kód se tím významně zkrátí a zpřehlední.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
20. 4. 2016   #71
-
0
-

#70 Kit
Jak objetově? Vždyť mám objekt a krátké to nebylo. Zkrátil jsem to takto

$dataCountry =& $this->data[$countryID][$lang];

$dataRegion =& $dataCountry->regions[$localRegionCounter];

$dataTown =& $dataDistrict->towns[$localTownCounter];

$dataBorough =& $dataTown->boroughs[$localBoroughCounter];

Kdyby tam nebyly ty zkratky tak je to mnohem delší na řádek

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
20. 4. 2016   #72
-
0
-

#71 oxidián
Tohle není objekt, ale klasická struktura. S OOP to mnoho společného nemá.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
peter
~ Anonymní uživatel
3981 příspěvků
20. 4. 2016   #73
-
0
-

No, on se Kit ohani objekty dost casto. Ale zatim jsem ho nevidel zminit jediny jednoduchy a prehledny objekt s vhodny nazvy promennych :)
Treba take casto rika, jake je super pdo proti mysql. Ale ve skutecnosti se musis naucit uplne novou terminologii a principy a nakonec zjistis, ze to neumi to, co umi mysql v zakladu. Takze si musis napsat prevodnik se spoustou podminek navic :)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:ace8:e5...–
oxidián0
Grafoman
20. 4. 2016   #74
-
0
-

Cílový člen pochopitelně není objekt, ale pole, ale celkově jsou to všechno objekty. Je to struktura objektů. Nevím co jinač myslíš pod OOP. Dej příklad.

class Import_locations_country_object{
  public $regions; // array of objects
  public $queue;

  function __construct(){
    $this->regions = array();
  }
}

class Import_locations_region_object{
  public $districts; // array of objects
  function __construct(){
    $this->districts = array();
  }
} 

class Import_locations_district_object{
  public $towns; // array of objects
  function __construct(){
    $this->towns = array();
  }
} 

class Import_locations_borough_object{
  public $name;
  public $uid; // unique id
  public $lid; // local id
}

class Import_locations_town_object{
  public $boroughs; // array of objects
  function __construct(){
     $this->boroughs = array();
  } 
}

class Import_locations_borough_object{
  public $name;
}
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
20. 4. 2016   #75
-
0
-

#73 peter
Co umí ovladač mysql v základu a PDO to neumí?

Nemohu navrhnout objekt, protože mi stále není jasné, co ta aplikace má dělat.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
20. 4. 2016   #76
-
+1
-
Zajímavé

#74 oxidián
Těch pár tříd s veřejnými atributy skutečně s OOP nemá nic společného. Používáš to jen jako alternativní strukturu. V těch třídách totiž vůbec nemáš žádné chování objektů.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
20. 4. 2016   #77
-
0
-

Import_locations_class->importAllFolders() - načte xml soubory ze složek s jazyky. Ve složce _default_ jsou austria.de.php, czech.cs.php, england.en.php, france.fr.php, germany.de.php, hungary.hu.php, poland.pl.php, slovakia.sk.php

Pořadí zemí a jazyků je předem dané.

 public function importAllFolders(){

  // spouští hlavní metodu pro načtení xml souboru
  $this->importLangFile(null,'_default_');
 }

 public function processAllData(){

  // spouští hlavní metodu pro vytažení dat z xml a přesunutí do datové struktury
  $this->processData(null,'_default_');
 }

$importer = new Import_locations_class($path);

$importer->importAllFolders();
$importer->processAllData();

Má naimportovat a připravit je do struktury $importer->data

Kromě složky default tam jsou i složky pro jednotlivé jazyky (překlady), tzn. že ve složce cs už není čeština, protože v ČR je jazykem čeština. Tam jsou pouze překlady.

Do array data zapisuji číselné indexy, kde číslo znamená číslo země, další úroveň obsahuje jazyk, kde klíč default znamená defaultní jazyk a překlady mají klič typu string (2 znaky).

Abych to shrnul co nejjednodušeji:

Zpracovávám nejdříve jazyky jedné země, a to vše uložím do $this->data. Schopnost je pojmout více zemí, avšak ve skutečnosti ještě před zápisem do mysql budu data dále převádět do finální podoby pomocí $this->queue() do pole $this->queue , takže data jsou vlastně jen dočasné pole. Tzn. zpracuju jednu zemi v různých jazycích a pak budu volat třetí funkci přímo zevnitř té funkce na zpracování dat processData(). Data pak stačí vyresetovat a pak zpracuju zase další zemi do $this->data a zase přidám do pole  $this->queue ... $this->queue() by měl taky vyhodnotit o jaký typ se jedná a do jaké tabulky to budu posílat. Až bude vše hotové zavolám metodu pro přidání do mysql.

Ještě jinak - z pohledu cyklů:

$attribs = $this->xml_data[$land][$lang]->attributes();      
$dataCountry =& $this->data[$countryID][$lang];

foreach($regions as $districtObj):

      $dataCountry->regions[] = new Import_locations_region_object;

      $dataRegion =& $dataCountry->regions[$localRegionCounter];
      $dataRegion->districts = array();

      foreach($districtObj as $districtID => $district):

        $dataRegion->districts[] = new Import_locations_district_object;
        $dataDistrict = $dataRegion->districts[$localDistrictCounter];

        foreach($district->towns->town as $k => $town ):

          $dataDistrict->towns[] = new Import_locations_town_object;
          $dataTown =& $dataDistrict->towns[$localTownCounter];

          foreach($town->boroughs->borough as $k => $borough ):  
            $dataTown->boroughs[] = new Import_locations_borough_object;
            $dataBorough =& $dataTown->boroughs[$localBoroughCounter];

          endforeach;

        endforeach;

endforeach;


To jsem zkrátil. Pochopitelně tam jsou ještě počítadla a přiřazování atributů, hlavně title členům objektu.
 

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
20. 4. 2016   #78
-
0
-

Myslím že si pod OOP představuješ, že by se jednotlivé úrovně foreach měly nechat zpracovat jednotlivými metodami. Ne vše v jedné metodě. Možná? Takže by objekt $this->country měl obsahovat metodu processRegions, která by provedla to co tam mám napsáno...

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
20. 4. 2016   #79
-
0
-

Tak co si o tom myslíš, pisni jak budeš mít čas jestli to mám tak předělat. Nerad bych to předělával dvakrát.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
20. 4. 2016   #80
-
0
-

#79 oxidián
Už jsem psal, že bych data tohoto typu nedával do aplikace, ale do databáze. Tím odpadá hromada starostí, protože data nemusíš všechna natahovat do RAM, ale vybereš si jen ten malý kousek, který skutečně potřebuješ.

PHP má na běžném hostingu k dispozici asi 5 různých databází, každou s jinými vlastnostmi. Typicky jsou dvě relační (MySQL a SQLite), další jsou typu KVS - např. INIFILE, CDB a DB4. Není tedy žádný důvod pro to, abys všechna data cpal do aplikace.

PHP dokonce umí prohledávat XML posobným způsobem, jako se vyhledává v SQL databázích. Jen se to nehodí pro moc velké soubory, protože PHP čte znovu celý soubor při každém dotazu z klientova prohlížeče. Se zvětšující velikostí XML se tedy efektivita snižuje. Podobně dopadnou i data umístěná přímo do skriptu PHP. Databáze však tímto netrpí.

Úkolem tedy není nacpat všechna data do objektů a pak si z nich vybírat, ale dostat do objektu pouze potřebná data a ta prezentovat. Tedy nefiltrovat výstup dat, ale vstup. A v tomhle jsou relační databáze skvělé. Poskytnou přesně ta data, která od nich požaduješ - PDO dokonce ve formě kolekce objektů. Stačí jen vyplivnout na výstup do HTML...

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
20. 4. 2016   #81
-
0
-

Tvoje poslední odpověď je pro mě sklamáním. Myslel jsem že si rozumíme o čem se tu bavíme. O čem tu celou dobu píšu. O programu, který data z xml naimportuje do db. Já přece nepsal nic o vybírání dat z objektů. Je to script na vyexportování dat z xml a na převedení do db. Kde teda vidíš jakýkoliv kód který obsahuje data v aplikaci?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
20. 4. 2016   #82
-
0
-

#81 oxidián
Promiň, už jsem se v té tvé aplikaci začal ztrácet. Je to na můj vkus překombinováno. Řešíš příliš mnoho problémů naráz a na jednom místě. Já sám si netroufám udělat ani dvojitý cyklus. Najednou tady vidím 4 vnořené cykly. Tak se nediv, že jsem z toho zmatený. A ty dlouhatánské identifikátory tomu vůbec nepomáhají, jsem zvyklý na jednoslovní. Používáš referenční odkazy, kterým se zásadně vyhýbám. Máš prostě jiný styl, tak se s tím musíš nějak poprat beze mne.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
20. 4. 2016   #83
-
0
-

ok, dík za vše

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
25. 4. 2016   #84
-
0
-

Projekt se blíží do konce a tak se chci zeptat jak by si vložil data do databáze mysql pomocí PDO. Jen pro představu zde je několik prvních položek z pole queue:

http://paste.ofcode.org/PMkPV9rjPCMWjiyRPdCVqH

Prosím o kompletní funkční příklad včetně konfigurace a připojení. Dík

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
25. 4. 2016   #85
-
0
-

Tak nic udělám to přes mysql_...

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
25. 4. 2016   #86
-
0
-

Poradíte mi proč vzniká tato chyba?

Chyba

SQL-dotaz:

CREATE TABLE test(
id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY ,
GROUP TINYINT unsigned NOT NULL default '1',
country TINYINT unsigned default NULL ,
INDEX SMALLINT default NULL ,
TYPE TINYINT unsigned NOT NULL default '0',
cs VARCHAR( 100 ) NOT NULL default '',
sk VARCHAR( 100 ) NOT NULL default '',
pl VARCHAR( 100 ) NOT NULL default '',
en VARCHAR( 100 ) NOT NULL default '',
fr VARCHAR( 100 ) NOT NULL default '',
hu VARCHAR( 100 ) NOT NULL default '',
de VARCHAR( 100 ) NOT NULL default ''
) CHARACTER SET utf8

MySQL hlásí: Dokumentace
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group TINYINT unsigned NOT NULL default '1',
  country TINYINT unsigned default' at line 3 
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
25. 4. 2016   #87
-
0
-

#86 oxidián
Asi proto, že u TINYINT má být DEFAULT 0

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
25. 4. 2016   #88
-
0
-

To nepomohlo. Tam je problém v tom že mysql nechápe že type a group jsou názvy sloupců. Interpretuje to jako příkazy GROUP a TYPE.

Pomohlo mi dosadit zpětné uvozovky: `group`

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
25. 4. 2016   #89
-
0
-

#88 oxidián
Ono je dobré se takovým názvům vyhýbat, abys nemusel v SQL dotazech psát ty zpětné apostrofy.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
25. 4. 2016   #90
-
0
-

Když mám tuto tabulku:

CREATE TABLE `options_locations` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `group` tinyint(3) unsigned NOT NULL default '0',
  `country` tinyint(3) unsigned default NULL,
  `index` smallint(6) default NULL,
  `type` tinyint(3) unsigned NOT NULL default '0',
  `cs` varchar(100) NOT NULL default '',
  `sk` varchar(100) NOT NULL default '',
  `pl` varchar(100) NOT NULL default '',
  `en` varchar(100) NOT NULL default '',
  `fr` varchar(100) NOT NULL default '',
  `hu` varchar(100) NOT NULL default '',
  `de` varchar(100) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


A snažím se vložit 11 záznamů do tabuky s 12 sloupci dostávám chybu:

INSERT INTO options_locations VALUES (0, 0,,128,'Česká Republika','','','Czechy','Czech Republic','République tchèque','Tschechische Republik')

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '128,'Česká Republika','','','Czechy','Czech Republic','République tchèque','' at line 1

Id je nastaveno jako auto_increment a tak bych očekával, že přeci nebudu sloupec id vkládat. Takže nechápu jak to mám udělat/vložit.

Jo a poddotaz: když není tam vkládám prázdnou hodnotu '' do cs a sk, mohu to tak nechat nebo je lepe dát null? jako , null, null místo , '', '' ? Má to vliv na výkon při načítání dat za tabulky?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
25. 4. 2016   #91
-
0
-

#90 oxidián
Do sloupce id buď nedáváš vůbec nic (ideální stav) nebo tam dáš NULL. Nesmíš do něj vložit 0, to je chyba.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
25. 4. 2016   #92
-
0
-

Jede to jen když tam dám null. Bez null to vrací chybu. S tím jsem se ještě nesetkal.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
25. 4. 2016   #93
-
0
-

Vkládání funguje, ale phpmyadmin nezobrazuje správně diakritiku utf-8. Pravděpodobně to není velký problém, ale vypadá to divně, když si prohlížím data.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
25. 4. 2016   #94
-
0
-

#92 oxidián
Když tam nedáš null, tak musíš vyjmout `id` ze seznamu sloupců. Pak to také funguje. Tomuto řešení dávám přednost, protože je imunní proti vkládání a přidávání sloupců do tabulky. Zároveň si tak udržuješ v aplikaci přehled o sloupcích v databázi. Reflexe je sice hezká věc, ale všechno má své meze.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
25. 4. 2016   #95
-
+1
-
Zajímavé

#93 oxidián
Protože jsi zapomněl jako první SQL příkaz v aplikaci poslat: 

SET NAMES utf8;

Pokud to tam nedáš, do databáze se uloží nesmysly, které se už těžko dají spravit.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
25. 4. 2016   #96
-
0
-

#95 Kit
Nevím jestli to dělá jedno a to samé, ale já tam mám toto:

ini_set('default_charset', 'UTF-8');

Vlastně mám v aplikaci tyto dva řádky:

    ini_set('default_charset', C_CHARSET);
    
    // mysql_query("SET NAMES utf8");


Z toho vyplývá že jsem to odkomentoval a nevím proč. Tedy se domnívám že tam problém není.

Edit:

Tak už vím proč to nebylo zakomentováno. Problém je v tom že jsem začal ukládat data bez tohoto příkazu. Abych je byl schopen přečíst v aplikaci tak jsem to zakomentoval. Když to odkomentuju tak se data vkládají správně.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
26. 4. 2016   #97
-
+1
-
Zajímavé
Kit +

Tak se to povedlo. Naimportoval jsem přes 11.000 záznamů a vložení do mysql zabralo jen 0.37s. Když jsem to zkoušel přes phpmyadmina tak to nešlo. Tak jsem udělal cyklus, který vytvořil 11 požadavků po 1000 záznamech a jeden navíc.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
26. 4. 2016   #98
-
0
-

Jakým způsobem by šlo upravit tento dotaz:

SELECT *
FROM `options_locations`
WHERE TYPE =104
LIMIT 0 , 30


aby se mi vypsaly jen ty výsledky kde sloupec `de` obsahuje text delší než určitý počet znaků? Např. 254

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
26. 4. 2016   #99
-
+1
-
Zajímavé

#98 oxidián

SELECT *
    FROM `options_locations`
    WHERE TYPE=104 AND LENGTH(de)>254
    LIMIT 0, 30

Zkus někdy místo té hvězdičky uvést seznam požadovaných sloupců.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
26. 4. 2016   #100
-
0
-

To je dobré, to jsem si nikdy nevšiml, že když v phpmyadminu provedu tenhle příkaz tak se mi zobrazí border v tom sloupci `de`. Dost dobrý, ale je lépe vidět jen když vypnu formátování dané webovou stránkou. To by asi nešlo zobrazit přímo délku té hodnoty v phpmyadminu, že?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
26. 4. 2016   #101
-
0
-

#100 oxidián
Neznám phpMyAdmin, nemám tedy zkušenosti s jeho formátováním.

Délku hodnoty si však můžeš zobrazit přímo SQL dotazem: 

SELECT id, LENGTH(de) AS length_de
    FROM `options_locations`
    WHERE TYPE=104
    LIMIT 0, 30
Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
26. 4. 2016   #102
-
0
-

Nemohl jsem se rozhodnout jestli to dát do jedné tabulky nebo do třech. Pak jsem narazil na nějaké omezení, myslím že to byla délka VARCHAR. Tak jsem to předělal aby se to posílalo do třech různých tabulek. Takže metoda, která vytváří SQL řetězec vyžadovala abych vytvořil řízení nad tím do které tabulky půjdou jednotlivá data. Není to tak jednoduché, když si vezmeš, že každý tabulka má trochu jiný počet sloupců. Tzn. není možné to dělat po 1000 řádcích. Ve výsledku to tedy vypadá takto:

http://paste.ofcode.org/fjnviPg5iENp8Pxc9wUdwB

Doba zpracování 8.6s . Stále rychlejší než v phpmy admin.

Docela mazec - kdybych tam měl víc dat jako čtvrti a města z dalších zemí tak by to bylo dost časově náročné.

Ale dalo by se to vyřešit tím, že bych zadal do hlavní metody, která země se má zpracovat a udělal bych to po jedné.

Momentálně to vypadá takto:

$path = C::PATH."/classes/lang";
$importer = new Import_locations_class($path, S::I()->Results);
$importer->importAllFolders();
$importer->processAllData();
$importer->queue();
$importer->clearData();

/*
$importer->mysql->dropTables();
$importer->mysql->createTables();
*/

$importer->mysql->truncateTables();    
$start = microtime (true);
$importer->mysql->insertDataFromQueue();
echo (microtime (true) - $start);
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
26. 4. 2016   #103
-
0
-

#102 oxidián
Typ VARCHAR je určen spíš pro jednotlivá slova, případně víceslovní názvy. Pro název města nebo jiného správního celku by 255 znaků mělo bohatě stačit.

Pro delší texty je zde typ TEXT, který je určen pro běžné texty do 64K znaků - pro články, blogy, komentáře. Nehodí se pro klíčové sloupce, ale je možné použít fulltext.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #104
-
0
-

Chystám se na sqlite. Mám pár otázek:

- Jak zjistit jakou mám verzi SQLite? Zatím ještě jedu na php 5.2.0 a tam je asli SQLite 2, ale nevím jak to potvrdit pomocí php.

- Jak nastavit pracovní adresář nebo umístění databáze? Nemusím to umísťovat přímo do příkazu CREATE TABLE?

- Má SQLITE taky stejný nebo podobný příkaz jako SET NAMES u mysql?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #105
-
+1
-
Zajímavé

#104 oxidián
Verze SQLite je dána použitým ovladačem. Třída SQLite se historicky zabývá verzí 2. V nových aplikacích už nemá opodstatnění. Ovladače SQLite3 a PDO obsluhují verzi 3. Dávám přednost PDO kvůli jednotnému ovládání více druhů databází.

Databázi umisťuji nejčastěji do adresáře, který je pro Apache neviditelný. Zároveň musí mít dostatek práv, aby do něj šlo zapsat z PHP. Lokaci zadávám do konstruktoru PDO. Celá databáze je v jednom souboru.

SQLite má jen omezenou podporu UTF-8, na rozdíl od MySQL nedělá žádné konverze vstupu a výstupu. To, co uložíš, to také vytáhneš. Příkaz SET NAMES tedy nemá význam.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #106
-
0
-

Co toto?

sqlite_query("SET CHARACTER SET $charset");
sqlite_query("SET COLLATION_CONNECTION='utf8_czech_ci';");

To má smysl dělat? Dělal jsem to u mysql

Já zatím PDO nepoužívám, ale později přejdu (umí PDO pracovat s verzí sqlite 2.8?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #107
-
0
-

#106 oxidián
Pro SQLite to smysl nemá. Nedělá konverze a proto jsou tyto příkazy zbytečné.

Nepoužívám je ani u MySQL.

SQLite 2 nepoužívám. V PDO se to nastaví změnou prefixu v DSN. Je to triviální úprava.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #108
-
0
-

#107 Kit
Chápu, jenže u mě to znamená předělat celý projekt, nejen ten aktuální na kterém dělám. Takže chci nejdříve dodělat jednu věc než zkusím PDO. Ale nevím jestli to má smysl na moji verzi php

Stále se mi nedaří najít příkaz na připojení k sqlite (sqlite_,,)

Mám sice tenhle vzor:

http://camendesign.com/code/uth3_sqlite/sqlite2.php

ale nejsem z toho moudrý

Je tam sqlite_open ten jsem použil, ale copak se tam nepoužívají přihlašovací údaje?

Aha, asi ne. Už začínám chápat. Když mám sqlite na straně apache, tak přihlašování je nepovinné ale mohu ho dodat pomocí php... Aspoň tak jsem to pochopil

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #109
-
0
-
Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #110
-
0
-

Jak to udělat, když v php chci nejdříve zjistit jestli tabulka existuje? Používám teď to sqlite_..., ale ideální by bylo vrátit buď 0 nebo 1 či false nebo true. Je na to SELECT dotaz?

Nechci používát toto

create table if not exists <tablename> . . .; truncate table <tablename>;

protože to chci oddělit takto:

if (!$table_exists){

$importer->sql->dropTables();
$importer->sql->createTables();

}

else

$importer->sql->truncateTables();    

Spíš než abych zevnitř truncateTables() šaškoval s vytvářením tabulky.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #111
-
0
-
Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #112
-
0
-

#111 Kit
A proč bych ji měl odstraňovat a potom znovu zakládat?

Asi jsem na to přišel:

SELECT name FROM sqlite_master WHERE type='table' AND name='table_name';
Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
27. 4. 2016   #113
-
0
-

Jak to má sqlite s uvozovkami pro sloupce? Když posílám požadavek jako tento:

CREATE TABLE options_locations_lists ( id int unsigned NOT NULL auto_increment primary key, country TINYINT unsigned, `type` TINYINT unsigned NOT NULL default 0, `default` TEXT NOT NULL default '', cs TEXT NOT NULL default '', sk TEXT NOT NULL default '', pl TEXT NOT NULL default '', en TEXT NOT NULL default '', fr TEXT NOT NULL default '', hu TEXT NOT NULL default '', de TEXT NOT NULL default '' ) CHARACTER SET utf8


Tak dostávám chybu:

unrecognized token: "`"

ale musím mít v uvozovkách kvůli mysql, když používám jeden a ten samý sql příkaz jak pro mysql tak pro sqlite. A v uvozovkách je to proto aby nedošlo k záměně se slovy vyhrazenými SQL - DEFAULT, TYPE, GROUP.

Edit:

Zde jsem se dočetl:

https://www.sqlite.org/lang_keywords.html

`keyword` A keyword enclosed in grave accents (ASCII code 96) is an identifier. This is not standard SQL. This quoting mechanism is used by MySQL and is included in SQLite for compatibility.

Nicméně pokud bych použil na sloupce uvozovky "" nevím jestli to mysql akceptuje?

Edit:

http://stackoverflow.com/questions/13884854/mysql-double-quoted-table-names

Tak dvojté uvozovky v mysql zase nefungujou tak asi mi nezbývá než to `` přejmenovat manuálně

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #114
-
0
-

#112 oxidián
Protože tak jsi to chtěl. Alespoň tak jsem tvůj požadavek pochopil, i když jsem ho nechápal.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #115
-
0
-

To ne, já chci vymazat tabulku pokud existuje, pokud neexistuje tak ji vytvořím. Ale to podstatné, je že je to oddělené přes jednotlivé metody. Prostě když se metoda jmenuje truncate tak by neměla zakládat tabulku, apod.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #116
-
0
-

#113 oxidián
SQLite se na rozdíl od MySQL drží standardu, takže identifikátory se nedávají do zpětných apostrofů, ale do uvozovek.

Uvozovky v MySQL fungují. Stačí se úvodním SQL dotazem přepnout do standardního chování.

Tahle schizofrenie implementací v mém případě vedla k tomu, že zpětné apostrofy ani uvozovky v SQL dotazech nepoužívám. Prostě se nevhodným identifikátorům vyhýbám, protože je to opruz.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
27. 4. 2016   #117
-
0
-

#115 oxidián
Podmíněné vymazání tabulky je DROP TABLE IF EXISTS. Vytvoření tabulky zase CREATE TABLE. Když tyto dva příkazy dáš za sebou, bude to OK.

Příkaz TRUNCATE je docela ošemetný, protože obchází některá integritní omezení databáze. Je lepší se mu vyhnout.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #118
-
0
-

Tak to bych udělal taky, ale jak je ten úvodní SQL dotaz aby se mysql chovalo standardně?

Mimoto jsem zjistil, že mi nejdou přejmenovat ty zpětné uvozovky

  private function do_sqlite()
    {
    $count_of_rows = null;
    $handle = S::I()->sqlite->getHandle();
    $query = $this->query;
    if (SQLITE::REPLACE_GRAVE_ACCENTS_TO_DOUBLE_QUOTES)
      $query = str_replace('`','"', $query);
      echo $query."<br>";
    $original_query_result = sqlite_query( $handle, $query);

$query = str_replace('`','"', $query); nefunguje
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #119
-
0
-

#118 oxidián
Takové operace se stejně nedělají na hotových SQL dotazech. Je lepší ten SQL dotaz udělat pro každou databázi zvlášť a rovnou tam dát to správné quotování.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #120
-
0
-

Uvozovky v MySQL fungují. Stačí se úvodním SQL dotazem přepnout do standardního chování.

Ještě si nenapsal jak zní ten dotaz. Stále na to čekám.

A mohu to vůbec ovlivnit nebo je to pevně nastavené v konfiguráku vzdáleného serveru?

Edit:

No jo jenže ono to není tak jednoduché:

SQL mode and user-defined partitioning.  Changing the server SQL mode after creating and inserting data into partitioned tables can cause major changes in the behavior of such tables, and could lead to loss or corruption of data. It is strongly recommended that you never change the SQL mode once you have created tables employing user-defined partitioning.

https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html#sql-mode-setting

Edit 2:

Možná by šlo nastavit pouze toto?

ANSI_QUOTES

Treat “"” as an identifier quote character (like the “`” quote character) and not as a string quote character. You can still use “`” to quote identifiers with this mode enabled. With ANSI_QUOTES enabled, you cannot use double quotation marks to quote literal strings, because it is interpreted as an identifier.

A nehrozilo by tak poškození existujících tabulek?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #121
-
+1
-
Zajímavé

#120 oxidián
Tak jsem to za tebe vyhledal v manuálu: 

SET sql_mode='ANSI_QUOTES';
Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #122
-
0
-

Dík, já ho čtu ale tam jsem se ještě nedočetl.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
27. 4. 2016   #123
-
0
-

Ty uvozovky kolem soupců a tabulek ale nejsou povinné ne?

Dal by se např. takový dotaz spolehlivě přečíst?

místo

SELECT LEFT(`message`,50) as message, LEFT(`badwords`,100) as badwords

dát

SELECT LEFT(message,50) as message, LEFT(badwords,100) as badwords

a dvojíté uvozovky dát pouze tam kde hrozí záměna s klíčovým slovem

Jěště jsem si zkoušel v mysql jestli mi toto bude fungovat:

SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='options_options' AND TABLE_SCHEMA='locations'


a normálně to funguje i bez uvozovek kolem indentifikátorů, takže pokud to půjde odstraním uvozovky. Tím bude méně problémů s escapováním.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #124
-
0
-

#123 oxidián
Přesně to jsem se ti pokoušel vysvětlit. Využívám toho i ke konverzím mezi zvyklostmi jazyků SQL a PHP: 

SELECT sloupec_jedna AS sloupecJedna, sloupec_dva AS sloupecDva
    FROM tabulka;

V PHP se mi ty záznamy objeví už ve správné konvenci: 

echo $row->sloupecJedna, $row->sloupecDva;
Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
27. 4. 2016   #125
-
0
-

Další problém mi hlásí chybu poblíž auto_increment:

CREATE TABLE options_locations ( id int unsigned NOT NULL auto_increment primary key, country TINYINT unsigned, "index" TINYINT unsigned, type TINYINT unsigned NOT NULL default 0, "default" VARCHAR(100) NOT NULL default '', cs VARCHAR(100) NOT NULL default '', sk VARCHAR(100) NOT NULL default '', pl VARCHAR(100) NOT NULL default '', en VARCHAR(100) NOT NULL default '', fr VARCHAR(100) NOT NULL default '', hu VARCHAR(100) NOT NULL default '', de VARCHAR(100) NOT NULL default '' ) CHARACTER SET utf8

Já myslel že ten SQLITE je zpětně kompatibilní s MYSQL/SQL.Takže mi nezbývá než to přejmenovat pomocí str_replace? I CREATE Table to přece nevadí... Takže se mi to zdá jako nejjednodušší řešení.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
27. 4. 2016   #126
-
0
-

#125 oxidián
Je tam toho víc. Vzorem pro SQLite totiž nebyla databáze MySQL, ale standard SQL. Proto ty odlišnosti. 

CREATE TABLE options_locations (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    country INT,
    "index" INT,
    "type" INT DEFAULT 0,
    "default" TEXT DEFAULT '',
    cs TEXT DEFAULT '',
    sk TEXT DEFAULT '',
    pl TEXT DEFAULT '',
    en TEXT DEFAULT '',
    fr TEXT DEFAULT '',
    hu TEXT DEFAULT '',
    de TEXT DEFAULT ''
);

To "id" nesmí být INT, ale musí být INTEGER. Klauzule "NOT NULL" není nutná, když tam máš ten DEFAULT.

Nahlásit jako SPAM
IP: 194.228.68.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
28. 4. 2016   #127
-
0
-

Stále mi to vrací chybu poblíž AUTOINCREMENT

CREATE TABLE options_locations_lists (

id INTEGER primary key AUTOINCREMENT,

country TINYINT,

type TINYINT default 0,

"default" TEXT default '', cs TEXT default '', sk TEXT default '', pl TEXT default '', en TEXT default '', fr TEXT default '', hu TEXT default '', de TEXT default ''

) CHARACTER SET utf8

SQL logic error or missing database

Nahlásit jako SPAM
IP: 78.45.87.–
z_moravec
~ Redaktor
+3
Posthunter
28. 4. 2016   #128
-
0
-

Zkus toto:

CREATE TABLE options_locations_lists (

id INTEGER AUTO_INCREMENT,

country TINYINT,

type TINYINT default 0,

PRIMARY KEY(id),

"default" TEXT default '', cs TEXT default '', sk TEXT default '', pl TEXT default '', en TEXT default '', fr TEXT default '', hu TEXT default '', de TEXT default ''

) CHARACTER SET utf8
Nahlásit jako SPAM
IP: 147.251.29.–
Spát lze čtyři hodiny denně, spát déle je nemístný přepych.
Thomas Alva Edison
oxidián0
Grafoman
28. 4. 2016   #129
-
0
-

Když vymažu primary key tak to hlásí chybu poblíš CHARACTER. Takže PRIMARY KEY a CHARACTER SET musím vymazat?

Edit: Tak jo, teď se to vytvořilo. Ještě tam mám chyby poblíž TRUNCATE a jednu (?) chybu v INSERT

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
28. 4. 2016   #130
-
0
-

Když zadám požadavek

TRUNCATE TABLE options_locations

tak mi to hlásí

sqlite_query() [function.sqlite-query]: near "TRUNCATE": syntax error

TRUNCATE TABLE options_locations

Ale našel jsem řešení:

DELETE FROM options_locations_lists; VACUUM;

Ještě mě překvapilo že databáze zabírá 590kb. V mysql ty tři tabulky zabírají celkem 40kb. Ale je fakt, že v mysql jsou ještě další soubory. V mysql má prázdná tabulka kolem 9-10kb a celkem 58 tabulek zabírá 507kb. Takže to vypadá že s sqlite musím počítat že bude zabírat víc než mysql. Nejspíš je to dáno těmi městy, které jsou ve formátu text místo varchar.

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
28. 4. 2016   #131
-
0
-

Takovou drobnosti, jako par kilo navic, bych se netrapil :) Nejnovejsi disky maji 30T. I free hostingy nabizeji min 50MB, spis vic. Vetsi obrazek ma pres mega.
Je mozne, ze by to slo zipovat. Texty se daji tusim na 20-30%. Jakoze by si to mohlo umet db zazipovat a pouzivat pak jen indexy k dohledani.

Nahlásit jako SPAM
IP: 2001:718:2601:1f7:35d4:99...–
oxidián0
Grafoman
28. 4. 2016   #132
-
0
-

zazipovat třeba vzkazy co půjdou do archivu, apod. Dobrý nápad

Edit:

Ještě budu potřebovat vyřešit jak prohlížet data. Program DB Browser for SQLite mi hlásí invalid file format. Přitom píšou že je to kompatibilní s verzí 2

Edit 2:

Nainstaloval jsem si toto rozšíření do Firefoxu

ale bohužel mi také píše že databáze je poškozená

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
28. 4. 2016   #133
-
0
-

Kde je chyba?

$importer->sql->do_sql(
"INSERT INTO 'options_locations' 
('id', 'country', 'index', 'type', 'default', 'cs', 'sk', 'pl', 'en', 'fr', 'hu', 'de') 
VALUES(null, '0','0','8','Adamov','','','','','','',''),
      (null, '0','1','8','Bečice','','','','','','','')
");

syntax error near ","

Když vymažu druhý vkládaný řádek tak se to povede. Dva řádky a víc nejdou vložit.

dotazy INSERT na ostatní tabulky mi fungují, toto ne.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
28. 4. 2016   #134
-
0
-

#127 oxidián
Kde jsi vyhrabal typ TINYINT? V SQLite nic takového není.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
28. 4. 2016   #135
-
0
-

#130 oxidián
Když do SQLite budeš neustále zapisovat a zase mazat, tak se ta databáze trochu nafoukne kvůli fragmentaci. Psal jsem, že by ses měl vyhýbat příkazu TRUNCATE.

Příkaz VACUUM slouží k defragmentaci. DB soubor se tím zkrátí.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
28. 4. 2016   #136
-
0
-

#132 oxidián
Zipování dat v databázi je špatný nápad, zejména kvůli vyhledávání. Vzkazy bývají krátké, na nich neušetříš.

Nechápu, proč se snažíš používat SQLite 2.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
28. 4. 2016   #137
-
0
-

#133 oxidián
Kolem identifikátorů máš místo uvozovek apostrofy. To nemůže fungovat. Zkus tohle: 

$insert = <<<EOT
INSERT INTO "options_locations" (
   "country", "index", "type", "default", cs, sk, pl, en, fr, hu, de
) VALUES (
   '0', '0', '8', 'Adamov','','','','','','',''
);
EOT;
$importer->sql->do_sql($insert);

Když se naučíš prepared statements v PDO, bude to mnohem kratší, jednodušší a rychlejší.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
28. 4. 2016   #138
-
0
-

#136 Kit
Psal jsem že upgraduju až dokončím určitou programovací etapu. Testovací data mám ve staré db. Je to práce na několik měsíců, bohužel to jde tak pomalu.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
29. 4. 2016   #139
-
0
-

Zprvu jsem nechápal jak se tam ty uvozovky dostaly. Bylo to tak, že jsem to zkopíroval z phpmyadmina kde byly zpětné uvozovky ``. Pak jsem dělal hromadné nahrazování v celém projektu kde jsem nahrazoval ` za \' ... a tak se změnil význam uvozovek. Ale už jsem to odstranil.

Co se týče toho TINYINT, tak s tím si sqlite poradil. Sqlite neumožňuje použít jendobytové číselné hodnoty? To je dost na houby, to bude tabulka (*) zbytečně zabírat data navíc. Když je tam hodně hodnot v malém číselném rozsahu. * - myslím tabulku jiného projektu.

Já už TRUNCATE nepoužívám, používám DELETE ...

INSERT INTO options_locations (id, country, "index", type, "default", cs, sk, pl, en, fr, hu, de) VALUES(null, 3,'0',8,'Bromsgrove','','','','','','',''),(null, 3,'1',8,'Malvern Hills','','','','','','',''),(null, 3,'2',8,'Redditch','','','','','','',''),(null, 3,'3',8,'Worcester','','','','','','',''),(null, 3,'4',8,'Wychavon','','','','','','',''),(null, 3,'5',8,'Wyre Forest','','','','','','',''),(null, 3,'',32,'Yorkshire and the Humber','Yorkshire a Humber','Yorkshire a Humber','Yorkshire i Humber','','Yorkshire et Humber','Yorkshire és Humber','Yorkshire und Humber')


Warning: sqlite_query() [function.sqlite-query]: near ",": syntax error


Tu chybu s čárkou jsem stále nevyřešil

Toto mi jede:

S::I()->sqlite->view->sql->SQL('INSERT INTO options_locations (id, country, "index", type, "default", cs, sk, pl, en, fr, hu, de) '.
"VALUES(null, 3,'0',8,'Bromsgrove',   '','','','','','','')");

Když přidám čárku za ukončovací závorku a zkopíruju/vložím ty hodnoty ještě jednou

(null, 3,'0',8,'Bromsgrove',   '','','','','','','')

tak mám:

S::I()->sqlite->view->sql->SQL('INSERT INTO options_locations (id, country, "index", type, "default", cs, sk, pl, en, fr, hu, de) '.
"VALUES(null, 3,'0',8,'Bromsgrove',   '','','','','','',''),(null, 3,'0',8,'Bromsgrove',   '','','','','','','')");


a je to chyba

Našel jsem vysvětlení.

Tohle jede (jeden řádek):

S::I()->sqlite->view->sql->SQL('INSERT INTO options_locations
SELECT null as id, 3 as country, 0 as "index", 8 as type, '.
"'Bromsgrove' as \"default\", '' as cs,'' as sk,'' as pl,'' as en,'' as fr,'' as hu,'' as de"
); 
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
29. 4. 2016   #140
-
0
-

#139 oxidián
Integer v SQLite je inteligentní, zabírá jen tolik bajtů, kolik je potřeba. U malých čísel jen jeden.

Však jsem psal, že to máš napsat takhle: 

INSERT INTO options_locations (country, "index", type, "default") 
    VALUES (3,'0',8,'Bromsgrove');

Místo čárky tam za závorku patří středník.

Pokoušíš se o to, co je v MySQL nestandardním syntaktickým cukrem. V SQLite se to řeší jinak, elegantněji - přes prepared statements v transakci.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
29. 4. 2016   #141
-
0
-

#140 Kit
To čemu říkáš nestandardní syntatický cukr se běžně používá v phpmyadmin pro export z databáze. Takže ty bych chtěl abych to dělal po jednotlivých řádcích tzn vytvořit 11278 sqlite požadavků? Jestli jsem tě správně pochopil.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
29. 4. 2016   #142
-
0
-

#141 oxidián
Ano, 11278 požadavků uzavřených do jedné transakce. Ta to významně zrychlí.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
29. 4. 2016   #143
-
0
-

Aha už chápu. A co si myslíš o tom stylu s SELECT ... UNION ALL SELECT  ? Prý je to výkonný.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
29. 4. 2016   #144
-
0
-

#143 oxidián
UNION ALL se k tomu také dá využít, ale připadá mi to jako kanón na vrabce.

Prepared statements se mi jeví jako mnohem praktičtější: Napíšeš jeden SQL dotaz, jednou ho zkompiluješ a pak už jen do tohoto virtuálního procesoru v cyklu sázíš data. Když před cyklem otevřeš transakci a za cyklem ji zavřeš, je to bleskové.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
29. 4. 2016   #145
-
0
-

Je to ovšem podivné a velikost řetězce/paměti narůstá s tím že musíš vždy opakovat sloupce

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
29. 4. 2016   #146
-
0
-

#145 oxidián
Právěže nemusíš: 

<?php
$pdo->beginTransaction();
$sql = <<<EOT
INSERT INTO options_locations (country, "index", "type", "default", cs)
    VALUES (?, ?, ?, ?, ?)
EOT;
$insert = $pdo->prepare($sql);
foreach ($data as $line) {
    $insert->execute(array(
        $line['country'],
        $line['index'],
        $line['type'],
        $line['default'],
        $line['cs']
    ));
}
$pdo->commit();

Metodou prepare() se ten SQL dotaz přeloží a pak už jen přes execute() sypeš data.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
29. 4. 2016   #147
-
0
-

Mohl bys sem vlepit ten hotový dotaz SQL třeba na pět řádků? Z tohoto nejsem moudrý.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
29. 4. 2016   #148
-
0
-

#147 oxidián
Máš ho tam na dvou řádcích v proměnné $sql. To nestačí?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
30. 4. 2016   #149
-
0
-

Nevim jestli jsem to spravně pochopil sestavuješ tento řetězec?

INSERT INTO options_locations (country, "index", type, "default")
VALUES (3,'0',8,'Bromsgrove');
INSERT INTO options_locations (country, "index", type, "default")
VALUES (3,'1',8,'Basildon');
INSERT INTO options_locations (country, "index", type, "default")
VALUES (3,'2',8,'Brainttree');
INSERT INTO options_locations (country, "index", type, "default")
VALUES (3,'3',8,'Brentwood');

atd?
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
30. 4. 2016   #150
-
0
-

#149 oxidián
Ne. Je to jen jeden krátký řetězec s těmi otazníky. Ten je metodou prepare() zkompilován do podoby virtuálního procesoru. Tomu pak jen dodáváš data.

Výhodou tohoto postupu je, že nemusíš řešit tzv. SQL injection. Do databáze jde totiž zvlášť SQL dotaz a zvlášť data. Dokonce tímto způsobem můžeš do DB uložit delší datové záznamy, než je maximální povolená délka SQL dotazu.

MySQL to umí také, ale defaultně je PDO pro MySQL nastavené na emulaci. Tedy tak, že se data escapují a vkládají místo těch otazníků přímo do řetězce SQL dotazu. Tak, jak sis to myslel o SQLite.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
30. 4. 2016   #151
-
0
-

Co znamená to  <<<EOT ? Není to otevření streamu?
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
30. 4. 2016   #152
-
+1
-
Zajímavé

#151 oxidián
To je Heredoc. Umožňuje psát dlouhé, i víceřádkové stringy, které obsahují apostrofy i uvozovky. Navíc umí do toho stringu expandovat obsah proměnných i objektů podobně jako stringy v uvozovkách. Odpadají trable s escapováním uvozovek v atributech elementů HTML a proměnné vkládáš přímo - místo <?= $var ?> píšeš jen $var .

Místo slova EOT může být jakékoli slovo, které se v tom stringu nevyskytuje. Tímto slovem se string i ukončí. Musí být na samostatném řádku a kromě středníku už za ním nesmí nic být.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
30. 4. 2016   #153
-
0
-

Už chápu. V PHP manuálu jsem o tom nic nenašel. Od které verze PHP se to dá použít?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
30. 4. 2016   #154
-
+1
-
Zajímavé
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
30. 4. 2016   #155
-
0
-

To zírám, že jsem to ještě nikdy neviděl.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
30. 4. 2016   #156
-
0
-

#155 oxidián
PHP má spoustu velmi zajímavých vychytávek. Také jsem kdysi nechápal, k čemu je v něm dobrý "interface", když se bez něj obejde, ale dnes bych už bez něho DI nedělal. Velmi zajímavé jsou uzávěry, operace map/filter/reduce, přímé čtení CSV, JSON, XML a dalších formátů včetně jejich generování, ...

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
30. 4. 2016   #157
-
0
-

Uzávěry pro mě nejsou aktuální, ale jinak znám z JS.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
30. 4. 2016   #158
-
0
-

#146 Kit
Ty sice nepoužíváš uvozovky, ale interně si ten pdo ty uvozovky musí dosadit. Posíláš tam hodnoty, ale interně sestaví nějaký SQL dotaz a ten ty uvozovky musí obsahovat.

Já to dělám takto:

$special = array();
$special['type'] = SQL_query_type::INSERT_SELECT_MULTIPLE;
$this->sql->SQL("INSERT INTO $table", $special, SQL_query_mode::PREPARE);
$special['header'] = 'id,group,type,"default",cs,sk,pl,en,fr,hu,de';          
$special['row'] = array(null,$q['group'],$q['type'],$default,$cs,$sk,$pl,$en,$fr,$hu,$de); 
$this->sql->SQL('INSERT', $special, SQL_query_mode::PREPARE_AND_INITIATE);
$this->sql->SQL('INSERT ...', $special, SQL_query_mode::EXECUTE);

a pátém řádku vkládám hodnoty do pole, tudíž medota SQL mi musí dosadit uvozovky pro jednotlivé sloupce. Interně se volá metoda prepare();

dotaz k sql injection. Stačí ty jednoduché uvozovky vyescapovat \' nebo se to musí nahradit za html entitu? Často jsem viděl že programátoři z nějakého důvodu používají htmlentities(), ale proč? Vždyď jediné riziko je u té jednoduché uvozovky. Ještě mě napadá možnost vkládání tagů a (java)scriptů do stránky, tak nahradit <,>.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
30. 4. 2016   #159
-
+1
-
Zajímavé

#158 oxidián
To dosazováí quotovaných dat se dělá pouze v případě emulace u MySQL. Jinak ne. Skus si to najít v manuálu SQLite, je to tam docela dobře vysvětleno. Do SQL dotazu se data prostě neexpandují. SQL dotaz se posílá zvlášť (s otazníky místo dat) a data také zvlášť (bez uvozovek).

Používání funkce htmlentities() při ukládání do databáze je blbost z několika důvodů:

  1. SQL nemá s HTML nic společného. Když  pak chceš data vložit třeba do LaTeXu, máš problém.
  2. Problém je i s délkou, protože entita je delší než znak. Může snadno dojít k oříznutí v nevhodném místě.
  3. Tato funkce databázi neochrání.

Příklad, který jsem uvedl, je bez frameworku a je kompletní. Není mi jasné, co se na něm snažíš vylepšit. tvůj příklad se mi jeví jako obtížně čitelný - chybu bych v něm hledat nechtěl. Co dělá tvoje metoda SQL(), je mi také záhadou. Kromě toho porušuješ konvence názvu metody.

Do příkazu INSERT nedávej sloupec "id". Máš ho tam zcela zbytečně, stejně do něj cpeš NULL.

Na escapování apostrofů je v PDO metoda quote(), která doplní i okrajové apostrofy. Je to pohodlnější než mysql_real_escape_string() pro MySQL. Navíc to dělá přesně podle typu databáze - jinak se escapuje pro MySQL, jinak pro PostgreSQL a SQLite. S metodou quote() tě to může přestat zajímat.

Čísla se do uvozovek ani apostrofů nedávají. Není k tomu důvod.

Jednoduché uvozovky mají význam v typografii, ale při programování se nepoužívají.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
30. 4. 2016   #160
-
0
-

#159 Kit
 

SQL dotaz se posílá zvlášť (s otazníky místo dat) a data také zvlášť (bez uvozovek).

To mluvíš ale o PDO a já PDO ještě nepoužívám...

Já se do PDO teď nebudu vrhat do by bylo na rok než bych vše předělal.

Ohledně PDO zacházíš moc do detailů, které si stejně nezapamatuju. Pracuji s rozšířením sqlite_ . Beru to jen informativně a že budu sem mít možnost nahlédnout až se tím začnu zabývat.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
30. 4. 2016   #161
-
0
-

#160 oxidián
Nejen PDO, ale i ovladače SQLite3 a MySQLi používají prepared statements.

PDO jsem začal používat právě kvůli jeho jednoduchosti. Pracuje se s ním stále stejně bez ohledu na to, zda ta databáze je MySQL, PostgreSQL nebo SQLite. Ovládání je jednotné.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
30. 4. 2016   #162
-
0
-

Tak to pak třeba updatuju až na to bude čas.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
1. 5. 2016   #163
-
0
-

Zjistil jsem jak dlouho to trvlá když při sqlite používám to SELECT UNION ALL. Oproti mysql se to zdá výrazně pomalejší než u mysql (syntaxe INSERT INTO .. VALUES ..,...,..):

Můžeš to vyzkoušet u sebe


length: 8479 , time: 0.306387901306s

http://paste.ofcode.org/kQ42FYAv5uicBLRJNW63u3


length: 13616 , time: 0.0454878807068s

http://paste.ofcode.org/394GhieHZ9j8W5ERAmBEeXb

Při cca 11000 cyklech to trvá 20s kdežto mysql to měl celé za 8s. Ještě jsem nezkoušel měnit konfiguraci slite, ale zdá se mi že 10-13kb není moc na to aby to trvalo tak dlouho. Php to vydnotí za zlomek vteřiny, zbytek je čekání na sqlite.

Taky se chci zeptat proč mi tento dotaz hlásí chybu:

$sql = <<<EOT
INSERT INTO options_locations_lists SELECT 
null as id, 
'4' as country,
'102' as type,
'Alsace-Champagne-Ardenne-Lorraine;Aquitaine-Limousin-Poitou-Charente;Auvergne-Rhône-Alpes;Bretagne;Burgundsko-Franche-Comté;Centre-Val de Loire;Île-de-France;Languedoc-Roussillon-Midi-Pyrénées;Nord-Pas-de-Calais-Pikardie;Normandie;Pays de la Loire;Provence-Alpes-Côte d\'Azur;' as "default", 
'Alsasko-Champagne-Ardenne-Lotrinsko (Alsace-Champagne-Ardenne-Lorraine);Akvitánie-Limousin-Poitou-Charente (Aquitaine-Limousin-Poitou-Charente);Auvergne-Rhône-Alpes;Bretaň (Bretagne);Burgundsko-Franche-Comté;Centre-Val de Loire;Île-de-France;Languedoc-Roussillon-Midi-Pyrénées;Nord-Pas-de-Calais-Pikardie;Normandie;Pays de la Loire;Provence-Alpes-Côte d\'Azur;' as cs, 
'Alsasko-Champagne-Ardenne-Lotrinsko (Alsace-Champagne-Ardenne-Lorraine);Akvitánie-Limousin-Poitou-Charente (Aquitaine-Limousin-Poitou-Charente);Auvergne-Rhône-Alpes;Bretónsko (Bretagne);Burgundsko-Franche-Comté;Centre-Val de Loire;Île-de-France;Languedoc-Roussillon-Midi-Pyrénées;Nord-Pas-de-Calais-Pikardie;Normandie;Pays de la Loire;Provence-Alpes-Côte d\'Azur;' as sk, 
'Alzacja (Alsace-Champagne-Ardenne-Lorraine);Akwitania (Aquitaine-Limousin-Poitou-Charentes);Auvergne-Rhône-Alpes;Bretania;Burgundia (Bourgogne-Franche-Comté;Region Centralny-Dolina Loary (Centre-Val de Loire);Île-de-France;Languedoc-Roussillon-Midi-Pyrénées;Nord-Pas-de-Calais-Pikardie;Normandia;Pays de la Loire;Provence-Alpes-Côte d\'Azur;' as pl, 
'Alsace-Champagne-Ardenne-Lorraine;Aquitaine-Limousin-Poitou-Charente;Auvergne-Rhône-Alpes;Bretagne;Burgundsko-Franche-Comté;Centre-Val de Loire;Île-de-France;Languedoc-Roussillon-Midi-Pyrénées;Nord-Pas-de-Calais-Pikardie;Normandie (Normandy);Pays de la Loire;Provence-Alpes-Côte d\'Azur;' as en, 
'' as fr,
'Alsace-Champagne-Ardenne-Lorraine;Aquitania (Aquitaine-Limousin-Poitou-Charente);Auvergne-Rhône-Alpes;Bretagne;Burgundia (Bourgogne-Franche-Comté);Centre-Val de Loire;Île-de-France;Languedoc-Roussillon-Midi-Pyrénées;Nord-Pas-de-Calais-Pikardie;Normandia;Pays de la Loire;Provence-Alpes-Côte d\'Azur;' as hu, 
'' as de    
EOT;
$result = sqlite_query( $handle, $sql);
if ( $result === false )
{
      $offset = strpos($query, ' ');
      $command = substr($query, 0, $offset);
		  echo "<b>Sqlite $command error: </b>".sqlite_error_string( sqlite_last_error($handle) )."<p>/";
      echo $this->callingFunction."/<p>";
      echo $query;
      die;
      return -1;
}


Vkládám tam 11 záznamů

PS: dotaz jsem zkopíroval, je automaticky vygenerovaný a nemá smysl odstraňovat uvozovky u číselných hodnot, protože to na výkon nemá žádný vliv.

PS:

PRAGMA synchronous = OFF

To urychlí o jednu desetinu vteřiny (19,9s).

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
1. 5. 2016   #164
-
0
-

Je zvláštní, že někdy 5 záznamů za sebou jedním příkazem zabere

0.024s a hned na to další příkaz s 9 záznamy zabere 0.119442939758 s. Toto nechápu.

Třeba tenhle krátký:

INSERT INTO options_locations SELECT null as id, '4' as country, '0' as "index", '16' as type, 'Côtes-d\'Armor' as "default", '' as cs, '' as sk, '' as pl, '' as en, '' as fr, '' as hu, '' as de UNION ALL SELECT null,'4','1','16','Finistère','','','','','','','' UNION ALL SELECT null,'4','2','16','Ille-et-Vilaine','','','','','','','' UNION ALL SELECT null,'4','3','16','Morbihan','','','','','','','' UNION ALL SELECT null,'4',null,'32','Burgundsko-Franche-Comté','','','Burgundia (Bourgogne-Franche-Comté','','','Burgundia (Bourgogne-Franche-Comté)','' 



0.0244328975677 s +5 records in db. 1462181069


A jeden záznam dlouhý (seznam měst):

INSERT INTO options_locations_lists SELECT null as id, '0' as country, '104' as type, 'Bezděkov;Břasy;Březina;Bujesily;Bušovice;Cekov;Čilá;Dobřív;Drahoňův Újezd;Ejpovice;Hlohovice;Holoubkov;Hradiště;Hrádek;Hůrky;Cheznovice;Chlum;Chomle;Kakejcov;Kamenec;Kamenný Újezd;Kařez;Kařízek;Klabava;Kladruby;Kornatice;Lhota pod Radčem;Lhotka u Radnic;Liblín;Litohlavy;Líšná;Medový Újezd;Mešno;Mirošov;Mlečice;Mýto;Nevid;Němčovice;Osek;Ostrovec-Lhotka;Plískov;Podmokly;Příkosice;Přívětice;Raková;Radnice;Rokycany;Sebečice;Sirá;Skomelno;Skořice;Smědčice;Strašice;Svojkovice;Štítov;Terešov;Těně;Těškov;Trokavec;Týček;Újezd u Svatého Kříže;Vejvanov;Veselá;Vísky;Volduchy;Všenice;Zbiroh;Zvíkovec' as "default", '' as cs, '' as sk, 'Bezděkov;Břasy;Březina;Bujesily;Bušovice;Cekov;Čilá;Dobřív;Drahoňův Újezd;Ejpovice;Hlohovice;Holoubkov;Hradiště (Twierdza);Hrádek;Hůrky;Cheznovice;Chlum;Chomle;Kakejcov;Kamenec;Kamenný Újezd;Kařez;Kařízek;Klabava;Kladruby;Kornatice;Lhota pod Radčem;Lhotka u Radnic;Liblín;Litohlavy;Líšná;Medový Újezd;Mešno;Mirošov;Mlečice;Mýto;Nevid;Němčovice;Osek;Ostrovec-Lhotka;Plískov;Podmokly;Příkosice;Přívětice;Raková;Radnice;Rokycany;Sebečice;Sirá;Skomelno;Skořice;Smědčice;Strašice;Svojkovice;Štítov;Terešov;Těně;Těškov;Trokavec;Týček;Újezd u Svatého Kříže;Vejvanov;Veselá;Vísky;Volduchy;Všenice;Zbiroh;Zvíkovec' as pl, 'Bezděkov;Břasy;Březina;Bujesily;Bušovice;Cekov;Čilá;Dobřív;Drahoňův Újezd;Ejpovice;Hlohovice;Holoubkov;Hradiště (Hillfort);Hrádek (Small Castle);Hůrky;Cheznovice;Chlum;Chomle;Kakejcov;Kamenec;Kamenný Újezd;Kařez;Kařízek;Klabava;Kladruby;Kornatice;Lhota pod Radčem;Lhotka u Radnic;Liblín;Litohlavy;Líšná;Medový Újezd;Mešno;Mirošov;Mlečice;Mýto;Nevid;Němčovice;Osek;Ostrovec-Lhotka;Plískov;Podmokly;Příkosice;Přívětice;Raková;Radnice;Rokycany;Sebečice;Sirá;Skomelno;Skořice;Smědčice;Strašice;Svojkovice;Štítov;Terešov;Těně;Těškov;Trokavec;Týček;Újezd u Svatého Kříže;Vejvanov;Veselá;Vísky;Volduchy;Všenice;Zbiroh;Zvíkovec' as en, '' as fr, '' as hu, 'Bezděkov;Břasy;Březina;Bujesily;Bušovice;Cekov;Čilá;Dobřív;Drahoňův Újezd;Ejpovice;Hlohovice;Holoubkov;Hradiště;Hrádek;Hůrky;Cheznovice;Chlum;Chomle;Kakejcov;Kamenec;Kamenný Újezd;Kařez;Kařízek;Klabava;Kladruby;Kornatice;Lhota pod Radčem;Lhotka u Radnic;Liblín;Litohlavy;Líšná;Medový Újezd;Mešno;Mirošov (Miröschau);Mlečice;Mýto;Nevid;Němčovice;Osek;Ostrovec-Lhotka;Plískov;Podmokly;Příkosice;Přívětice;Raková;Radnice (Radnitz);Rokycany (Rokitzan);Sebečice;Sirá;Skomelno;Skořice;Smědčice;Strašice;Svojkovice;Štítov;Terešov;Těně;Těškov;Trokavec;Týček;Újezd u Svatého Kříže;Vejvanov;Veselá;Vísky;Volduchy;Všenice;Zbiroh (Sbirow);Zvíkovec' as de 


0.0244789123535 s +1 records in db. 1462181388 neobsahuje UNION.
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
1. 5. 2016   #165
-
+1
-
Zajímavé

#164 oxidián
Zápis u SQLite trvá déle. Proto vždy tvrdím, že SQLite se hodí tam, kde se velmi často čte, ale zapisuje se jen občas. Ostatně by to měl být ten tvůj případ.

Už jsem psal, že máš při zápisu více záznamů za sebou použít transakci. Bude to mnohem rychlejší.

#163 oxidián
Máš tam chybně quotování. Místo \' patří '' (dva apostrofy za sebou). Metoda quote() v PDO tohle řeší automaticky.

Opět jsi tam nedal transakci. Proto to trvá tak dlouho.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
1. 5. 2016   #166
-
0
-

Mysql to celé zvládne za 10.68s. To je sice 2x rychleji, ale o 2s pomaleji než u toho jednoduchého INSERT INTO ... VALUES ...,...,...,... .... s UNION ALL je to pomalejší.

Transakci na sqlite 2 použít nemohu.

sqlite mám nainstalované jako součást wampu, nižší verze. A vyšší verzi wampu nenainstaluji kvůli tomu problému s databází mysql, že tam mám testovací data. Možná bych mohl prostudovat jak nainstalovat vyšší verzi sqlite nezávisle na wampu.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
1. 5. 2016   #167
-
0
-

#166 oxidián
Vyexportuj si data ze starého wampu a celý wamp si přeinstaluj.

Pokud bys MySQL nepoužíval, stačila by instalace samotného PHP (takhle to mám). SQLite3 i webserver je jeho součástí. MySQL je možné instalovat samostatně a Apache při vývoji není potřebný.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
1. 5. 2016   #168
-
0
-

Jsem zvyklý na wamp protože je to bezproblémová instalace. Mě tedy konfigurace trvá 2 hodiny i u tak jednoduché věci jako je wamp.

To co popisuješ ten export by bylo nejjednodušší řešení.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
1. 5. 2016   #169
-
0
-

#168 oxidián
Pokud si data z MySQL vyexportuješ ve formátu CSV, tak PHP umí tento formát načíst.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
1. 5. 2016   #170
-
0
-

Proč ne do SQL? Nějak nechápu proč do CSV. Chci to co nejjednodušeji a ne abych zas musel vymášlet parsovač

Edit:

Teď budu dělat prohlížeč databáze sqlite, abych si mohl prohlídnout data a případně filtrovat nebo vyexportovat. To samé udělám pro mysql. Při jednom tedy budu moci udělat i import. Ale zas to zabere minimálně týden...

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
1. 5. 2016   #171
-
+1
-
Zajímavé

#170 oxidián
Protože SQL pro MySQL není kompatibilní s SQL pro SQLite. Zejména ty apostrofy, na které jsi před chvílí narazil, působí potíže.

PHP už obsahuje parsovač CSV, vymýšlet ho nemusíš.

Prohlížeč databází nemusíš vymýšlet. Stáhni si Adminer.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
1. 5. 2016   #172
-
0
-

To je fajn, žes mi to řekl. Už si prohlížím db. A je tam přes 200.000 záznamů 32MB (sqlite).

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
1. 5. 2016   #173
-
0
-

Poradíš jak napsat toto

SELECT TABLE_NAME as name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND TABLE_SCHEMA='databaze' ORDER BY TABLE_NAME;

abych dostal ve výsledném asociativním poli místo názvu sloupce TABLE_NAME sloupec/klíč name?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
1. 5. 2016   #174
-
0
-

#173 oxidián

SELECT name FROM sqlite_master WHERE type='table'
    ORDER BY name;
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
1. 5. 2016   #175
-
0
-

pro mysql ne sqlite

abych dostal ve výsledném asociativním poli místo názvu sloupce TABLE_NAME sloupec/klíč name?

něco jako TABLE_NAME as name existuje?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
1. 5. 2016   #176
-
0
-

#175 oxidián
Však to máš dobře. Mně ten tvůj SQL dotaz v MySQL jede.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
1. 5. 2016   #177
-
0
-

a jo, funguje, tak to je chyba někde jinde

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
2. 5. 2016   #178
-
0
-

Mám už napsanou metodu, která mi vypíše všechny tabulky v db. Jenom vybrat jestli chci sqlite nebo mysql. Mělo by to taky zobrazilt počet záznamů k tabulce.

http://paste.ofcode.org/VNyAruMRAspGmEFRfrDDGZ

Teď se chci jen zeptat - když vyberu checkbox a odešlu data, tak se mi v příslušném políčku $_POST['SQLW_remember_me'] neobjeví data. Element jinak existuje. string(0) ""  To je normální? Jak zkontrolovat hodnotu? Mám tam dát

$checked = empty( $_POST['SQLW_remember_me'] ) ) ? '' : ' checked';

?

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
2. 5. 2016   #179
-
0
-

:)
Jestli treba neresis ten problem, ze formulat odesila jen to, co musi? Cili, kdyz je zaskrtly checkbox, tak se odesle jeho value. Kdyz ne, neodesle se nic. To se da detekovat pres isset(). is_empy dela neco uplne jineho.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:b44e:2a...–
peter
~ Anonymní uživatel
3981 příspěvků
2. 5. 2016   #180
-
0
-

*empty() ne is_empty. Ono to bude tim, ze jsem v zivote tuhle funkci nepouzil, asi :)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:b44e:2a...–
oxidián0
Grafoman
2. 5. 2016   #181
-
0
-

Chyba v metodě. Správně má být takto:

http://paste.ofcode.org/AS4XsjZTHkSAAgQDeEEstk

empty() kontroluje zda je proměnná prázdná tedy např. (string) '' nebo array() bez prvků. Měl jsem tam

 if ( !isset($_POST[$v]) OR empty($_POST[$v] ) )
  return '';

Takže se nikdy nemohl vrátit řetězec " checked" jak jsem očekával dále po touto podmínkou.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
2. 5. 2016   #182
-
0
-

#181 oxidián
Ta funkce je stejně pofidérní. Všechna "else" jsou tam zbytečná. A zhruba od poloviny je zbytek kódu nedostupný.

Checkbox je množinový. To znamená, že proměnná existuje nebo neexistuje. Stačí tedy jednoduchý test: 

$checked = isset($_POST['SQLW_remember_me']) ? ' checked' : '';
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
2. 5. 2016   #183
-
0
-

Ta updatovaná funkce není pofiderní. Else tam má svůj význam. Dosazuje defaultní hodnotu pro options.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
2. 5. 2016   #184
-
0
-

#183 oxidián
Tak zkus všechna "else" vyhodit. Ta metoda bude fungovat úplně stejně.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
2. 5. 2016   #185
-
0
-

hlavně jsem měl chybu ve formuláři u prvku SQLW_remember_me. Já to checked omylem nastavoval jako value

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
2. 5. 2016   #186
-
0
-

#185 oxidián
Tak proč ten skript nezjednodušíš? V takové změti HTML značek a PHP proměnných se dá snadno ztratit.

K čemu máš například v elementu "form" atribut "action"?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
2. 5. 2016   #187
-
0
-

html značky s tím nemaj co dělat

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
2. 5. 2016   #188
-
0
-

#187 oxidián
Tak proč ten form máš tak komplikovaný? Co tam pohledává ta "božská metoda" checkValue()?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
2. 5. 2016   #189
-
0
-

checkValue() dosazuje defaultní hodnotu což může zahrnovat checked nebo selected.

http://paste.ofcode.org/wQmhvCKEyaMxsZBfaxqpdc

Na tu metodu createForm() se vůbec dívat nemusíš, ta funguje dobře.

Aktuální problém mám s načítáním dat ze session.

loadSessionData()

Uvnitř konstruktoru volám toto:

$this->getPostData(); // načti data z $_POST do $this->post
$this->loadSessionData(); // buď ulož data z $_POST do $_SESSION nebo naopak načti ze $_SESSION do $this->post

Pak volám

echo $instance->createForm();

Po vyplnění dat se vyplněné data uloží do $this->post a $_SESSION['remember_me'] je "on".

Když najedu na danou stránku znova, tak hodnoty zmizí, i když v $_SESSION se ty vyplněné hodnoty drží.


["SQLW_remember_me"]=> string(2) "on"

["SQLW_display_tables"]=> string(6) "FILLED"

["SQLW_start_from_name"]=> string(0) ""

["SQLW_last_table_name"]=> string(0) ""

["SQLW_rows_count"]=> string(0) ""

["SQLW_where"]=> string(0) ""
 

Ještě podotknu že sessions ve skutečnosti spouštím někde úplně jinde, protože toto je jen podmodul většího projektu.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
3. 5. 2016   #190
-
0
-

#99 Kit

Proč? Je to rychlejší? Třeba když chci jen spočítat COUNT() (počet záznamů) nebo MAX(LENGTH()) (maximální délka sloupce)

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #191
-
0
-

#190 oxidián
Je to výrazně rychlejší, protože se přenáší méně dat.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #192
-
0
-

OK. Nenapadá tě proč dotaz  "SELECT COUNT(*) as count FROM $table_name" zobrazuje o jeden záznam víc než ve skutečnosti? U prázdných tabulek mi to zobrazí 1 záznam. Např. u tabulky banlist mám velikost dat a velikost indexů 16 384 a 32 768, prázdná tabulka, ale já mám ve funkci výsledek 1

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #193
-
0
-

#192 oxidián
Zřejmě ty tabulky nejsou zcela prázdné. Nevidím důvod, proč by COUNT(*) neměl fungovat správně.

Pokud si však zobrazíš počet získaných záznamů z databáze, tak je samozřejmě jeden.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #194
-
0
-

Tak chyba je někde jinde.

$rows_count = $this->getRowsCount($table_name);
/** If requested, skip empty table **/
if ( isset($this->post['SQLW_display_tables']) AND  
         $this->post['SQLW_display_tables']=="FILLED" AND 
         !$rows_count )
     {
     $this->tables_skipped_str .= "$table_name is empty;<br>";
     continue;
     }
var_dump($rows_count);die;

string(1) "1"

První tabulka která prošla filtrem je banlist a má být prázdná a tady je
$rows_count == 1 takže asi to je předchozí hodnota nebo co
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #195
-
0
-

#194 oxidián
Vypadá to, že chybu máš v metodě $this->getRowsCount($table_name).

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #196
-
0
-

Mě to spíš připadalo že je to v tom cyklu, Tady je ta metoda:

 public function getRowsCount($table_name){
  $result = $this->sql->SQL("SELECT COUNT(*) as count FROM $table_name");
 return $result[0]['count'];
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #197
-
0
-

#196 oxidián
Co dělá metoda $this->sql->SQL()? Možná v ní bude ta chyba.

Proč nemáš proměnnou $table_name oquotovanou? Tady je to správné místo.

Jinak nejjednodušším způsobem, jak zjistit chybu v metodě, je spustit test.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #198
-
0
-

SQL pouze provede sql příkaz. SQL umí příjmout více druhů argumentů jako konfiguraci a tak. V podstatě zajišťuje kompatibilitu mezi příkazy mysql určřenými pro sqlite a naopak. Ale tady problém není. Ten výsledek jsem ti ukázal co to vrací. Výsledekem SQL je pole řádků. Když dáš dotaz na COUNT() as count tak to vrátí Array [0]['count']. Pokud hledáš SELECT * from table a nic nenajde tak je výsledek (bool) false. SQL zajišťuje vytištění případných chybových hlášek a funkce která volala SQL.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #199
-
+1
-
Zajímavé

#198 oxidián
Metoda getRowsCount() ti vrací jako výsledek 1 a přitom by měla vracet 0. Tak bys ji měl řádně otestovat, jestli za určitých okolností nevrací nesmysly.

Tohle mi funguje bezvadně: 

<?php
function getRowsCount($db, $table_name) {
    $select = $db->prepare("SELECT COUNT(*) as count FROM $table_name");
    $select->execute();
    return $select->fetch(PDO::FETCH_COLUMN);
}

$db = new PDO('sqlite:music.sqlite3');
$db->query("CREATE TABLE IF NOT EXISTS pokus(nazev text)");
echo getRowsCount($db, "pokus"), PHP_EOL;
$db->query("INSERT INTO pokus VALUES ('Adam')");
echo getRowsCount($db, "pokus"), PHP_EOL;

První echo mi vypíše 0, druhý vypíše 1. Při opětovném spuštění vypíše 1 a 2.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #200
-
0
-

No právě to bude v tom cyklu.

Co je to music?

Co je to PHP_EOL?

Tohle zdá se funguje:

$rows_count!=='0'

místo

!$rows_count

foreach ($tables as $table_name => $table):    
 $rows_count = $this->getRowsCount($table_name);
 var_dump($rows_count);
 echo (!$rows_count)."/".($rows_count!=='0')." <br>";


Vypíše:

http://paste.ofcode.org/9sseWtbnf9dvUBv635c3Xe

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #201
-
0
-

#200 oxidián
"music.sqlite3" je název souboru, ve kterém je databáze SQLite. To je pozůstatek z jiného prototypu.

Jak by to mohlo vzniknout v cyklu, když tam žádný není?

PHP_EOL je konstanta, ve které je odřádkování.

Proč máš tu nulu v apostrofech?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #202
-
0
-

Koukni se do mého předchozího příspěvku.#200 a #194 ono to je uvnitř cyklu.a je tam podmínka která se špatně vyhodnotí a za ní je continue.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
3. 5. 2016   #203
-
0
-

200, já to updatuju.

if ( isset($this->post['SQLW_display_tables']) AND  
         $this->post['SQLW_display_tables']=="FILLED" AND 
         !$rows_count )
continue


má být spíš

if ( isset($this->post['SQLW_display_tables']) AND  
         $this->post['SQLW_display_tables']=="FILLED" AND 
         $rows_count==='0' )
continue

protože výsledek je string a '0' by mělo být true. Nevím, ale prostě s !$rows_count to nefunguje
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #204
-
0
-

#203 oxidián
To nefunguje, protože '0' je v PHP false.

Proč metoda getRowsCount() vrací string? Je přece mnohem obvyklejší použít integer.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #205
-
0
-

To nevím. Požadavek je vyhodnocován takto (pro sqlite):

if ( $count_of_rows )
   while($row = sqlite_fetch_array($original_query_result, SQLITE_ASSOC))
		    $this->data[] = $row;

return $affected_rows === false ? 0 : $affected_rows;

podobně je tomu s mysql

if ( $count_of_rows ) // pokud jde o SELECT ulož data
      while($row = mysql_fetch_assoc($original_query_result))
		    $this->data[] = $row;

return $affected_rows === false ? 0 : $affected_rows;
Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
3. 5. 2016   #206
-
0
-

Tak už jsem na to přišel. Ten adminer mi nezobrazuje mysql data správně. tabulka banlist obsahuje jeden záznam, adminer neukazuje žádný. mysqladmin ukazuje jeden. Problém není v programu. Jenže pak mi nedává smysl proč se mi nevypíše ten 1 záznam, ale na to budu muset přijít sám.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #207
-
0
-

#205 oxidián
Tohle vůbec nechápu. K čemu je tam ten cyklus?

Počet řádků SQL dotazu s COUNT(*) je vždy 1 (je právě jeden řádek výsledků), ale my potřebujeme znát tu hodnotu, která je v tom výsledku - výsledek funkce COUNT(*).

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
3. 5. 2016   #208
-
0
-

Už jsem našel tu chybu - definitivně. Jen nechápu proč to tak je.

SELECT *
FROM 19_banlist
LIMIT 1 , 30


nevrátí žádný řádek.

Ale

SELECT *
FROM 19_banlist
LIMIT 0 , 30

mi vrátí jeden řádek, víc jich tam není.

Já už tu první číslici smazal. Jen ne všude a pak jsem tu chybu zkopíroval.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
3. 5. 2016   #209
-
0
-

#207 Kit
To jsem ti psal v #196

Třídu na výpis tabulek mám skoro hotovou. Je to dost bomba. Výpis vypíše buď všechny tabulky čímž získám přehled o struktuře, nebo k tomu přidá ještě pár řádků obsahu tabulky. Případně mohu kliknout a provede se výpis více řádků. Tam je dobré, že stačí snadno upravit počet. Pochopitelně bych ještě zabudoval možnost vyexportovat data z tabulky nebo zevšech. Apod. Bylo by možné vyexportovat to co jsem si vyfiltroval. Případně bych mohl porovnat dvě databáze.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
3. 5. 2016   #210
-
0
-

#208 oxidián
Co tam ten LIMIT pohledával? Tady jsi chtěl jen počet záznamů a tam se vůbec LIMIT nedává.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
3. 5. 2016   #211
-
0
-

#209 oxidián
Měl jsem na mysli ten cyklus 

while ($row = ...

který v žádném programu nepoužívám. Prostě zavolám: 

$this->data = $select->fetchAll();

a je to. Projíždět položky v cyklu po jedné je nuda.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
4. 5. 2016   #212
-
0
-

Dělal jsem dva, tři dotazy. Nejdříve jsem zjistil jaké tabulky mám v db. Potom projíždím tabulky. U každé tabulky zjistím počet záznamů. Pokud počet záznamů je 0 pak tuto tabulku přeskočím, pokud není 0, pak vypíšu pár řádků z tabulky. Proto tam je LIMIT.

Proč když odešlu formulářem hodnotu s uvozovkama (dvojitýma, "") např. count("id")<2 dostanu vyescapovaný řetězec? Toho jsem si nikdy nevšiml. Jak mám postupovat abych zpracovával původní řetězec?

Poznámky:

@TODO:  #165

Notice to PDO: Prepared statements

(however, if other portions of the query are being built up with unescaped input, SQL injection is still possible).

Edit:

Jak tak čtu o prepare statements v PDO, tak mi dochází rozdíl mezi mojí třídou Results (ve které je uložený objekt SQL) a PDO. Rozdíl je v tom že já používám třídu Results takto. $results = Results->SQL("SQL dotaz....");

if ($results)

  { while... fetch ...

   }

else die("No data found")

Tedy fakticky mi stačí jeden příkaz pro databázi a pak následuje řada různých kroků mimo třídu.

Takže co musím udělat pokud chci přejít na PDO znamená zavést pod Results->SQL metody prepare, execute, fetch, count a get (či getData, getResults).

A udělat ty 3-4 kroky pomocí třídy Results->SQL ...

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
4. 5. 2016   #213
-
0
-

Díky pánům ze Stack Overflow jsem problém s escapováním uvozovek v $_POSTu jsem vyřešil.

php.ini

magic_quotes_gpc = Off

zdroj

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
4. 5. 2016   #214
-
0
-

#213 oxidián
Magic quotes byly zrušeny v PHP 5.4 a nemá už valného významu se jimi zabývat.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
4. 5. 2016   #215
-
0
-

#212 oxidián
Dříve jsem se pokoušel v PDO umisťovat metody prepare(), execute() a fetch() resp. fetchAll() do jedné metody. Spousta vývojářů to tak dělá dodnes. Když jsem došel k závěru, že výsledkem metody prepare() je vlastně virtuální procesor, do kterého se jen ládují data, začal jsem při práci s PDO uvažovat trochu jinak.

Velmi se mi na PDO líbí, že metoda fetch() může vracet dle volby: skalár, pole, slovník, anonymní objekt nebo objekt nějaké třídy. Je to velmi praktické. Když k tomu přidám metodu fetchAll(), která vytvoří seznam ze všech nalezených záznamů výšeuvedených typů, jiné ovladače už u mne nemají šanci. Včetně faktu, že metoda bindParam(), která mne dříve prudila, se de facto stala zbytečnou.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
4. 5. 2016   #216
-
0
-

Hádám že brzo se tím začnu zabývat.

Ještě úvaha k sqlite. Napadlo mě že problém na sdíleném hostingu je, že tam jede pomalu mysql databáze. Jak to tedy udělat s tabulkou online uživatelů, do které se má ukládat kdo je přihlášený... Do sqlite by to nebylo vhodné dávat, do mysql, pomalé. Tak mě napadlo že bych to mohl ukládat do normálního souboru. Otevřít to v módu c+

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
4. 5. 2016   #217
-
0
-

#216 oxidián
Tabulka online uživatelů bude nejlepší asi v SQLite. Sami autoři SQLite uvádějí, že tato databáze má být spíše náhradou za fopen(). Je to přesně případ: Málo zápisů, časté čtení.

Zřejmě si nedovedeš představit obtíže, které by tě čekaly, kdybys takovou evidenci dělal v normálním souboru.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
4. 5. 2016   #218
-
0
-

No právě že zápis do online uživatelů je velmi častý. Při každé návštěvě by se měla provést aktualizace poslední návštěvy. Možná by se tam dalo dát omezení třeba nezapisovat návštěvy mladší 20 sekund. Kolik tam může být uživatelů online... třeba 20-40. 70 berme jako extrém. Zapisovat by se měli i nepřihlášení uživatelé, ale třeba ne tak často. Díky tomu mohu říct kolik lidí je online. 40*3 = 120 zápisů za minutu pokud by každý aspoň občas klikl. Při návštěvnosti 10 lidí online by to bylo 30 kliků za minutu. Mno a když si tam lidé zrovna budou něco ukládat tak to bude znát si myslím

Edit:

A co kdybych to rozdělil do tří databází sqlite: pro online uživatele přihlášené, nepřihlášené a třetí db by se týkala webovek? Oddělit to?

Protože tabulka online uživatelů do toho by se zapisovalo jen při přihlášení a při kliknutí na určitou stránku. Taky mě zajímá v které sekci se uživatel nachází tak to bych taky chtěl zapisovat ale to by nejspíš mělo být v jiné tabulce vlastně (v tabulce návštěv). No tak by mohla být tabulka návštěv taky zvlášť v samostatné databázi.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
4. 5. 2016   #219
-
0
-

#218 oxidián
Za nízký počet považuji do několika set zápisů za sekundu. Čtení několik desítek tisíc za sekundu. SQLite tohle běžně zvládá.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
4. 5. 2016   #220
-
0
-

A když by to překročilo několik set zápisů za minutu, tak to mám pak rozdělit? :-)

Jinak se chci zeptat, funkce htmlentities() nepřekládá mezery a zpětné uvozovky? ``

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
4. 5. 2016   #221
-
0
-

#220 oxidián
Chápeš rozdíl mezi "za minutu" a "za sekundu"?

Funkce htmlentities() se používá pouze při výstupu do HTML. S databázemi nemá nic společného a proto by se s nimi vůbec neměla používat. Není důvod k tomu, aby překládala mezery ani zpětné apostrofy, neboť tyto znaky nemají v HTML žádné problémy.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
4. 5. 2016   #222
-
0
-

#221 Kit
já to htmlentities použil na vytvoření argumentů do linku (tag a). A právě že mezery a zpětná lomítka se nepřeložily. Dělám teď stránkování v prohlížeči databázové tabulky. Tak proto. Teda zpětná lomítka už nechci používat, ale teď zrovna mi nejel dotaz tak jsem je použil.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
4. 5. 2016   #223
-
0
-
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
4. 5. 2016   #224
-
0
-

Nechápu to jak ta funkce funguje. Argument má být pole, ale na co? Nechápu.

$this->base_url = preg_replace('/\?.*$/','',$_SERVER['REQUEST_URI']);
$end = $n_pages>30?'end':false;
$max = $n_pages>29?30:$n_pages;
$anchor = '';
$where = http_build_query($this->post['SQLW_local_where']);
for ($n=$page; $n<$max; $n++):
  $title = $n;
  $anchor .= "<a href='$this->base_url?table=$table_name&page=$page&rows=".$this->post['SQLW_local_rows_count']."&where=$where'>$title</a>&nbsp;";
endfor;
$last = $rows_count_filtered - $maxcount; 
if ($end)
  $anchor .= "<a href='$this->base_url?table=$table_name&page=$last&rows=".$this->post['SQLW_local_rows_count']."&where=$where'>last</a>&nbsp;";
$s .= "<p>$anchor</p>\n";


$this->post['SQLW_local_where'] = <<<EOT "default" LIKE 'p%'

EOT;
$where = http_build_query($this->post['SQLW_local_where']);
tag a končí takto: &where=$where'>

takže když se tam vypíše ta věc, tak se do url předá jen default" LIKE
 

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
4. 5. 2016   #225
-
+1
-
Zajímavé

#224 oxidián
Z toho skriptu chápu jen to, že si děláš zbytečné bezpečnostní díry do databáze. Zkusil jsem si to podle tvého vzoru:

$table_name = "ta bul`ka";
$page = 42;
$post = array(
    'SQLW_local_rows_count' => 40,
    'SQLW_local_where' => 'brown',
);
$atributy = array(
    'table' => $table_name,
    'page' => $page,
    'rows' => $post['SQLW_local_rows_count'],
    'where' => $post['SQLW_local_where'],
);
echo http_build_query($atributy);

a výsledek je: 

table=ta+bul%60ka&page=42&rows=40&where=brown

Tohle jenom přilepíš za otazník v URL.

Nechápu smysl toho slova LIKE. To patří až do SQL dotazu - v URL nemá co pohledávat.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 5. 2016   #226
-
0
-

Díky. LIKE vyhledává řetězec jakože když hledáš Praha, Plzeň apod dáš town LIKE ... Prohlížeč tabulek není určený pro veřejnost

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 5. 2016   #227
-
0
-

#226 oxidián
V takovém případě obvykle stačí dát za otazník jako parametr town=Praha, nebo chceš-li town_like=Praha. Velmi dobře (a hlavně bezpečně) se to pak zpracovává.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:5d86:...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 5. 2016   #228
-
0
-

v tom argumentu where může být cokoliv já nevím co si tam zrovna vymyslím za podmínku

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 5. 2016   #229
-
0
-

#228 oxidián
Však vlevo od toho rovnítka může být také cokoliv. Nejlépe název sloupce, který filtruješ.

Trochu jsem rozšířil předchozí příklad: 

<?php
$table_name = "ta bul`ka";
$page = 42;
$post = array(
    'SQLW_local_rows_count' => 40,
    'SQLW_local_where' => array(
        'town' => 'Praha',
        'color' => 'brown',
    ),
);
$atributy = array(
    'table' => $table_name,
    'page' => $page,
    'rows' => $post['SQLW_local_rows_count'],
    'where' => $post['SQLW_local_where'],
);
echo http_build_query($atributy);

a výsledek? 

table=ta+bul%60ka&page=42&rows=40&where%5Btown%5D=Praha&where%5Bcolor%5D=brown

No prostě nádhera, která je hezky strukturovaná a dá se velmi snadno zpracovat.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:5d86:...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 5. 2016   #230
-
0
-

To bych měl podle tebe explodovat where? To je komplikované. Nechápu proč to dělat tak složitě. Zbytečné. Navíc já používám smyčku na výpis stránek mám tam tedy například 30 odkazů. To mám podle tebe pokaždé opakovat
http_build_query($atributy); ve smyčce? Proč to neaplikovat pouze na atribut where?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 5. 2016   #231
-
0
-

#230 oxidián
Protože si tím zjednodušíš aplikaci a usnadníš údržbu.

Data se předávají v atomizované nebo strukturované podobě. Parsování složených hodnot obvykle bývá nevýhodné.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 5. 2016   #232
-
0
-

Jak říkám je to moc složité a zbytečně. Tohle je věc na jeden jednoduchý argument.

Mám to takto:

$where = array(
        'where' => $this->post['SQLW_local_where'],
    );
$where = http_build_query($where);
$links = '';    
for ($n=1; $n<$page; $n++):
     $anchor = $this->base_url."?table=$table_name&page=$n&rows=".$this->post['SQLW_local_rows_count']."&$where";
     $links .= "<a href='$anchor'>$n</a>&nbsp;";
endfor;
$links .= "<span>$n&nbsp;</span>";
for ($n=$page+1; $n<$max; $n++):
     $anchor = $this->base_url."?table=$table_name&page=$n&rows=".$this->post['SQLW_local_rows_count']."&$where";
     $links .= "<a href='$anchor'>$n</a>&nbsp;";
endfor;    
$last = $rows_count_filtered - $maxcount; 
$anchor = $this->base_url."?table=$table_name&page=$last&rows=".$this->post['SQLW_local_rows_count']."&$where";
if ($end)
     $links .= "<a href='$anchor'>last</a>&nbsp;";
$s .= "<p>Pages:</p><p>$links</p>\n";

Mně to příjde dost jednoduché. Není to kód který by se měl dále vyvíjet. Je to prakticky hotové a dál není třeba se v tom vrtat. Teď přemýšlím nad exportem.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
5. 5. 2016   #233
-
0
-

#232 oxidián
Ještě by sis to celé mohl poskládat v Javascriptu u klienta a poslat to do PHP jako jeden SQL dotaz.

To uvádím jako opačný pól k mému řešení v PHP.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
peter
~ Anonymní uživatel
3981 příspěvků
5. 5. 2016   #234
-
0
-

Jenomze, jak bys pak kontrolovat data? Ledaze by slo o vnitrni aplikaci, do ktere se nikdo nebude pokouset nabourat a nezada ti tam ani omylem spatny dotaz. Pak by to bylo idealni, ziskat dotaz uz z js. PHP cas by pak pak mohla byt jednoduchy vypis.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:74d3:c9...–
peter
~ Anonymní uživatel
3981 příspěvků
5. 5. 2016   #235
-
0
-

A propo, tohle bych taky nepovazoval za bezpecne. Adresa do url se koduje pres urlencode(). A do html do pres htmlspecialchars().
"?table=$table_name&page=$last&rows=".$this->post['SQLW_local_rows_count']."&$where"
 

Nahlásit jako SPAM
IP: 2001:718:2601:26c:74d3:c9...–
Kit+15
Guru
5. 5. 2016   #236
-
0
-

#234 peter
Takhle je to právě myšleno. Pro veřejnou aplikaci by se to vůbec nehodilo, ale pro vlastní správu databáze by se javascriptové řešení použít dalo.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
5. 5. 2016   #237
-
0
-

#234 peter
Nepotřebuju kontrolovat data, je to jen pro potřebu správce.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
7. 5. 2016   #238
-
0
-

nevíte jak to udělat když bych chtěl aby po kliknutí na číslo stránky se skočilo na kotvu?

Běžně se to dělá takto:

<a href="#anchor">Link Text</a>

Ale já mám místo href url s argumentama. Takže po kliknutí se mi zpracuje dotaz a zobrazí se stránka s daným číselem. Připadá mi totiž praktické, že po kliknutí na číslo stránky by se měla zaměřit kotva.

Pro bližší představu mám to takto:

$this->base_url = preg_replace('/\?.*$/','',$_SERVER['REQUEST_URI']);
$table_name = $this->local_table_name;
$url = $this->base_url."?table=$table_name&rows=".$this->post['SQLW_local_rows_count']."&where=".$this->where_encoded;
$links = $this->pagination->create($limit, $maxcount, $this->total_rows_filtered, $page, $url);
// Print pages
$s .= "<p>Pages:</p>\n<div id=pagination><a name=pagination></a>\n$links\n</div>\n";

Je mi jasné že kotva standardě nepůjde, možná bych měl přidat javascipt aby po načtení stránky se přešlo na kotvu "pagination" pokud url obsahuje argument &paginate=1?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
7. 5. 2016   #239
-
+1
-
Zajímavé

#238 oxidián
Tu kotvu prostě přilep za URL.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
7. 5. 2016   #240
-
0
-

supr, dík

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
10. 5. 2016   #241
-
0
-

Tvořím podmínku pro vyhledávací filtr (hledání tabulek). Formulář obsahuje dva prvky - na co formulář začíná a na co formulář končí. Mám dvě proměnné indikující stav.

Když je $start false a $end false znamená to že má vypsat všechny tabulky protože vyhledávací pole jsou prázdné.

Když je $start true budu hledat začátek slova (jestli tabulka začíná na hledaný řetězec), Nedokončená podmínka by zněla asi takto: pokud nenajdeš řetězec ($start zůstává true) nedělej nic ale pokud najdeš řetězec, $start nastavím na null, takže od té doby co $start je null začínám mazat elementy z pole výledků. Je tu ale ještě ta druhá poměnná $end která taky ovlivňuje podmínku...

Když $end je true budu hledat konec slova ale nebudu ho mazat. Když nastavím null, začínám mazat elementy (výsledek podmínky je true).

Celkově tedy lze říct, že k vymazávání má docházet pokud start je true NEBO end je null.

Ale. Pokud $start je false a $end je true pak nechci nic mazat. To znamená že k mazání ma začít až když najdu tabulku která začíná na dané slovo...

První podmínka kterou jsem zkusil sestavit a byla nefunkční ve smyslu že nefunguje ta úplně posleední podmínka (čti tučně napsanou větu).

   if (
 !( 
      ($start===false OR $start===null)
     ) // vnitřní podmínka říká kdy nechci mazat
     OR
     !( $end===false OR $end!==null)
         )

Druhá podmínka kterou jsem zkusil je s rozšířením první podmínky:

     if ( 
   /** Celkově k vymazávání má docházet
   pokud start je true NEBO end je null **/
    !( ( $end===true AND $end!==null)
      AND
      ($start===false OR $start===null)
     ) // vnitřní podmínka říká kdy nechci mazat
     OR
     !( $end===false OR $end!==null)
         )

Ale to mi taky nefunguje (všechny tabulky se vymažou).

Tak zkouším napsat sem a snad mi s tou podmínkou poradíte. Jde mi jen o tu podmínku.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
10. 5. 2016   #242
-
0
-

#241 oxidián
Zkus se v PHP zbavit proměnných typu boolean. Hodně ti to usnadní život.

Operátory AND a OR fungují trochu jinak, než si představuješ. Používej místo nich operátory "&&" a "||".

Místo těch komplikovaných podmínek by ti mělo stačit: 

if ($start) {
    ...
}

// přes funkci strlen() se to bude chovat jinak
// "0" bude true, ale "" bude false.

if (strlen($start)) {
    ...
}
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
10. 5. 2016   #243
-
0
-
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
10. 5. 2016   #244
-
0
-

#243 oxidián
Podrobně je to popsáno tady: PHP: Logical Operators

Edit: Zkus si ještě tohle: 

echo true && false ? "foo" : "bar", PHP_EOL;
echo true and false ? "foo" : "bar", PHP_EOL;
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
10. 5. 2016   #245
-
0
-

Tady ale neprovádím matematické operace takže by to nemělo mít vliv.

Používám AND / OR protože jsou lépe vidět (mám je zvýrazněné barevně, && || nejsou barevně.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
10. 5. 2016   #246
-
0
-

#245 oxidián
Asi záleží na použitém editoru, protože mám barevně obojí.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
11. 5. 2016   #247
-
0
-

#244 Kit
To nemusím zkoušet používám to běžně a používám tam závorky.

Upravil jsem to takto a stále to nefunguje:

     if ( 
   /** Celkově k vymazávání má docházet
   pokud start je true NEBO end je null **/
     ( ( $end===true )
      &&
      !( $start===null) // nemazat
     ) // vnitřní podmínka říká kdy nechci mazat
     ||
     ( ( $end===true )
      &&
      ( $start===true ) // mazat
     )
     ||
     ( $end===null) // mazat
         )
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
11. 5. 2016   #248
-
0
-

#247 oxidián
K čemu tam jsou dobré ty konstanty null a true?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
11. 5. 2016   #249
-
0
-

Tak jsem našel tu chybu. Celou dobu jsem pracoval s nesprávně nastavenýma vstupními proměnnýma. $start a $end jsem nenastavil podle funkce !empty ale podle isset a to byla chyba. Vstup byl nastaven vždy proto bylo $start nebo $end vždy true.

Toto jede:

     ( ( $end===null )
      &&
      ( $start===false) // mazat
     )
     ||
     ( ( $end===true )
      &&
      ( $start===true ) // mazat
     )
     ||
     ( ( $end===NULL )
      &&
      ( $start===NULL ) // mazat
     ) { ... smaž element ... }

Kompletně:

     ( ( $end===null )
      AND
      ( $start===false) // mazat
     )
     OR
     ( ( $end===true )
      AND
      ( $start===true ) // mazat
     )
     OR
     ( ( $end===NULL )
      AND
      ( $start===NULL ) // mazat
     )
     OR
     ( ( $end===false )
      AND
      ( $start===NULL ) // mazat
     )

Pomohlo mi že jsem si vypsal typ těch proměných v každém cyklu.

Respektive takto to má být správně:

     ( ( $end===null )
      AND
      ( $start===false) // mazat
     ) 
     OR
     ( ( $end===true )
      AND
      ( $start===true ) // mazat
     )
     OR
     ( ( $end===NULL )
      AND
      ( $start===NULL ) // mazat
     )
     OR
     !( ( $end===false )
      AND
      ( $start===NULL ) // nemazat
      )
     )

Takže stačilo do formuláře zadat hodnotu kam jsem chtěl a pak si přečíst ten výpis. Najít si tu položku v poli ve výpisu podle které jsem se orientoval a jen opsat stav té proměnné. (bool) false (start) , (bool) NULL (end) apod. Takže nakonec se správnou metodikou to jde snadno.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
11. 5. 2016   #250
-
0
-

Tak konečně se dostávám k tomu exportu. Tak dám příklad tabulky mysql (export v admineru):

CREATE TABLE `messages` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `fromid` int(10) unsigned NOT NULL default '0',
  `toid` int(10) unsigned NOT NULL default '0',
  `subject` varchar(100) NOT NULL default '',
  `message` text NOT NULL,
  `badwords` text NOT NULL,
  `badrate` smallint(5) unsigned NOT NULL default '0',
  `badscore` smallint(5) unsigned NOT NULL default '0',
  `sendtime` datetime NOT NULL default '0000-00-00 00:00:00',
  `ip` int(10) unsigned NOT NULL default '0',
  `status` tinyint(1) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `ids` (`toid`,`fromid`)
)  ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='0notRead;1read;2deletedBySender;3deletedByRecieverNotRead;4x';

Jak vidíš, tak mi tam dal ty zpětné uvozovky `` ke sloupcům. Můj dotaz je ale na to, jak pomocí Mysql a SQlite zjistit Klíče, Engine, Charset (mysql) a Comment, abych mohl vytvořit SQL dotaz.

Dále k tomu CSV.

Čím mám nahradit čárky "," a zalomení řádků?

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
11. 5. 2016   #251
-
0
-

Jestli jsem to pochopil ze zkušebního příszpěvku který jsem vyexportoval tak, čárky se neescapují, ale dvojité uvozovky se vyescapovat musí:

id,myid,date,user,reason
1,9,2014-01-30,17,"zalomeni radku:
dvojita uvozovka:""
jednoducha uvozovka:'
carka:,"

Tučně jsou zvýrazněny uvozovky, které přibyly

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
11. 5. 2016   #252
-
+1
-
Zajímavé

A co jako chces escapovat vlastni silou? Php ma primo funkce pro prevod na csv. Nebo si snad pises vlastni kod? Pak doporucuji google a prostuduj si, jak se spravne escapuje csv.

http://php.net/manual/en/function.fgetcsv.php - read from file
http://php.net/…r-getcsv.php - read from string
http://php.net/….fputcsv.php - write to file
Co tam tedy neni, je zapis do csv stringu

Ty pravidla jsou, ze
- string se escapuje uvozovkami, kdyz je v nem uvozovka " nebo oddelovac (sloupcu "," nebo radku "\n")
- uvozovka v textu se escapuje zdvojenim
- escapovat uvozovkami text je mozne vzdy, jen je to neusporne
- je dobre do csv pridavat jmena sloupcu jako prvni radek
Excelovy csv ma jako oddelovat sloupcu strednik ";". A pokud nepridas BOM utf znaky na zacatek souboru, tak kodovani v souboru chape jako win1250 a neda si to vymluvit :)
Pri kopirovani z escelu do txt se pouzije jako oddelovac sloupcu tabelator "\t".

"aaa";"bbb";"ccc\n...""...";12345\n

Nahlásit jako SPAM
IP: 2001:718:2601:26c:d995:19...–
Kit+15
Guru
11. 5. 2016   #253
-
0
-

#250 oxidián
Jak vidím, tak tam Adminer nepřidal zpětné uvozovky, ale zpětné apostrofy. Je to standardní chování. Při ručním psaní SQL dotazů je zpravidla nepíši ze dvou důvodů: Lenost a přehlednost. Prostě se mi to blbě píše i blbě čte.

Nemusíš to exportovat do CSV a zase importovat. Můžeš si v PHP otevřít obě databáze zároveň a přesypávat data z jedné do druhé. Vyhneš se tím veškerému escapování.

Jak už psal peter, PHP má potřebné funkce pro práci s CSV. Nedoporučuji psát vlastní řešení.

Co ten COMMENT na konci? To má být součástí definice sloupce `status`, nikoli jako komentář.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
11. 5. 2016   #254
-
0
-

A jak to adminer dělá že ukládá hotový soubor do složky kam ukládá Prohlížeč? Jak zjistil cestu?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
11. 5. 2016   #255
-
0
-

#254 oxidián
Nevím, nepoužívám ho. Zkus nakouknout do zdrojáku. Bude to asi někde na začátku mezi definicemi konstant.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
11. 5. 2016   #256
-
0
-

oprava: je to složka do které ukládá prohlížeč stažené soubory, ne dokumenty. Tak to bude stačit uložit jako normální dočasný soubor a zpřístupnit linkem. Toď vše.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
12. 5. 2016   #257
-
0
-

Co dělám špatně, že vždy dostanu výsledek 1?

Vstupní hodnoty:


$export - 0 nebo 1
$import - 0 nebo 2


$action nikdy není 3 protože nikdy není současně $export = 1 a $import = 2

Přestože výsledek $action je 0, výsledek $r je true místo false. Proč?
 

$action = $export | $import;
$r = ( $action | $action_type ) ? true : false;
echo "$action = $export | $import<br>$r = ( $action | $action_type ) ? true : false;";


$action_type je přednastaven na 3

0 = 0 | 0

1 = ( 0 | 3 ) ? true : false;

Podle mě podmínka testuje jestli v 0 jsou obsaženy jedničky na dvou pozicích zprava a protože tam není ani jedna měl by být výsledek false.  očekávám že 1 | 3 dá true, 2 | 3 dá true a 0 | 3 dá false

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
12. 5. 2016   #258
-
0
-

#257 oxidián
Mně to sice funguje perfektně, ale stále nechápu, oč se pokoušíš.

Ty konstanty false a true to jen komplikují. Nešlo byto bez nich?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
12. 5. 2016   #259
-
0
-

Ale nefunguje to. Když je $action 0 tak výsledek musí být false:

  $action = $export | $import;
  $r = ( $action | $action_type ) ? true : false;
  var_dump($action);
  var_dump($r);

int(0)

bool(true)

Co musím udělat aby 0|3 dalo 0?

0 nemá nastavený ani jeden bit, tak proč je výsledek true?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
12. 5. 2016   #260
-
0
-

#259 oxidián
Vždycky přece bude platit, že 

0 | 3 == 3
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
12. 5. 2016   #261
-
0
-

Jak mám tedy binárně porovnat ty dvě proměnné? Proměnná A může být binárně 01 nebo 10. Proměnná B je binárně 11. Jak zjistit, jesli bit 01 je nastaven v 11 nebo bit 10 je nastaven v 11? Přitom mám jen tyto dvě proměnné A, B

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
12. 5. 2016   #262
-
0
-

#261 oxidián
Tak si to zamaskuj. Použij operátor "&".

Nebyl by obyčejný switch jednodušší a praktičtější?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
12. 5. 2016   #263
-
0
-

Kurňa já myslel že 01 & 11 bude false protože nejsou všechny bity 1. Takže už jsem doma.

Výsledkem 01 & 11 by mělo být 01 a

výsledkem 10 & 11 by mělo být 10 a

výsledkem 11 & 11 by mělo být 11

výsledkem 100 & 11 by mělo být 0 ve dvou posledních bitech není ani jeden nastavený bit

Nahlásit jako SPAM
IP: 78.45.87.–
peter
~ Anonymní uživatel
3981 příspěvků
12. 5. 2016   #264
-
0
-

Jestli by treba nebylo dobre priste zalozit dalsi tema? U je tu pres 250 prispevku a 99% uplne mimo :) Hlavne teda kvuli dobe nacitani.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:65ce:ce...–
oxidián0
Grafoman
12. 5. 2016   #265
-
0
-

Abych ukázal co jsem vytvořil:

http://paste.ofcode.org/Y86zvUPzVdPjU72Jk9D5Li

Třídu používám takto:

http://paste.ofcode.org/mBLMiPtekD6CQZUkdQ78Q3

Je to prohlížeč databáze, který bude umožňovat export a import tabulek. Výhoda oproti admineru a

Připojen obrázek.

phpmyadminu je v tom, že jednoduše většina věcí je předkonfigurovaných nebo se dělá automaticky.

Obsahuje rozsahový filtr díky kterému můžu vyhledat tabulky podle jména. Jednotlivé tabulky lze vybrat na tomto principu spíš než klikáním na checkboxy v admineru.

Myslím že se blížím ke konci takže do tohoto vlákna už dlouho psát nebudu.

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
12. 5. 2016   #266
-
0
-
Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
12. 5. 2016   #267
-
0
-

Já už to ale zjednodušil:

   $export = $import = 0;
   if ( isset($this->post['SQLW_action_export_db']) )
      $export = Sqlite_view_actions::EXPORT;
   if ( isset($this->post['SQLW_action_import_db']) )
      $import = Sqlite_view_actions::IMPORT;

Vidím ale že to mohu ještě zjednodušit. Jde tam o to, že já už to mám uložené ve členu post na což jsem tenkrát zapomněl.

Jinak teď řeším jak získat klíče pro Mysql a Sqlite. Jsou tam dvě klauzule PRIMARY KEY a KEY.

U KEY mysql hádám, u sqlite to nemám napsané protože nevím v jakém sloupci to je. Snad "k"?

  if ( $this->post['SQLW_export_syntax'] == "Mysql")
    {
    $sql_primary_key =  
    "SELECT k.COLUMN_NAME FROM information_schema.table_constraints t LEFT JOIN information_schema.key_column_usage k USING(constraint_name,table_schema,table_name) WHERE t.constraint_type='PRIMARY KEY' AND t.table_schema=DATABASE() AND t.table_name='myTable';";
    $sql_key =  
    "SELECT k.COLUMN_NAME FROM information_schema.table_constraints t LEFT JOIN information_schema.key_column_usage k USING(constraint_name,table_schema,table_name) WHERE t.constraint_type='KEY' AND t.table_schema=DATABASE() AND t.table_name='myTable';";
    }
  else
    {
    $sql_primary_key = "PRAGMA table_info(myTable)";
    }
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
12. 5. 2016   #268
-
0
-

#267 oxidián
Všimni si, že 2× nastavuješ proměnnou $export a 2× $import, což je mírně neefektivní. V některých programovacích jazycích to ani nejde.

Kdo má po tobě číst ty nudle? Neumíš zalamovat řádky?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
12. 5. 2016   #269
-
0
-

Vím o tom, ale teď to neřeším. Řeším teď SQL dotazy. To jsem jen zkopíroval z netu já to nepsal.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
13. 5. 2016   #270
-
0
-

Stále nemohu přijít jak získat ty klíče tabulky. Primární klíč Mysql už mám, KEY ne. Nakonci tabulky CREATE dotazu  `messages` mám

  PRIMARY KEY  (`id`),
  KEY `ids` (`toid`,`fromid`)

Našel jsem. INDEX == KEY

http://stackoverflow.com/questions/5213339/how-to-see-indexes-for-a-database-or-table

Ale není mi jasné kde mám zjistit název schématu pro moji databázi.

SELECT DISTINCT
    TABLE_NAME,
    INDEX_NAME
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'your_schema';
Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
14. 5. 2016   #271
-
0
-

Je nějaký rozdíl mezi syntaxí SQL a SQLITE? Teď řeším to, že když mám ve vstupních datech z Mysql db typ Mysql, a chci pro Sqlite připravit dotaz na vytvoření tabulky, tak jestli mám použít syntaxy SQL nebo Sqlite (tedy jak správně pojmenovat políčko ve formuláři) - abych v tom měl jasno.

Na samotné přejmenování dotazu CREATE z Mysql do sqlite používám toto:

$query = preg_replace ( array(
    '/(?<=\W)INT(?=\W)/i',
    '/AUTO_INCREMENT/i',

    '/TINYINT/i',
    '/SMALLINT/i',            
    '/VARCHAR/i',

    '/PRIMARY KEY/i',
    '/CHARACTER SET utf8/i',
    '/PRIMARY KEY/i'
  ),
  array(
    'INTEGER',
    'AUTOINCREMENT',

    'INTEGER',
    'INTEGER',
    'TEXT',

    '',
    '',
    ''
  ),          
  $query);
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
14. 5. 2016   #272
-
0
-

#271 oxidián
Jsou mezi nimi rozdíly, občas i velké. Například SQLite nepřipouští v jednom INSERTu vkládání více záznamů jedním příkazem. V MySQL zase nemá moc velký význam dávat nesouvisející DB operace do jedné transakce.

Je dobré s těmi databázemi zacházet podle jejich vlastních pravidel. To je také pro me jedním z důvodů, proč SQL dotazy dávám až do servisní vrstvy aplikace, navíc rozdělené do domén. Mohu tak mít potřebné SQL dotazy pro různé databáze hezky pod sebou a nemusím dělat složité konverze, které mohou být zdrojem chyb.

Místo preg_replace() bych raději vyrobil 2 metody pro každý typ dotazu, které budou syntetizovat SQL dotaz podle dodaných parametrů. Například 

$data = array(
    'jmeno' => 'Adam',
    'boty' => 42,
);
$result = $mysql->insert('osoba', $data);

// vyrobí SQL dotaz
//     INSERT INTO `osoba` (`jmeno`, `boty`) VALUES (?, ?);
// a provede jej:

$insert = $pdo->prepare($sql);
$insert->execute(array_values($data));
return $insert->rowCount();

Metoda pro SQLite však ten SQL dotaz vyrobí jinak: 

INSERT INTO "osoba" ("jmeno", "boty") VALUES (?, ?);

a také ho provede.

Tyto dvě metody budou ve dvou různých třídách: jedna pro MySQL, druhá pro SQLite. V konstruktoru jim injektuješ databázi (nebo jen přístupové údaje) a vyrobíš tím databázový objekt, který si už bude pamatovat, s jakou databází pracuje a podle toho bude ty SQL dotazy generovat a provádět.

Nahlásit jako SPAM
IP: 2a00:1028:83a0:37a6:b596:...–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
14. 5. 2016   #273
-
0
-

Vždyť jsem do SQLite vkládal vícero záznamů pomocí SELECT UNION ALL.

Já to dělám jinak. Mám nejdříve třídu

Db_class která obsahuje typy a metody. Určuje s jakou databází momentálně pracuju, jaká je defaultní databáze, jaká je databáze kterou používám právě teď v rámci konkrétní třídy. Tady jsou metody na převod mezi sqlite a mysql. Dle mého názoru je to jednoduché a přehledné

http://paste.ofcode.org/57FxYsDpQYpuTGvGfxb7MA

Poté co se vytvoří tato instance, mohu vytvořit instanci SQL_query_class, Mysql_class a Sqlite_class. SQL_query_class už přebírá konigurák, který může změnit přednastavené chování.

Samotná záměna ve stringu zabere jen nepatrný zlomek času, který ani nemá cenu počítat. Taky tabulky nevytváříme každý den, že?

Abych ujasnil proč to dělám tak jak to dělám. Jedu v režimu MYSQL, načtu data z tabulky mysql (konkrétně jde o typy sloupců), dle formuláře chci výstupní formát Sqlite, takže se spustí funkce:

if ($this->post['SQLW_export_syntax']=='Sqlite' )
    $this->db->mysql2sqlite($sql_table, $config);

a ta mi pro ten dotaz CREATE upraví typy z mysql na sqlite.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
14. 5. 2016   #274
-
0
-

1. Jak v SQLite v dotazu CREATE vytvořit primární klíč?

.. PRIMARY KEY ("id"), KEY ("ids") )  nefunguje


2. Tady to píše chyba poblíž "("

CREATE table "msg" ( "myid" INTEGER,

"user" INTEGER,  

"new_mes" INTEGER,

"total_mes" MEDIUMINT,

"lastdate" DATETIME , KEY ("ids") )

3. Typ MEDIUMINT asi v Sqlite neexistuje že?

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
14. 5. 2016   #275
-
0
-

#274 oxidián
Však jsem ti to psal o kus výš: 

id INTEGER PRIMARY KEY

Všechny tři způsoby máš i na stránce, na kterou tě zavede Google: SQLite Create Table

Pokud potřebuješ autoincrement, tak ten je kousek vedle: SQLite Autoincrement

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
15. 5. 2016   #276
-
0
-

Nakonec jsem to vyřešil takto:

http://paste.ofcode.org/aNP4GztxXWEZ8wK8d8eimp

Slouží to k převodu mysql dotazu CREATE (TABLE) na sqlite syntaxy.

Musel jsem nejdříve dohledat klíče a primární klíče, pak nahradit typy, a nakonec ještě jednou nahradit kotvy `!` za příslušný typ klíče.

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
16. 5. 2016   #277
-
0
-

Nevíš proč mi adminer hlásí že tabulka neexistuje?
 

INSERT INTO "19_banlist" SELECT '1' as id, '9' as myid, '2014-01-30' as date, '17' as user, '""' as reason

Přitom je založená:

Tabulka: 19_banlist

Sloupec Typ
id integer NULL
myid integer NULL
date date NULL
user integer NULL
reason tinytext NULL

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
16. 5. 2016   #278
-
0
-

#277 oxidián
Už jsi někde viděl identifikátor proměnné, který začíná číslicí? Zkus vyhodit to "19_".

Proč máš čísla v apostrofech? Má to být integer.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
16. 5. 2016   #279
-
0
-

Jestli to spíš nebude tím že ta tabulka byla vytvořena s mezerou v názvu
CREATE table "19_banlist " ...

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
16. 5. 2016   #280
-
0
-

#279 oxidián
Proč dáváš číslice a mezery do názvu tabulky?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
16. 5. 2016   #281
-
0
-

Ta mezera tam být neměla. Bylo to způsobeno konverzí řetězce

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+15
Guru
16. 5. 2016   #282
-
0
-

#281 oxidián
A ty číslice na začátku?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
oxidián0
Grafoman
17. 5. 2016   #283
-
0
-

Je to jen tabulka z nějaké databáze, není to jedno?

Dotaz na mkdir. Spustil jsem to že vytvořím adresář "/data/sql_export/sqlite",

if ( !file_exists($this->config['folder']))
if ( mkdir($this->config['folder'], 0777, true) )
      echo "<br><b>Success. $this->config['folder']</b>";

Adresář se vytvořil ale nemohu ho najít. Prostě kořenový adresář by měl být tam kde spouštím stránku, ale pod adr. data se nic nevytvořilo a není to ani ve složce kde běží localhost... Nechápu kde to je

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Grafoman
20. 5. 2016   #284
-
0
-

Jak by si nahradil tento Mysql příkaz syntaxí pro Sqlite?

CREATE table "19_new_photos" (
"uid" INTEGER   ,
"photonum" SET('0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63')  
)

Něco podobného mám taky v nastavení jazyků a zájmů:

"lang" SET('0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63')  ,
"interests" SET('0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32',...
Nahlásit jako SPAM
IP: 78.45.87.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 6 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý