Nette\Database jednoduchý návod
- bluray
- Člen | 178
Dobrý den, potřeboval bych trochu poradit s Nette\Database. nenašel jsem
tu nikde žádný rozsáhlejší návod, pouze "":https://doc.nette.org/cs/database a
to je pro mě dost málo.
Dělám registraci uživatelů a snažím se ověřit jestli mám už uživatele
se zadaným jménem nebo emailem. jak to udělám? potřebuju tento SQL dotaz:
select id from users where name=$name or email=$email
mám tento kod:
public function add(array $data){
$this->exists($data["name"], $data["email"]);
}
private function exists($name, $email){
$this->database->query("SELECT `name` FROM `users` WHERE `name`= ? OR `email`= ?", $name, $email)->dump();
}
Vygeneruje mi to ale toto:
SELECT name
FROM users
WHERE name
=
‚pepa‘ OR email
= ?
Dále bych potřeboval vědět jak dodělat metodu exists(), takže bych
potřeboval něco jako num_rows to ale nikde nevidím, query vrací podle
dokumentace Nette\Database\ResultSet, takže to se hodí asi jenom při select
dotazu že jo? co když chci při insertu vědět jestli dotaz proběhl? jak to
zkontroluju?
Existuje nějaký rozsáhlejší návod na databázi?
Děkuji za pomoc
Editoval bluray (19. 5. 2014 20:16)
- Mysteria
- Člen | 797
Anglická verze toho samého návodu je lepší (aktuálnější): https://doc.nette.org/…ase/explorer
Chceš používat čistou Nette\Database nebo Nette\Database\Table?
Kdyby jsi chtěl to druhý, tak celkem jednoduše:
if (count($this->database->table('users')->where(['name' => $username, 'email' => $email]))) {
// Je možné použít...
}
@matej21: Super vědět ;)
Editoval Mysteria (19. 5. 2014 20:49)
- David Matějka
- Moderator | 6445
@Mysteria: cz verze uz byla aktualizovana
@bluray: neescapuj v SQL, o to se postara nette – vse, co je malyma pismenama bere jako identifikator (nazev sloupce, tabulky) a oescapuje to. Klicovy slova atd. musis proto psat velkyma pismenama.
- bluray
- Člen | 178
Děkuji za pomoc, už mi to funguje.
Ale narazil jsem na jiný problém. Jak mohu v modelu zjistit IP? našel jsem
že v presenteru to jde pomocí
$this->context->httpRequest->getRemoteAddress()
context ale v modelu nemám a když zkusím $_SERVER[„REMOTE_ADDR“] vznikne
chyba že byly odeslány hlavičky.
- bluray
- Člen | 178
matej21 napsal(a):
Vyzadej si Nette\Http\IRequest
viz http://nette.matej21.cz/cs/di
Mohl bys mi prosím tě ukázat jak to IRequest použiji? Moc se v tom nevyznám
- David Matějka
- Moderator | 6445
class MyService
{
protected $httpRequest;
public function __construct(\Nette\Http\IRequest $httpRequest)
{
$this->httpRequest = $httpRequest;
}
public function doSth()
{
$ip = $this->httpRequest->getRemoteAddress();
}
}
- amik
- Člen | 118
Přístup k proměnné $_SERVER[‚REMOTE_ADDR‘] (a ani žádné jiné)
sám o sobě chybu s hlavičkami nezpůsobí, ta nastává při obvyklém
nastavení serveru, pokud se pokusíš volat php funkci header() potom, co již
byl odeslán nějaký výstup. Problém tedy bude jinde, nicméně čistější
nette řešení je použít IRequest.
Záleží na tom, jak tvůj model vypadá, pokud jde například o service,
stačí do konstruktoru dát parametr typu Nette\Http\IRequest (a pak si ho
uložit do proměnné):
function __construct(Nette\Http\IRequest $request) {
$this->request = $request;
}
a Nette ti do něj automaticky hodí správnou třídu. Pokud nejde o službu, ale nějakou třídu, jejíž instance vytváříš v aplikaci ručně, musíš do ní taky ručně z presenteru dopravit IRequest.
Ani v presenteru bys podle nejnovějších coding standardů neměl používat context, ale vyžádat si request pomocí injection – podobně jako v modelu, jen ne přes konstruktor presenteru, ale speciální metodu inject:
function injectWhateverNameYouWantToGive(Nette\Http\IRequest $request) {
$this->request = $request;
}
Nette volá všechny metody začínající „inject“ automaticky při vytvoření presenteru a předá jim služby odpovídající parametrům.
- David Matějka
- Moderator | 6445
@amik: inject* metody nejsou doporucovane, v presenterech by se mela
pouzivat @inject
anotace, viz https://forum.nette.org/…inych-sluzeb
- bluray
- Člen | 178
Pořád mi to nefunguje, potřebuju ukládat IP do db, mám takovouto metodu:
public function __construct(Nette\Database\Context $database, Nette\Http\IRequest $request) {
parent::__construct($database);
$this->request = $request;
$this->table = "users";
}
public function add(array $data){
$pass = $data["password"];
if(strlen($pass) < PasswordLenght)
throw new \Nette\InvalidArgumentException("Minimální délka hesla je ". PasswordLenght." znaků");
$data["password"] = Passwords::hash($pass);
$data["ip"] = "INET_ATON(".$this->request->getRemoteAddress().")";
$this->database->query('INSERT INTO '.$this->table, $data);
}
Místo IP mi to ale píše ::1
INSERT INTO users (name
, email
, password
,
gender
, ip
)
VALUES (‚jmeno‘, ‚email‘, ‚heslo‘, ‚muž‘,
‚INET_ATON(::1)‘)
- David Matějka
- Moderator | 6445
$data["ip"] = "INET_ATON(".$this->request->getRemoteAddress().")";
ti nebude fungovat, bude se to brat jako hodnota, ktera se nalezite oescapuje, zkus:
$data["ip"] = $this->database->literal("INET_ATON(?)", $this->request->getRemoteAddress());
- David Matějka
- Moderator | 6445
jo, radeji to ukladej jako string, ten inet_aton by ipv6 asi nezvlad :)
mám tam ::1 napadá mě, není to tím že jsem na localhostu? ale to by přece měl vracet 127.0.0.1
viz prispevek #11