Black Friday je tu! Využij jedinečnou příležitost a získej až 80 % znalostí navíc zdarma! Více zde
Aktualizovali jsme provozní podmínky. Pokračováním užívání sítě s nimi projevíte souhlas.
BF extended 2022
Avatar
Ryan99
Člen
Avatar
Ryan99:1.3.2018 21:18

Ahoj,

chtěl bych se zeptat jak můžu u databázovému wrapperu použít vlastní SQL dotaz?

Vím že wrapper funguje právě pro odstínění logiky od dat (ačkoliv zaescapování mi přišlo jednodušší), ale já bych potřeboval v dotazu:

public function vratClanky()
        {
                return Db::dotazVsechny('
                        SELECT `clanky_id`, `titulek`, `url`, `popisek`
                        FROM `clanky`
                        ORDER BY `clanky_id` DESC
                ');
        }

Použít vlastní "WHERE" ve stylu viz. níže s tím že tam těch parametrů může být více. Cena tam být může, ale nemusí, stejně tak oblast. V klasickém dotazu by to bylo jasné, ale tady předpokládám místo otazníku nemůžu použít celé "AND cena < XXX"...

public function vratClanky($cena,$oblast)
        {
                return Db::dotazVsechny('
                        SELECT `clanky_id`, `titulek`, `url`, `popisek`
                        FROM `clanky`
                        WHERE cena = ? AND oblast = ?
                ',array($cena,$oblast));
        }

Díky

 
Odpovědět
1.3.2018 21:18
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na Ryan99
Petr Čech:1.3.2018 21:27

můžeš udělat něco takového:

$where = $cond ? 'WHERE cena = ? AND oblast = ?' : '';
return Db::dotazVsechny('
                        SELECT `clanky_id`, `titulek`, `url`, `popisek`
                        FROM `clanky`'
.$where ,array($cena,$oblast));
Nahoru Odpovědět
1.3.2018 21:27
the cake is a lie
Avatar
Petr Čech
Tvůrce
Avatar
Petr Čech:1.3.2018 21:29

Jo, a ještě:
ewww, český kód.

Nahoru Odpovědět
1.3.2018 21:29
the cake is a lie
Avatar
Ryan99
Člen
Avatar
Ryan99:1.3.2018 21:42

Díky za rychlou reakci. Zjednodušil jsem si to na jednu proměnnou, ale bohužel mi řešení nefunguje. Takto:

public function vratClanky($oblast)
        {
                return Db::dotazVsechny('
                        SELECT `id`, `nazev`
                        FROM `clanky` WHERE `oblast` = ?
                ', array($oblast));
        }

Vypíše přesně to co potřebuji. Pokud kód změním na:

public function vratClanky($oblast)
        {
                        $where = $cond ? ' WHERE `oblast` = ? ' : '';
                return Db::dotazVsechny('
                        SELECT `id`, `nazev`
                        FROM `clanky`
                '.$where, array($oblast));
        }

Tak nevypíše žádný článek. A ještě jedna věc - jak bys mi doporučil předat tu proměnnou "where" s dotazem? Tohle mám totiž v modelu (snažím se o MVC) a v kontroleru potom:

$clanky= $clanky->vratClanky($oblast,$cena, atp.);

Předpokládám že jako parametr funkce to nepůjde...

PS: Co je myšleno tím "ewww, český kód"?

Editováno 1.3.2018 21:43
 
Nahoru Odpovědět
1.3.2018 21:42
Avatar
Šimon Rataj
Člen
Avatar
Šimon Rataj:2.3.2018 15:19

Takhle to mám vyřešené ve své knihovně:

  protected $connect;
  protected $fncs = [];

 public function query($query) {
    if(empty($this->db) && !in_array($fnc, ["__construct", "changeDB", "dbList"]))
      throw new Exception("No database selected");
    $result = $this->connect->query($query);
    if($this->connect->errno)
      throw new Exception("Error in MySQL: " . $this->connect->error . " <strong>SQL command:</strong> " . $query);
    return $result;
  }

  public function __set($name, $query) {
    $this->fncs[$name] = $query;
  }

  public function __get($name) {
    return $this->fncs[$name];
  }

  public function __call($name, $params) {
    if(isset($params[0]) && is_array($params[0]))
      $this->execFnc($name, $params[0]);
    else
      $this->execFnc($name, $params);
  }

  public function __isset($name) {
    return isset($this->fncs[$name]);
  }

  public function __unset($name) {
    if(isset($this->fncs[$name]))
      unset($this->fncs[$name]);
    return true;
  }
  public function setFnc($name, $query) {
    $this->fncs[$name] = $query;
  }

  public function execFnc($name, $params = []) {
    if(isset($this->fncs[$name]))
      $this->queryf($this->fncs[$name], $params, $name);
    else
      throw new Exception("(" . $name . "): This function isn't defined");
  }
public function queryf($q, $a) {
    foreach($a as $k => $v) {
      $q = str_replace("%" . $k, $this->escape($v), $q);
    };
    return $this->query($q);
  }

A můžeš to provést třeba takhle:

$db->vratClanky = "SELECT `clanky_id`, `titulek`, `url`, `popisek` FROM `clanky`  WHERE cena = %0 AND oblast = %1";
$result = mysqli_fetch_object($db->vratClanky("Oblast..."));
 
Nahoru Odpovědět
2.3.2018 15:19
Avatar
Hando
Člen
Avatar
Odpovídá na Ryan99
Hando:2.3.2018 20:03

Pokud používáš MVC, tak si v modelu napiš funkci, která ti podle množství uvedených parametrů sestaví dotaz na míru a ten následně předá wrapperu ke zpracování jako argumenty funkce/metody, tedy vratVsechny($query, $params), ať si to následně wrapper sám přebere. To mi připadá jako nejčistší řešení a není potřeba "ohýbat" samotný wrapper. Minimálně se ti to bude hodit při debugování, když si budeš moci nechat vypsat celý dotaz jako string a uvidíš, co se taky dosazuje.

Pokud bys chtěl používat nějakou pokročilejší třídu, tak třeba Dibi ( https://dibiphp.com/cs/quick-start ) nabízí poměrně značné možnosti, případně i fluentí skládání dotazů, ale to si myslím není úplně potřeba.

 
Nahoru Odpovědět
2.3.2018 20:03
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.