« 1 2
Autor Zpráva
Medvídek
Profil
Jcas:
No ta funkce ti vrací obrácenou logiku, takže při prvním letmým prohlédnutí kódu je to takové zmatené. Ty ve funcki vracíš true, pokud je výsledek kontroly false. Pokud bychom vynechaly tu tvojí funkci, tak se musíš zeptat správně takto:

if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {$hláska='spatne vyplnen email'}
Jcas
Profil *
Medvídek
Jsme psali zároveň. Takže:
filter_var($hodnota, FILTER_VALIDATE_EMAIL) //vyhovuje hodnota emailu - vrátí true
if(!Email($_POST['email'])) //podmínka splněna, pokud se vrátí false
juriad
Profil
Jcas:
Pojmenovávej funkce slovesy, tak aby její činnost byla zřejmá; porovnej názvy funkcí:
- isEmailValid
- isEmail
- checkEmail
- validateEmail
- email

Od všech bys asi čekal, že vrátí true, pokud to co zadáš je email a false v opačném případě. Ale je to jediný možný očekávaný výsledek?
U prvních dvou čekáš odpověď true/false.
U dalších dvou čekáš, že se stane něco nepříjemného (vrátí false, vyhodí výjimku, vypíše hlášku, ukončí skript), pokud nezadáš e-mail.
U poslední musíš fakt hádat. Co když z neplatného e-mailu udělá platný, nebo k uživatelskému jménu doplní @doména.cz

Obdobná konvence platí pro proměnné, ty by zase měly být pojmenovávány podstatnými jmény.
Tori
Profil
Jcas:
Nedávno jsem narazil na zajímavou věc, i když to asi není správně. Volám fc dřív, než jsem ji vytvořil. Zajímavé, že to v php prošlo.
Projde to pouze v případě, že ji voláte ve stejném skriptu, v němž je později definované. Jednotlivé skripty se totiž (AFAIK) nejdřív parsují a potom provádějí, a includované soubory se zpracovávají (a parsují) až v době, kdy hlavní skript už běží. V následujícím příkladu selže volání skript.php s hláškou "nedefinovaná fce":

// fce.php
<?php
function foo() { echo '<br>volana funkce'; }

