Autor Zpráva
eager_beaver
Profil
Ahojte odborníci ☺ Potřeboval bych poradit s menším problémem.
Nedokázal jsem za celé odpoledne přijít na to, jak pracovat s proměnnýma v databázi, učím se za pochodu. Jelikož čas neúprosně utíká, obracím se na vás.

Takže řekněme, že chci dostat z databáze např. chybové hlášky. Některé hlášky jsou pravidelné, které se opakují a některé zase konkrétně cílené, tzn., že jsou složené z vlastního řetězce, ale zároveň obsahují proměnnou z pravidelných hlášek.

Jestli to zní zamotaně (ač si to nemyslím), možná pomůže následující kód, jakým získávám tyto složené řetězce:

//ids chybových hlášek, které chci získat
$req_errs_elems=array('e_id_one','e_id_two',...);

//inicializace pole složených chybových hlášek
$errors=array();

//statement
if($q=$mysqli->prepare("SELECT * FROM errors WHERE data_type=? AND e_id IN ('$req_errs_elems')")){
  //vazba parametru
  $d_t='value';
  $q->bind_param('s',$d_t);
  //provedení dotazu a výsledek
  $q->execute();
  $r=$q->get_result();
  //iterace
  while($row=$r->fetch_assoc()){
    //id erroru
    $e=str_replace(' ','',$row['e_id']);
    $e_len=mb_strlen($e);
    //jazyková verze
    $l=str_replace(' ','',$row['lang']);
    $l_len=mb_strlen($l);
    //hodnota
    $v=$row['val'];
    $v_len=mb_strlen($v);
    //podmínky pro přijetí výsledku
    if(($e_len>=3)&&($l_len==3)&&($v_len>=3)){
        //výsledek splňuje podmínky a může být zařazený do pole chybových hlášek
        $errors[$e][$l]=$v;             // je problém snad tady?
    }
  }
}

Stejným způsobem jsem ještě předtím získal pravidelné řetězce, jejichž pole má stejnou strukturu:
print_r($reg_errs);
Array(
  [unexp_err] => Array (
     [ces] => Nastala neočekávaná chyba:
     [eng] => An unexpected error has become:
   )
)

Tímto způsobem jsou data uložená v databázi (uvádím jen potřebné sloupce a jedna řádka snad postačí):

ID              |      e_id (VARCHAR)       |     lang(CHAR3)      |      val(MEDIUMTEXT)
-------------------------------------------------------------------------------------------
1               |      e_id_one             |     ces              |      $reg_errs['unexp_err']['ces'].' Řetězec chybové hlášky
                                                                          e_id_one s prefixem z pravidelných řetězců.'


Takže, pokud se vám někomu zkušenému podařilo hned zjistit, kde je problém, budu vám vděčný, pokud mě alespoň navedete na správný směr. Naopak se na mě obraťte, pokud jste čemukoliv neporozuměli a pomohlo by vám to mně pomoct ☺ Jo a prosím vás o shovívavost (školu na to nemám), pokud jsem vám dal tímto topicem důvod myslet si, že jsem nevzdělanec, tak mně to aspoň napište, díky ☺


EDIT:
Jen pro doplnění, výsledek by samozřejmě neměl vypadat jako v databázi, ale jako řetězec mezi uvozovkama níže:

echo $errors['e_id_one']['ces'];

"Nastala neočekávaná chyba: Řetězec chybové hlášky e_id_one s prefixem z pravidelných řetězců."
eager_beaver
Profil
Prosím vás, řekněte mi alespoň někdo, že jsem problém špatně vyložil, či dělám něco úplně špatně. Díky moc.
juriad
Profil
eager_beaver:
Zkus napsat, co už ti funguje. Předpokládám, že ti to vypíše:
$reg_errs['unexp_err']['ces'].' Řetězec chybové hlášky e_id_one s prefixem z pravidelných řetězců.'

