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
Reklama
Reklama

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

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
oxidián0
Věrný člen
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.–
Reklama
Reklama
Kit+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
2528 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
Věrný člen
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+42
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+11
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
Věrný člen
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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+11
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
Věrný člen
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
Věrný člen
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
2528 příspěvků
7. 4. 2016   #24
-
0
-
Nahlásit jako SPAM
IP: 2001:718:2601:26c:8525:bf...–
peter
~ Anonymní uživatel
2528 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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
7. 4. 2016   #30
-
0
-
Nahlásit jako SPAM
IP: 78.45.87.–
Kit+11
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
7. 4. 2016   #35
-
0
-

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

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
2528 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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
2528 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
Věrný člen
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+11
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
Věrný člen
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
2528 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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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+11
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
19. 4. 2016   #67
-
0
-

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

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
2528 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
Věrný člen
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+11
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+11
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
Věrný člen
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
20. 4. 2016   #83
-
0
-

ok, dík za vše

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
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
Věrný člen
25. 4. 2016   #85
-
0
-

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

Nahlásit jako SPAM
IP: 78.45.87.–
oxidián0
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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+11
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+11
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
Věrný člen
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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
Věrný člen
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
2528 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
Věrný člen
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
Věrný člen
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+11
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+11
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+11
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+11
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
30. 4. 2016   #151
-
0
-

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

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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
Věrný člen
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
2528 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
2528 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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
2. 5. 2016   #187
-
0
-

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

Nahlásit jako SPAM
IP: 78.45.87.–
Kit+11
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
Věrný člen
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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
Věrný člen
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+11
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?