// skript.php
<?php 
foo();
require './fce.php';
(Může to způsobovat zajímavé problémy při includování definic tříd a jejich potomků, viz tady.)
Jan Tvrdík
Profil
Tori:
Projde to pouze v případě, že ji voláte ve stejném skriptu, v němž je později definované.
Ani to není obecně pravda. Projde to prostě tehdy, když v době volání je funkce již definovaná =) Je pravda, že u PHP skriptů rozlišujeme compile a runtime fázi. Definice funkcí a tříd obvykle probíhá probíhá v compile fázi, nicméně PHP je jazyk dynamický, takže je možné vynutit, aby i definice funkce proběhla až v runtime fázi, tedy např následující kód neprojde:
<?php
foo();
if (true) {
    function foo() {
        // funkce foo bude definovaná až v runtime fázi
    }
}
Joker
Profil
Jan Tvrdík [#5]:
Právě to je mimochodem důvod slova „obvykle“ v mém vyjádření „zatímco v PHP obvykle jde volat funkci před její deklarací“ na minulé stránce.
(Toto je ten případ „neobvykle“, kdy to nejde.)
Amunak …a tohle zase je právě ten důvod, proč jsem celou problematiku shrnul jen slovem „obvykle“ :-)
Amunak
Profil
Tori, Jan Tvrdík, Jcas:
Já bych do toho moc nevrtal. Nemá cenu učit začátečníky kdy něco takového funguje, když by se to stejně nemělo používat, protože je to „bad practice“. Raději bych jim řekl, že funkce musí být vždy definovaná před tím, než se zavolá, a jinak že nebude fungovat. Tuhle obskurnost bych raději úplně zatajil. Protože to tak stejně ve většině případů (a v každém normálním jazyce) bude. A akorát se tím někomu zamozá hlava (podobně jako s tím, že foreach dělá kopii pole, nebo co). Začátečník ultimátně nepotřebuje vědět, jak to uvnitř pracuje, když bude vědět, jak to použít.
Jcas
Profil *
Já to vzdávám. Právě jsem strávil 6 hod hledáním článku !!!Českého!!!, jak to je s těmi uvozovkami, apostrofy při komunikaci s Mysql. Občas se mi odařilo něco chytnout v nějaké diskusy, ale jinak nic moc.
Hlavně, když 90% článků k Mysql (asi se jedná o komunikaci přímo v DB a ne pomocí php) je naprosto bez uvozovek, apostrofů a čehokoliv - pouze slova.
Takže co jsem pochytil.
// 1. SQL dotaz je v uvozovkách "...."
"SELECT * FROM `tabulka`"
// 2. Porovnáváme číslo - datový typ (dále budu psát DT) je int
"SELECT * FROM `tabulka` WHERE `id` = 3"
// 3. Jméno tabulky a jméno sloupce možno dávat s `...`, nebo bez
// 4. Porovnáváme text - DT varchar, text atd.
"SELECT * FROM `tabulka` WHERE `text` = 'blabla'" //3 čárky jsou jedna jednoduchá uvozovka a jedna dvojitá
// nebo možná i takto
"SELECT * FROM `tabulka` WHERE `text` = ".'blabla'   //když zde dotaz končí, asi to stačí takto.
"SELECT * FROM `tabulka` WHERE `text` = ".'blabla'." AND ............."
// 5. Proměnná
"SELECT * FROM `tabulka` WHERE `text` = '$mojepromenna'"
"SELECT * FROM `tabulka` WHERE `text` = ".$mojepromenna
"SELECT * FROM `tabulka` WHERE `text` = ".$mojepromenna." AND .........."
//jeli $mojepromenna typu int - ukládáme číslo do DT int. Je-li v $mojepromenna string - ukládáme jako string do DT např. varchar
// 6. Složitější proměnná ve které normálně používáme apostrofy
"SELECT * FROM `tabulka` WHERE `text` = '$_POST[email]'"
"SELECT * FROM `tabulka` WHERE `text` = '{$_POST['email']}'"
"SELECT * FROM `tabulka` WHERE `text` = ".$_POST['email']." AND ......."
// Krom toho vstup od uživatele by měl být ošetřen.
"SELECT * FROM `tabulka` WHERE `text` = ".mysql_real_escape_string($_POST['email'])." AND ......."
// 7. Tím jsem narazil na použití funkce v SQL dotazu
"UPDATE `uzivatele` SET `heslo` = '".sha1($NoveHeslo)."' WHERE `user`= '{$_POST['user']}'"
// 8. Takové syntaxe s použitím funkce se asi použije při vkládání datumu do DT-DATE
"UPDATE `uzivatele` SET `datum` = '".date(??????)."' WHERE `user`= '{$_POST['user']}'"
// 9. Pravidla budou asi naprosto stejná pro všechny typy dotazů. UPDATE, SELECT, INSERT
// 10. A poslední věc, která mě cca za týden čeká a absolutně zatím o ní nevím nic, je ukládání obrázku do DT-BLOB

Snad jsem chytl všechny situace, které při psaní SQL dotazu mohou nastat.
Prosím, co je špatně?
Fisir
Profil
Reaguji na Jcase:
Prosím, co je špatně?
Kromě funkce mysql_real_escape_string(), která je zastaralá nic.
Joker
Profil
Jcas:
SQL dotaz pro MySQL je: SELECT * FROM `tabulka` WHERE `text` = 'blabla', přičemž ty obrácené čárky jsou nepovinné, pokud název není zároveň rezervovaným slovem MySQL.
Čili v uvedeném případě by bylo správně i SELECT * FROM tabulka WHERE `text` = 'blabla' (text je rezervované slovo).

Pokud se v nějakém programovacím jazyce, třeba v PHP, s SQL dotazem pracuje jako s řetězcem, v rámci toho jazyka jde o řetězec a je nutné dodržovat pravidla daného jazyka pro řetězce.

