Diskuze: Komentáře pouze pro přihlášené
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 42 zpráv z 42.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Pouze vždy ověříš, zda je uživatel přihlášený, např. podle
$_SESSION
.
if (isset($_SESSION['user']) && $_SESSION['user'])
{
// ...
}
Tu podmínku můžeš použít jak při odesílání formuláře, tak při jeho zobrazování.
Co jsem tak letmo proletěl onu knihu návštěv, tak by nejspíš stačilo udělat drobnou úpravu v při návrhu databáze. Konkrétně propojit tabulku články a komentáře. Nevím jak jsi v tomhle směru zdatný, tak se případně dál zeptej na to, co by ti nebylo jasný.
Jde o to, že budeš mít řekněme tabulku články a tabulku komentáře.
Jak teď ale poznáš, který komentář patří k jakému článku? Když to
vezmu stručně tak v tabulce komentáře budeš mít sloupeček id_clanku_FK
(cizí klíč), kterým budeš odkazovat na článek, ke kterému komentář
patří. Jestli si databázi navrhuješ přes phpMyAdmin, tak tam myslím ten
cizí klíč nastavit jde, ale nejsem si jistý. Lepší by bylo ho tam potom
přidat SQL příkazem na konci, ale to teď nebudeme řešit. Když už budeš
mít databázi hotovou, tak při zobrazení nějakého článku budeš znát
jeho ID z GET parametru, pak už jen stačí upravit dotaz do databáze tak, aby
načetl i komentáře, které mají id_clanku_FK stejné jako id_clanku, to se
dělá přes SQL pomocí JOIN.
Jinak můžeš postupovat podle návodu, jen při ukládání komentáře do DB
musíš uložit navíc to ID článku do id_clanku_FK (nebo jak si to
pojmenuješ) a při načítání to samé.
Ok, v tabulce mám sloupec pojmenovaný jako id_clanku_FK (mohl by jsi mi
prosím napsat ten sql dotaz, který je propojí?
Mám tabulky clanky se sloupcem clanky_id a chci mít cizí klíč v tabulce
nkniha ve sloupci id_clanku_FK
A zapisovaní dat do databáze takto:
<?php
session_start();
require('Db.php');
$spojeni = Db::connect('127.0.0.1', 'sokolmilicincz1', 'root', ''); //pripojeni k db
if (isset($_GET['clanek'])) //zobrazeni clanku
$url = $_GET['clanek'];
else
$url = 'uvod';
$clanek = Db::queryOne('
SELECT *
FROM clanky
WHERE url=?
', $url);
if (!$clanek) //pokud se nenalezne clanek, tak 404
{
if ($url != 'chyba')
{
header('Location: index.php?clanek=chyba');
exit();
}
else
die('Nebyl nalezen chybovy clanek');
}
if (isset($_GET['odhlasit']))
{
session_destroy();
header('Location: index.php');
exit();
}
function zabezpec($retezec)
{
return Db::quote($retezec);
}
?>
<!DOCTYPE html>
<html lang="cs-cz">
<head>
<meta charset="utf-8" />
<meta name="description" content="<?= htmlspecialchars($clanek['popisek']) ?>" />
<meta name="keywords" content="<?= htmlspecialchars($clanek['klicova_slova']) ?>" />
<link rel="stylesheet" href="styl.css" type="text/css"/>
<link rel=stylesheet href="style_blue.css" id=css>
<link rel=stylesheet href="print.css" media="print">
<title><?= htmlspecialchars($clanek['titulek']) ?></title>
<script src="js/rozklikavaci_menu.js"></script>
<script src="js/switcher.js"></script>
<script src="js/checkform.js"></script>
</head>
<body>
<header>
<div id="logo"><img src="obrazky/sokolMale.png" alt="logo"></div>
<nav>
<ul>
<li class="aktivni"><a href="index.php">Domů</a></li>
<li><a href="sport.php">Sport</a></li>
<li><a href="kultura.php">Kultura</a></li>
<li><a href="fotogalerie.php">Fotogalerie</a></li>
<li><a href="dokumenty.php">Dokumenty</a></li>
<li><a href="historie.php">Historie</a></li>
<?php
if (!isset($_SESSION['id'])) {
echo '<a href="prihlaseni.php" class="login">Přihlášení</a>';
} else {
echo '<a href="index.php?odhlasit" class="login">Odhlásit</a>';
echo '<a href="#" class="login">'.htmlspecialchars($_SESSION['uzivatel_jmeno']).'</a>';
}
?>
</ul>
</nav>
</header>
<div id="centrovac">
<article>
<header>
<h1><?= htmlspecialchars($clanek['titulek']) ?></h1>
</header>
<section>
<?= $clanek['obsah'] ?>
</section>
<div class="cistic"></div>
</article>
</div>
<?php
if (!isset($_SESSION['id'])) {
echo 'Pro komentování článků se prosím <a href="prihlaseni.php">přihlašte</a>';
}
else
{
** if (isset($_POST['autor']) AND isset($_POST['obsah'])) {
$data_insert['autor'] = zabezpec($_POST['autor']);
$data_insert['datumvlozeni'] = DATE("Y-m-d");
$data_insert['obsah'] = zabezpec($_POST["obsah"]);
Db::insert("nkniha", $data_insert);**
}
}
?>
<div id="komentare">
<form action="" method="post" name="formular">
Vaše jméno:<br>
<input type="text" name="autor" maxlength="30" size="30" required pattern="[0-9A-Za-z]{3,}" title="Minimální délka jména musí být tři znaky." accesskey="j"><br>
Váš vzkaz:<br>
<textarea name="obsah" rows="7" cols="50" wrap="soft" required pattern="[0-9A-Za-z]{2,}" title="Vzkaz musí být delší více jak tři znaky"></textarea><br>
<input type="submit" value="Ulož do knihy">
</form>
</div>
<footer>
<a href="prihlaseni.php">Administrace</a>
</footer>
</body>
</html>
Nevím teď úplně teď, jakým způsobem bych měl získat to ID článků, jak jsi o tom mluvil... :/
ID článku bys měl mít v $clanek['clanky_id']. Pro získání komentářů by ti pak měl stačit dlaší dotaz:
$komentare = Db::queryAll('
SELECT *
FROM komentare
WHERE id_clanku_FK=?
', $clanek['clanky_id']);
Zkouším to tedy nejdříve jednoduše - vypsat všechny komentáře, které se v tabulce nkniha vyskytují takto:
$spojeni = Db::connect('127.0.0.1', 'sokolmilicincz1', 'root', ''); //pripojeni k db
$vysledek= mysqli_query($spojeni, "SELECT * FROM nkniha ORDER BY id DESC");
while ($radek=mysqli_fetch_array($vysledek)):
echo '<p><b>'.$radek['autor'].'</b> ';
echo '('.$radek['datumvlozeni'].')<br>';
echo $radek['obsah'].'</p>';
endwhile;
A vyhodí mi to chyby
mysqli_query() expects parameter 1 to be mysqli, null given in
mysqli_fetch_array() expects parameter 1 to be mysqli_result, null
Chápu asi správně, že ta druhá chyba souvisí s tou první a ta první říká, že proměnné nejsou definovány - což pravda není, si myslím. Proměnnou $spojeni definuji již na začátku
Vubec netestujes, jestli se pripojila db, jestli probehla spravne ta query a
pak zachazis s vysledkem jako kdyby vse bylo vzdy ok... spojeni uz mas na
zacatku souboru, tak mozna to mas 2x, pak v te query na cteni formularu mas
ORDER BY id, ale pises, ze PK se jmenuje clanky_id.
Pak k tomu formulari name=formular - chybi tam id clanku pro komentar - coz asi
pujde pouzit primo z promenne $clanek[id] :
$data_insert['id_clanku_FK'] = $clanek['clanky_id'];
Nevím proč najednou používáš mysqli a ne PDO wrapper, který jsi používal předtím. Zkus
$komentare = Db::queryAll('SELECT * FROM KOMENTARE');
foreach $komentare as $komentar {
echo $komentar['nazevSloupceKVypsani'];}
Jenom si tam doplň název toho sloupce tak jak ho máš pojmenovaný v databázi a pak by se ti měli vypsat všechny komentáře za sebou.
Je to tak
Už se to vypisuje pod sebou i dokonce podle těch cizích klíčů - akorát bych měl ještě dvě otázky
<?php
if (!isset($_SESSION['id'])) {
echo 'Pro komentování článků se prosím <a href="prihlaseni.php">přihlašte</a>';
}
else
{
if (isset($_POST['autor']) AND isset($_POST['obsah'])) {
$data_insert['autor'] = zabezpec($_POST['autor']);
$data_insert['datumvlozeni'] = DATE("Y-m-d");
$data_insert['obsah'] = zabezpec($_POST["obsah"]);
$data_insert['id_clanku_FK'] = $clanek['clanky_id'];
Db::insert("nkniha", $data_insert);
}
}
$komentare = Db::queryAll('SELECT * FROM nkniha WHERE id_clanku_FK=? ORDER BY id DESC', $clanek['clanky_id']);
foreach ($komentare as $komentar) {
echo '<p><b>'. $komentar['autor']. '</b> ';
echo '<p><b>'. $komentar['datumvlozeni']. '</b> ';
echo '<p><b>'. $komentar['obsah']. '</b> ';
}
'<form action="index.php" method="post" name="formular">
Vaše jméno:<br>
<input type="text" name="autor" maxlength="30" size="30" required pattern="[0-9A-Za-z]{3,}" title="Minimální délka jména musí být tři znaky." accesskey="j"><br>
Váš vzkaz:<br>
<textarea name="obsah" rows="7" cols="50" wrap="soft" required title="Vzkaz musí být delší více jak tři znaky"></textarea><br>
<input type="submit" value="Ulož do knihy">
</form>'
?>
</div>
Myslel jsem si, že ten if udělá to, že pokud není uživatel přihlášen, vypíše mu to pouze text "Pro komentování se prosím přihlašte " a pokud je přihlášen (čili ta podmínka není splněna), tak se mu zobrazí ten celý formulář. Teď to funguje tak, že se mu žádný formulář nezobrazí
Ad 1) Ten formulář můžeš zpracovat v jinym scriptu (to změníš v
atributu action ve formuláři) a pak to zase přesměrovat zpátky.
Ad 2) Před tim formulářem ti nejspíš chybí echo a navíc je až za ifem
takže se pak zobrazí vždycky. Musíš ho přesunout do toho else.
Ok, takže to mám zatím takhle
else
{
if (isset($_POST['autor']) AND isset($_POST['obsah'])) {
$data_insert['autor'] = $uzivatel['uzivatel_jmeno'];
$data_insert['datumvlozeni'] = DATE("Y-m-d");
$data_insert['obsah'] = zabezpec($_POST["obsah"]);
$data_insert['id_clanku_FK'] = $clanek['clanky_id'];
Db::insert("nkniha", $data_insert);
}
echo '<form action="index.php" method="post" name="formular">
Vaše jméno: ';
echo htmlspecialchars($_SESSION['uzivatel_jmeno']).'<br>
<input type=hidden name=';
$uzivatel = htmlspecialchars($_SESSION['uzivatel_jmeno']).'
><br>';
echo 'Váš vzkaz:<br>
<textarea name="obsah" rows="7" cols="50" wrap="soft" required></textarea><br>
<input type="submit" value="Ulož do knihy">
</form>';
}
$komentare = Db::queryAll('SELECT * FROM nkniha WHERE id_clanku_FK=? ORDER BY id DESC', $clanek['clanky_id']);
foreach ($komentare as $komentar) {
echo '<p><b>Autor: </b>'. $komentar['autor'];
echo 'Datum: '. $komentar['datumvlozeni'];
echo '<p><b>Text: </b>'. $komentar['obsah'];
}
?>
Nicméně úplně si nejsem teď jist, jak mám ze session předat databázi
toho uživatele - mám to takto $data_insert['autor'] =
$uzivatel['uzivatel_jmeno'];
a to mi nefunguje
<input type="hiden" name="jmeno" value=".$_SESSION['uzivatel_jmeno'].">
Snad nějak takhle, píšu z mobilu a nejsem si úplně jistej
Jo, to jo, já jsem myslel spíše co bude v tom zpracovani.php
Tohle tam bude?
session_start();
require('Db.php');
$spojeni = Db::connect('127.0.0.1', 'sokolmilicincz1', 'root', ''); //pripojeni k db
if (isset($_POST['autor']) AND isset($_POST['obsah'])) {
$data_insert['autor'] = Db::quote($_POST['autor']);
$data_insert['datumvlozeni'] = DATE("Y-m-d");
$data_insert['obsah'] = Db::quote($_POST["obsah"]);
$data_insert['id_clanku_FK'] = $clanek['clanky_id'];
Db::insert("nkniha", $data_insert);
Ten předchozí příspěvek ignoruj
Mám tedy na indexu takto napsán formulář
<?php
if (!isset($_SESSION['id'])) {
echo 'Pro komentování článků se prosím <a href="prihlaseni.php">přihlašte</a>';
}
echo '<form action="zpracovani.php" method="post" name="formular">
Vaše jméno: ';
echo htmlspecialchars($_SESSION['uzivatel_jmeno']).'<br>
<input type=hidden name="autor" value='.
htmlspecialchars($_SESSION['uzivatel_jmeno']).'
><br>';
echo 'Váš vzkaz:<br>
<textarea name="obsah" rows="7" cols="50" wrap="soft" required></textarea><br>
<input type="submit" value="Odeslat">
<input type="hidden" name="clanky_id" value='. $_SESSION[$clanek] .'
</form>';
$komentare = Db::queryAll('SELECT autor, datumvlozeni, obsah FROM nkniha WHERE id_clanku_FK=? ORDER BY id DESC', $clanek['clanky_id']);
foreach ($komentare as $komentar) {
echo '<p><b>Autor: </b>'. $komentar['autor'];
echo ' Datum: '. $komentar['datumvlozeni'];
echo '<p><b>Text: </b>'. $komentar['obsah'];
}
?>
A na zpracovani.php to vypadá takto:
<?php
session_start();
require('Db.php');
$spojeni = Db::connect('127.0.0.1', 'sokolmilicincz1', 'root', ''); //pripojeni k db
if (isset($_POST['autor']) AND isset($_POST['obsah'])) {
$data_insert['autor'] = Db::quote($_POST['autor']);
$data_insert['datumvlozeni'] = DATE("Y-m-d");
$data_insert['obsah'] = Db::quote($_POST["obsah"]);
$data_insert['id_clanku_FK'] = DB::quote($_POST["clanky_id"]);
Db::insert("nkniha", $data_insert);
header("index.php");
exit;
}
?>
V pořádku mi to zapisuje do databáze text i autora, ale nezapisuje si to id_clanku_FK (mám tam pravděpodobně chybu v tom předání mezi index.php a zpracovani.php)
Protože ho neposíláš tim formulářem. Udělej to stejně jako s tím jménem tzn. přes skrytej input. $clanek['clanky_id'] by měla bejt proměnná ve který je uložený.
Takže to mám takto:
else
{
echo '<form action="zpracovani.php" method="post" name="formular">
Vaše jméno: ';
echo htmlspecialchars($_SESSION['uzivatel_jmeno']).'<br>
<input type=hidden name="autor" value='.
htmlspecialchars($_SESSION['uzivatel_jmeno']).'
><br>';
echo 'Váš vzkaz:<br>
<textarea name="obsah" rows="7" cols="50" wrap="soft" required></textarea><br>
<input type="submit" value="Odeslat">
<input type=hidden name="clanky_id" value='.
htmlspecialchars($_SESSION['clanky_id;']).'
><br>';' </form>';
Ale stále mi to píše - přitom si myslím, že je to stejné jako to
jméno
Notice: Undefined index: clanky_id; in C:\xampp\htdocs\web\index.php on line
114
Ty tam máš $_SESSION['clanky_id'] (navíc tam máš středník, který tam být nemá), ale to ID článku načítáš někde na začátku společně se všema údajema toho konkrétního článku z databáze do pole $clanek. Tohle pole je asociativní, takže pomocí klíče, který se píše do těch hranatých závorek můžeš přistupovat k jednotlivým atributům toho článku. Ty chceš jeho ID a to je pod klíčem 'clanky_id' (aspoň podle těch kódů co jsi poslal dřív jsem tak usoudil), takže místo
$_SESSION['clanky_id;']
napiš
$clanek['clanky_id']
Jasně, už to chápu.
Ale v tom zpracovani.php to bude už s
DB::quote($_POST["clanky_id"])
Protože jsem to obdržel od formuláře.
Stále mi to nicméně nefunguje, do databáze se zapisuje id_clanky jako 0 - přitom pokud si tam vyhodím někde echo $clanek['clanky_id'], tak mi to píše id: 8 (což je správně)...
session_start()
$_SESSION["jmeno"] = "jmeno uzivatele po prihlaseni";
if (!empty($_SESSION["jmeno"])) {
//kod
}
Zkontroluj názvy proměnných. Konkrétně jestli v DB nemáš id_clanky a v kódu clanky_id
Nene, opravdu tam mám clanky_id. Když třeba nahradím $clanek['titulek'] pravě tím $clanek['clanky_id'], vypíše mi to správně ID toho článku. Nemohl by být problém v tom zpracování? Aktuálně ho mám takto:
<?php
session_start();
require('Db.php');
$spojeni = Db::connect('127.0.0.1', 'sokolmilicincz1', 'root', ''); //pripojeni k db
if (isset($_POST['autor']) AND isset($_POST['obsah'])) {
$data_insert['autor'] = Db::quote($_POST['autor']);
$data_insert['datumvlozeni'] = DATE("Y-m-d");
$data_insert['obsah'] = Db::quote($_POST['obsah']);
$data_insert['id_clanku_FK'] = DB::quote($_POST['clanky_id']);
Db::insert("nkniha", $data_insert);
header('Location: index.php');
exit;
}
?>
A takto je ten formulář
echo '<form action="zpracovani.php" method="post" name="formular">
Vaše jméno: ';
echo htmlspecialchars($_SESSION['uzivatel_jmeno']).'<br>
<input type=hidden name="autor" value='.
htmlspecialchars($_SESSION['uzivatel_jmeno']).'
><br>';
echo 'Váš vzkaz:<br>
<textarea name="obsah" rows="7" cols="50" wrap="soft" required></textarea><br>
<input type="submit" value="Odeslat">
<input type=hidden name="clanky_id" value='.
htmlspecialchars($clanek['clanky_id']). '
><br>';
'</form>';
Zkus do té podmínky dát tenhle kód
Db::query('
INSERT INTO nkniha (autor, datumvlozeni, obsah, id_clanku_FK)
VALUES (?, ?, ?, ?,)
',$_POST['autor'], DATE("Y-m-d"), $_POST['obsah'], $_POST['clanky_id']);
pak už mě napadá jen že je něco špatně v databázi. Jestli ti to nepůjde tak sem napiš jaký sloupečky máš v tabulce nkniha a jakýho jsou datovýho typu.
V tom zpracování máš if, tak co je vevnitř smaž kromě toho headeru a vlož tam to co jsem psal
Takže by to mělo být takto?
<?php
session_start();
require('Db.php');
$spojeni = Db::connect('127.0.0.1', 'sokolmilicincz1', 'root', ''); //pripojeni k db
if (isset($_POST['autor']) AND isset($_POST['obsah'])) {
Db::query('
INSERT INTO nkniha (autor, datumvlozeni, obsah, id_clanku_FK)
VALUES (?, ?, ?, ?,)
',$_POST['autor'], DATE("Y-m-d"), $_POST['obsah'], $_POST['clanky_id']);
header('Location: index.php');
exit;
}
?>
Vyhodí mi to error
Warning: PDO::prepare(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 2 in C:\xampp\htdocs\web\Db.php on line 42
Fatal error: Uncaught Error: Call to a member function execute() on boolean in C:\xampp\htdocs\zwa - project\Db.php:43 Stack trace: #0 C:\xampp\htdocs\zwa - project\Db.php(53): Db::executeStatement(Array) #1 C:\xampp\htdocs\web\zpracovani.php(10): Db::query('\r\n ...', 'admin', '2017-01-31', 'Ahoj', '8') #2 {main} thrown in C:\xampp\htdocs\webt\Db.php on line 43
Napiš jak vypadá ta tabulka v databázi do který to ukládáš.
Teď koukám, že na tom řádku s otazníkama je na konci jedna čárka navíc. Zkus jí odmazat jestli to nebylo tím.
Nevím, to co jsi používal ty je pro mě neznámý způsob práce s databází. Taky jsem začínal na zdejším NERS, kde se používá PDO a to používám pořád.
Ve zpracovani.php mas na konci funkci header, tak tam musis dat misto index jmeno souboru s clankem a doplnit ho o identifikaci aktualniho clanku
Zobrazeno 42 zpráv z 42.