Problém je v tom, že jsi do databáze uložil kus PHP. K jeho vykonání slouží funkce eval, ale každý (včetně mě) tě od jejího použití bude z dobrých důvodů odrazovat. Samotná databáze proměnné nezná.
Zde jsem omylem zaměnil funkci eval za exec, tyto funkce se podstatně liší.

Řešení je několik:
1) do tabulky errorů přímo zapsat hotovou hlášku bez proměnných. Ty proměnné se přece pokaždé nahradí stejnou hodnotou - můžeš si to předpočítat. Pak žádné proměnné nepotřebuješ.

2) použít jiný formát, třeba takový který vyhovuje funkci vsprintf.
Přidáš jeden další sloupec, ve kterém budeš mít čárkami oddělené hodnoty (toto také není ideální, ale může to být dobrý kompromis):
1 | e_id_one | ces | %s Řetězec chybové hlášky e_id_one s prefixem z pravidelných řetězců a suffixem %s. | reg_errs[unexp_err], reg_errs[nejaky_suffix]

Toto dokážeš do PHP načíšt. Ten poslední sloupec rozlámeš podle čárek a závorek - tím ti vznikne název tabulky (reg_errs) a id (unexp_err, nejaky_suffix).
A nakonec tím jen nakrmíš vsprintf:
vsprintf($errors[$id][$lang], array($reg_errs['unexp_err'][$lang], $reg_errs['nejaky_suffix'][$lang]));
eager_beaver
Profil
Ahoj juriade. Já jsem věděl, že mě tohle fórum nenechá na holičkách a jak vidím, opravdu bych to jinak nezvládl.

Rád bych se zeptal, proč bys mě odradil od funkce eval().

Hlášky bez proměnných - Tomuhle řešení bych se rád vyhnul z několika důvodů, které je ale zbytečné vypisovat. Tohle bych opravdu vynechal... Navíc, když...

... jsem funkci vsprintf po přelouskání oříšků jako "nakrmíš", "rozmlámeš" po založení nového sloupce implementoval a vše běží, jak má, takže za návod i linky opravdu tisíceré díky! ☺☺

Jakmile doladím, postnu sem trochu zpětné vazby pro fórum, aby případní kolemjdoucí mohli z čeho čerpat.
juriad
Profil
eager_beaver:
eval je především nebezpečný. Představ si, že budeš do hlášky doplňovat chybovou hodnotu, kterou zadal uživatel. A co když zadá něco jako: ' . `rm index.php` . '
Mazání vypadá špatně, ale co třeba taková funkce file_get_contents, kterou si může přečíst libovolný soubor, nebo funkce mail, kterou může spamovat při každém zobrazení stránky.

Eval vykoná cokoli a nemusí to být jen triviální doplnění hodnot proměnných, které očekáváš. Je to v podstatě to samé, jako bys umožnil uživateli zapsat cokoli do souboru a ten následně includnul. Protože eval je tak mocný, téměř vždy existuje vhodnější řešení. V tomto případě jsem zvolil vsprintf.

Při použití evalu musíš mít jistotu, že uživatel nikdy nebude mít způsob, jak ovlivnit hodnotu evalnutého řetězce.
Eval je navíc pomalý.

Zde jsem omylem zaměnil funkci eval za exec, tyto funkce se podstatně liší.
eager_beaver
Profil
juriad:
V tom případě se divím, že taková funkce je vůbec "k mání", nebo že to není nějakým způsobem ošetřené. Nezkušeného začátečníka, jako jsem já, by to mohlo stát nejen čas či peníze. Ale chápu že vývojáři nevyvíjí pro začátečníky. Každopádně jsem vděčný za cenné rady.
juriad
Profil
eager_beaver:
Spletl jsem si funkce eval a exec; myslel jsem samozřejmě eval. Ve svých příspěvcích jsem to opravil.
eager_beaver
Profil
juriad:

Taky jsem to v příspěvku opravil.
Alespoň v dokumentaci upozorňují:
Caution
The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

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