Toť vše.
Alphard
Profil
Jcas [#8]:
Již dříve jsem tady dával odkaz na PHP: Strings - Manual. Sice není česky, ale ty příklady snad ani nepotřebují komentář. Když umíte pracovat s řetězci v PHP, tak práce s db nepřínáší v tomto ohledu nic moc nového. Zpětné apostrofy nic nezmění a jednoduché apostrofy je třeba v určitých případech escapovat. Je třeba chápat to v kontextu, kdyby $mojepromenna obsahovala apostrof, tak se to rozsype, protože není escapován.

Nevidím důvod, aby byla v článcích o db rozebírána tato základní problematika, avšak měla by být detailně vysvětlená v základech PHP (to jsou ty nudné teoretické články, které mají lidé tendenci přeskakovat :-), netvrdím, že je to váš případ).
Jan Tvrdík
Profil
Jcas:
ukládání obrázku do DT-BLOB
Ukládat soubory (např. obrázky) přímo do databáze se dělá málokdy. Skoro vždy se soubory ukládají na disk a do databáze se ukládá jen cesta k obrázku (nebo nějaké identifikátor, ze kterého lze tu cestu odvodit).
Jcas
Profil *
Fisir
Děkuji za odka. Takže při použití bind_param() nemusím escapován řešit?

Jan Tvrdík
Děkuji za poznámku. Nahrávat na disk umím. Takže do DB uložím string s cestou a souborem?
'/obrazky/obrazek.jpg'

Postará se bind_param() o lomítka? Nebo musím ukládat:
'\/obrazky\/obrazek\.jpg'
Jan Tvrdík
Profil
Jcas:
Takže do DB uložím string s cestou a souborem?
Ano. Pokud ale víš, že obrázky ukládáš vždy do složky ./obrazky, tak nemusíš ukládat celou cestu (./obrazky/obrazek.jpg), ale můžeš do databáze uložit jen název souboru (obrazek.jpg).

Postará se bind_param() o lomítka?
Ano.
Fisir
Profil
Reaguji na Jcase:
Děkuji za odka.
Nemáš zač, vždyť odkazuji sám na svůj článek.

Takže při použití bind_param() nemusím escapován řešit?
Přesně tak, bind_param() odesílá data nezávisle na samotném dotazu a není tudíž třeba escapovat. Pokud bys to udělal, bylo by to dokonce špatně, protože by se data uložily a vypisovaly escapovaně.
Jcas
Profil *
Všem moc děkuji za odpovědi. Jste super. Kdybych nevedl tuto příšerně dlouhou diskusy, tak se ani třeba nedozvím, že mysql je zastaralé a nahrazuje ho mysqli. + spousty dalších věcí.
Kdyby Vás zajímalo, jak mi jde práce od ruky, tak ukážu první krůčky. I když to asi není zajímavé hrabat se kódu, který tvoří laik.

Mimochodem jsem narazil na zajímavou otázku. Rozhodl jsem se pro potvrzovaní z emailu. Takže potřebuji nějaký klíč pro kontrolu. Docela zajímavá otázka.
- soubor ten klíč by měl vytvořit dřív, než odešle email a zároveň si tu metodu vytvoření musí uchovat, až klient přijde z emailu. Kontrola 'id' či 'user' by se dala snadno vysledovat a třeba vypsat URL adresu ručně. I když nikdo neví, jak kontrolu provádím, tak lze předpokládat, že údaje, které odešlu při vyplňování registrace k tomu budou sloužit. A tak jsem si vymyslel (určitě nesmyslné řešení) $kod.

<?php     
// 1. Soubor zavolá nový user - chce se přidat do DB
// 2. Soubor se zavolá po odeslání formuláře - neprošel kontrolou
// 3. Soubor je zavolán z emailu - dokončení registrace.

// Soubor uloží data pouze do tabulky 'USER' a po potvrzení z emailu změní 'potvrzeni'=1
// Tabulka 'USER'
// |---id---|---nick---|---email---|---heslo---|---potvrzeni---|

// Do emailu se pošle odkaz na tento soubor a odkazem se předají hodnoty:
/* `USER['id']`==$_GET['id']
    `USER['nick']`==$_GET['nick']
    $kod==$_GET['kod']
    
    Kontrola formuláře:
    Odeslaný form odesílá $_POST['enter'] a pokud neprojde kontrolou, tak se naplní pole #hlaska[]
*/


require_once dirname(__FILE__).'/connect.php';        //není hotovo
require_once dirname(__FILE__).'/function.php';        //není hotovo

//---------KONTROLA FORMULARE-------------
$hlaska = array();
include './kontrola.php';        //není hotovo - funkce pro kontrolu formulářů

if (isset($_POST['enter'])) {                //form byl odeslán

    foreach ($_POST as $key => $value) {
        $_POST[$key] = odstranBileZnaky($_POST[$key]);        //odstranění bílých znaků
        $_POST[$key] = addslashes($_POST[$key]);                //escapování - bezpečnost
        }

    if(!empty($_POST['nick'])) {        //pokud nick není prázdný - zkontroluj existenci v DB
        $query = "SELECT * FROM `USER` WHERE `nick` = '" . $mysqli->real_escape_string($_POST['nick']) . "'");
        if ($mysqli->query($query)) {     
            $hlaska['nick'] = 'Přezdívka je již použita. Zvolte prosím jinou';
            }
        }
        else {$hlaska['nick'] = 'Přezdívka je poviná položka';}

    if(!empty($_POST['email'])) {                                            //kontrola emailu
        if(!jeEmai($_POST['email'])) {$hlaska['email'] = 'Špatně vyplněn email!';}
        }
        else {$hlaska['email'] = 'Email je poviná položka!';}
        
    if(!empty($_POST['heslo'])||!empty($_POST['heslo2'])) {        //kontrola hesla
        if(kontrolujHeslo($_POST['heslo'], $_POST['heslo2'])) {$hlaska['heslo'] = 'Špatně vyplněno heslo!';}
        }
        else {$hlaska['heslo'] = 'Nevyplnili jste heslo';}
    
    if($_POST['robot'] != 'nejsemspam') {        // kontrola proti spamu
        $hlaska['robot'] = 'Neprošla kontrola proti spamu';
        }
        
}


//---------------KONTROLA VSTUPU------------
if(isset($_GET['id'])&&isset($_GET['nick'])&&isset($_GET['kod'])) {        //vstup je z emailu - dokončit registraci
    
    // načti data z DB 
    $query = "SELECT * FROM `USER` WHERE `id` = '$_GET[id]' AND `nick` = '$_GET[nick]'";
    if ($result = $mysqli->query($query)) {
        $row = $result->fetch_assoc())             /* fetch associative array */           
        $result->close();                                /* free result set */
        }
    
    // kontrola $kod - aby někdo nemohl podstrčit adresu ručně + kontrola hodnoty potvrzeni
    $kod = $row['id']*3/2;
    if(($_GET['kod']) != $kod || $row['potvrzeni']!=0 || $_GET['id']!= $row['id'] || $_GET['nick']!= $row['nick'] || $_GET['email']!= $row['email']) {
        header("Location: chyba.php");        //přesměruj na chybovou stránku
        }
        else {                                        // změna hodnoty `potvrzeni`
            if($mysqli->query("UPDATE `USER` SET `potvrzeni` = 1 WHERE `nick`= '$_GET[nick]' AND `id` = '$_GET[id]'")) {
                header("Location: login.php?registrace=ok")            // vše OK - přesměrovat na přihlášení
                }
                else {header("Location: chyba.php");}
            }
    
    
    
    }
elseif(isset($_POST['enter']) && empty($hlaska)) {                //form odeslán a prošel kontrolou
    
    // uložit data do DB             |---id---|---nick---|---email---|---heslo---|---potvrzeni---|
    $statement = $mysqli->prepare("INSERT INTO `USER` VALUES (?,?,?,?,?)");
    if(!$statement) { echo("Příprava SQL dotazu selhala: ".$mysqli->error); }
    $statement->bind_param("isssi", '', $_POST['nick'], $_POST['email'], sha1($_POST['heslo'], 0));    
    $statement->execute();
    $statement->close();

    // nachystat email a odeslat
    $query = "SELECT * FROM `USER` WHERE `nick` = '$_POST[nick]'";
    if ($result = $mysqli->query($query)) {
        $row = $result->fetch_assoc())             /* fetch associative array */           
        $result->close();                                /* free result set */
        }
    
    $kod = $row['id']*3/2;
    
    $mail = $_POST['email'];
    $predmet = 'Registrace do databáze chovatelů';
    $zprava = "Děkujeme za registraci.\r\n Pro dokončení registrace navštivte prosím následují odkaz\r\n ."&id=".$_POST['id]http://www.zocschmoravskebranice.eu/DB-chovatelu/registrace.php.?kod=".$kod."&nick=".$_POST['nick']."&id=".$_POST['id'];    
    
    if (cs_mail($mail, $predmet, $zprava, "From: ".$mail.PHP_EOL)) {
        header("Location: konec.php");            // přesměrovat na konečnou stránku
            }
            else {echo "Chyba! Selhalo odeslání emailu pro dokončení registrace. Kontaktujte prosím administrátora.";}    

    }
    else { include './form-registrace.php'; }                                //form ještě nebyl odeslán, nebo neprošel kontrolou


$mysqli->close();

?>
Alphard
Profil
Jcas:
$_POST[$key] = addslashes($_POST[$key]);                //escapování - bezpečnost
Tohle není moudré, escapování zajístí dále použitá escapovací funkce konkrétní databázové extenze. Dvojité escapování rozbije data.
Celkově není moc dobrý styl programování modifikovat si superglobální pole POST, GET, .... Časem můžete být překvapen, proč je tam něco jiného než to, co odesíláte.

$query = "SELECT * FROM `USER` WHERE `id` = '$_GET[id]' AND `nick` = '$_GET[nick]'";
Jestli se tady nespoléháte na nějaké podobné globální escapování, tak zde je nezabezpečený vstup.
Jan Tvrdík
Profil
Jcas:
$_POST[$key] = odstranBileZnaky($_POST[$key]);
Liší se ta funkce nějak od vestavěné funkce trim? Navíc to selže pokud by $_POST[$key] obsahovala pole.

isset($_GET['id'])&&isset($_GET['nick'])&&isset($_GET['kod'])
Lze zkrátit na isset($_GET['id'], $_GET['nick'], $_GET['kod'])

"SELECT * FROM `USER` WHERE `id` = '$_GET[id]' AND `nick` = '$_GET[nick]'"
Obsahuje SQL injection zranitelnost. Vstupy do DB je potřeba správně escapovat.

$kod = $row['id']*3/2;
Tohle lze uhádnout. Správné řešení je použít jako kód náhodný řetězec, který si při registraci uložíš do databáze. Navíc proměnná $row nebude v případě neexistujícího uživatele vůbec existovat.

sha1($_POST['heslo']
Jednak tam chybí ukončovací závorka volání funkce (je na špatném místě) a jednak funkce sha1 není z hlediska bezpečnosti pro hashování hesel vhodná. Lépe je použít funkce password_hash dostupnou od PHP 5.5 nebo funkci crypt, která funguje dobře od PHP 5.3.7.

header("Location: konec.php");
Po přesměrování je dobrým zvykem ukončit provádění skriptu pomocí exit.
1Pupik1989
Profil
Jcas:
A nedej bože, že najdu ve fc break: Takové break a za ním return ve mě vyvolává přímo šílenství.

To je úplně jednoduché. break se používá jako ukončení switche nebo cyklu (while, for, foreach). Kdežto return ti v tom případě ukončí celou funkci. Return v cyklu zavoláš pouze v případě, že něco chceš vrátit hned. Třeba prohledáváš pole, kde chceš zjistit jestli hodnota existuje. Teď vynecháme nativní metody a funkce. Vytvoříš nějakou funkci, která projede pole a najde hodnotu shodující se s hledanou. V takovém případě prostě zapíše return true pokud pojde zbytek pole, tak na konci uvedeš return false. Zkráceně řečeno. break zastaví cyklus nebo switch, return zastaví celou funkci.
Jcas
Profil *
Děkuji - zkusím si zase trochu zpracovat Vaše poznámky.
Alphard, Jan Tvrdík: viz SELECT
Asi mám trochu problém pochopit, co je vstup. Zvlášť když zde pouze tahám data z DB a nic tak nevkládám.
-Takže vstup je každé kontaktování DB, i když jeho výsledkem je výstup (výpis dat).

I když jsem si $_GET['nick'] vytvořil sám získáním dat z DB (nepovažoval jsem ji jako vstup od uživatele) a použil ju pro odkaz, tak uživatel by mohl ručně přepsat URL a tím ji změnit.
http://cs.wikipedia.org/wiki/SQL_injection

Tím se ale dostávám k tomu, že se může hodit hromadné escapování při potřebě použít hodně podmínek. Aby nevznikal takové příšerné dotazy.
"...WHERE `col1` = '".$mysqli->real_escape_string($prom1)."' AND `col2` = '".$mysqli->real_escape_string($prom2)."' AND atd atd atd

Každopádně pro mé potřeby asi stačí bohatě jednoduchý dotaz, protože `id` je v DB unikátní a pořádnou kontrolu dělám o dva řádky níž.
"SELECT * FROM `USER` WHERE `id` = ".$mysqli->real_escape_string($_GET['id'])
...
...
if(($_GET['kod']) != $kod || $row['potvrzeni']!=0 || $_GET['id']!= $row['id'] || $_GET['nick']!= $row['nick'] || $_GET['email']!= $row['email'])

------------------------------------------------------------------

Jan Tvrdík:
1. odstranBileZnaky - je tam obyč trim(). Dal jsem ji bokem, protože ji chci volat i z jiných formulářů-souborů (editace, přidání záznamu atd)
Je to totální blbost, protože volám fc proto, aby zavolala jinou fc. A stejně tu fc musím zavolat v každém souboru. Takhle si opravdu každý soubor může zavolat přímo trim().

2. $kod uložit do DB s náhodným číslem - vše jasné
To konec konců mohu udělat přímo s sloupcem `potvrzeni`. Dám mu výchozí null a buď bude mít null, nebo kod.

3. sha1()
https://admin.skok.cz/conf.php?t=php5.3
Dle toho co píšeš, tak ty fc asi používat nemůžu. Mysqli bych teoreticky mohl používat, akorát "prepare statements" mohu používat pouze pro INSERT.
(ps. Mysqli - nenašel jsem snad jediný příklad pro UPDATE)
Jan Tvrdík
Profil
Jcas:
Asi mám trochu problém pochopit, co je vstup.
Všechno, co si bereš z $_GET, $_POST, $_FILES, $_COOKIE, $_REQUEST a částečně i $_SERVER je uživatelský vstup. Tedy něco, co přímo ovlivňuje uživatel.

I když jsem si $_GET['nick'] vytvořil sám získáním (…), tak uživatel by mohl ručně přepsat URL
Přesně tak. Ta proměnná nemusí existovat vůbec, nebo to může být pole, nebo může mít nějakou hodnotu, co si uživatel vymyslel.

Tím se ale dostávám k tomu, že se může hodit hromadné escapování při potřebě použít hodně podmínek. Aby nevznikal takové příšerné dotazy.
Jakékoliv hromadné escapování je principiálně špatně, protože vstup může být použit na různých místech, které vyžadují různé escapování. Je proto potřeba escapovat hodnoty až v místě použití funkcí, která je k tomu v daném místě (kontextu) vhodná.

Pro začátek je dobré naučit se formátovat SQL dotazy do více řádků. V jednom řádku je to velmi nepřehledné a tím pádem náchylné k chybám. Např. $mysqli->query("UPDATE `USER` SET `potvrzeni` = 1 WHERE `nick`= '$_GET[nick]' AND `id` = '$_GET[id]'") bys mohl přepsat takto:

if (isset($_GET['nick'], $_GET['id']) && is_string($_GET['nick') && is_numeric($_GET['id')) {
    $result = $mysqli->query("
        UPDATE `USER`
        SET `potvrzeni` = 1
        WHERE
            `nick` = '" . $mysqli->real_escape_string($_GET['nick']) . "' AND
            `id` = " . intval($_GET['id']) . "
    ");
}

Nebo s použitím prepared statements takto:

if (isset($_GET['nick'], $_GET['id']) && is_string($_GET['nick') && is_numeric($_GET['id')) {
    $statement = $mysqli->prepare("
        UPDATE `USER`
        SET `potvrzeni` = 1
        WHERE `nick` = ? AND `id` = ?
    ");
    $statement->bind_param('si', $_GET['nick'], $_GET['id']);
}

Pokud by ti zápis, který používá MySQLi nevyhovoval, tak můžeš ještě zkusit PDO nebo použít nějakou hotovou knihovnu pro pohodlné psaní SQL dotazů, např. dibi.

Dle toho co píšeš, tak ty fc asi používat nemůžu.
Na webu máš PHP 5.3.28, což je novější verze než 5.3.7, můžeš tedy bezpečně použít funkci crypt. Nebo můžeš použít knihovnu password_compat, která ti umožní používat funkce password_hash a password_verify i v PHP starším než 5.5.
Jcas
Profil *
Děkuju
ps. Není nad to mít pocit vlastní tuposti, hlouposti a omezenosti.
"SELECT * FROM `USER` WHERE `id` = ".$mysqli->real_escape_string($_GET['id'])
"escape_string" je v názvu té funkce asi pro srandu králíkům. Jen blbec může vymyslet, ze strachu z bezpečnosti, escapovat číslo.
"SELECT * FROM `USER` WHERE `id` = ".intval($_GET['id'])
Takže intval je dost bezpečný, protože by (asi) neměl propustit jiný znak než [0-9]

Prepare statement se mi líbí. Nicméně ve svém článku píšeš, že se svou verzí php ho nemůžu použít pro select. Ale co ten Update?
juriad
Profil
Na této stránce píše, jak je funkcionalita závislá na verzi PHP:
http://www.fisir.tk/itblog/prepared-statements

INSERT, UPDATE, DELETE nic nevrací, nepotřebuješ tedy získávat data z dotazu (to je ten okamžik, který dělá problémy).
Prostě zavoláš jen execute() a close(); žádné get_result() and bind_result() volat přece nebudeš.

Je však dobré podotknout: zvol jeden zpusob dotazování a ten používej konzistentně v celé aplikaci.
Jan Tvrdík
Profil
juriad:
Na této stránce píše, jak je funkcionalita závislá na verzi PHP:
Osobně mysqli ani prepared statements nepoužívám, ale tvrzení „MySQL Native Driver (…) je v PHP nativně dostupný až od verze 5.4“ je chybné. MySQL Native Driver je dostupný od PHP 5.3, viz php.net/manual/en/intro.mysqlnd.php. Stejně tak metoda mysqli_stmt::get_result je dostupná od PHP 5.3.
juriad
Profil
Jan Tvrdík:
Také to nepoužívám, takže jde buď o chybu v článku, nebo osobní zkušenost. Třeba se k tomu Fisir vyjádří nebo článek opraví.
Omlouvám se Fisákovi, kterého jsem zde omylem zmínil a Fisirovi, kterého jsem omylem nezmínil.
Jcas
Profil *
Co používáte? PDO?
Alphard
Profil
Jcas:
Většinou se používají nadstavbové knihovny, ať již v rámci různých frameworků jako Nette db vycházející z dibi a NotORM nebo různé ORM systémy jako Doctrine. Druhá část zmíněných věcí však podle mě rozhodně není vhodná pro začátečníka, který si není ani jist syntaxí, jak zapisovat stringy.
Zkuste kouknout na dibi.
Fisir
Profil
Reaguji na juriada:
Třeba se k tomu Fisak vyjádří nebo článek opraví.
Psal to Fisir.

Teď jste mě dostali. MySQLnd je skutečně dostupný již od PHP 5.3, nicméně jako výchozí ovladač je nastaven až od PHP 5.4 (zdroj). Je to mystifikování, ale už opravené.
« 1 2

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0