Hej, napisałem taką prostą witrynę w PHP, będę wdzięczny za code review :-)
lib/app_init.php
<?php
declare(strict_types=1);
require_once 'config/db.php';
try {
$db_conn = new PDO(PDO_DSN, DB_USER, DB_PASS);
$db_conn->query('ALTER TABLE IF EXISTS author DROP FOREIGN KEY fk_author_role_id');
$db_conn->query('ALTER TABLE IF EXISTS post DROP FOREIGN KEY fk_post_author_id');
foreach (['author_role', 'author', 'post'] as $db_table) {
$db_conn->query("DROP TABLE IF EXISTS $db_table");
}
$stmt = 'CREATE TABLE IF NOT EXISTS author_role (' .
'id int NOT NULL PRIMARY KEY AUTO_INCREMENT, ' .
'role_name varchar(100) UNIQUE NOT NULL)';
$db_conn->query($stmt);
$stmt = 'INSERT INTO author_role (role_name) VALUES ' .
"('Administrator'), ('Moderator'), ('User')";
$db_conn->query($stmt);
$stmt = 'CREATE TABLE IF NOT EXISTS author (' .
'id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, ' .
'username varchar(255) UNIQUE NOT NULL, ' .
'passwd varchar(255) NOT NULL, ' .
'email varchar(255) UNIQUE NOT NULL, ' .
'created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, ' .
'role_id int(11) NOT NULL, ' .
'FOREIGN KEY fk_author_role_id (role_id) REFERENCES author_role (id))';
$db_conn->query($stmt);
$stmt = 'INSERT INTO author (username, passwd, email, role_id) ' .
"VALUES ('lester29', 'test', 'lester29@lester29.org', 1)";
$db_conn->query($stmt);
$stmt = 'CREATE TABLE IF NOT EXISTS post ( ' .
'id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, ' .
'title varchar(255) UNIQUE NOT NULL, ' .
'content text NOT NULL, ' .
'author_id int(11) NOT NULL, ' .
'created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, ' .
'updated_at DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP, ' .
'FOREIGN KEY fk_post_author_id (author_id) REFERENCES author (id))';
$db_conn->query($stmt);
echo 'Successfully created required tables.';
} catch (PDOException $ex) {
echo "An error occurred while initializing database: " . $ex->getMessage();
}
lib/user.php
<?php
declare(strict_types=1);
require_once 'config/db.php';
function userExists(string $username, string $password): bool
{
try {
$db_conn = new PDO(PDO_DSN, DB_USER, DB_PASS);
$stmt = 'SELECT username, passwd ' .
'FROM author ' .
"WHERE username = ? " .
"AND passwd = ?";
$query = $db_conn->prepare($stmt);
$query->execute([$username, $password]);
return $query->rowCount() > 0;
} catch (PDOException $ex) {
die('An error occurred at auth_user function: ' . $ex->getMessage());
}
}
footer.php
<footer>
<p>This website is owned by lester29</p>
</footer>
</body>
</html>
header.php
<?php
session_start();
if (!isset($_SESSION['auth_user'])) {
$_SESSION['auth_user'] = false;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>lester29</title>
</head>
<body>
<header>
<h1>lester29</h1>
<p>My first website :-)</p>
<?php if ($_SESSION['auth_user']): ?>
<p>You're logged as <?php echo $_SESSION['username']; ?>.</p>
<?php endif; ?>
</header>
<section>
<nav>
<ul>
<li><a href="index.php">Home</a></li>
<?php if ($_SESSION['auth_user']): ?>
<li><a href="transact_user.php?action=logout">Log out</a></li>
<?php else: ?>
<li><a href="login.php">Login</a></li>
<?php endif; ?>
</ul>
</nav>
</section>
<main>
index.php
<?php
require_once 'lib/user.php';
require_once 'header.php';
?>
<section>
<h2>Posts</h2>
<?php
try {
$db_conn = new PDO(PDO_DSN, DB_USER, DB_PASS);
$stmt = 'SELECT post.title AS post_title, ' .
'author.username AS post_author, ' .
'post.created_at AS post_created, ' .
'post.content AS post_content ' .
'FROM post ' .
'LEFT JOIN author ' .
'ON post.author_id = author.id';
/** @var PDOStatement $posts */
$posts = $db_conn->query($stmt);
while ($post = $posts->fetch(PDO::FETCH_ASSOC)) {
?>
<article>
<h3><?php echo $post['post_title']; ?></h3>
<p>Created at <?php echo $post['post_author']; ?> by <?php echo $post['$post_author']; ?></p>
<p>
<?php echo htmlspecialchars(nl2br($post['post_content'])); ?>
</p>
</article>
<?php
}
if ($posts->rowCount() == 0) {
echo '<p>No such any posts.</p>';
}
} catch (PDOException $ex) {
echo '<p>An error occurred during retrieving posts: ';
echo $ex->getMessage();
echo '</p>';
}
?>
</section>
<?php
require_once 'footer.php';
login.php
<?php
require_once 'header.php';
?>
<section>
<?php if ($_SESSION['auth_user']): ?>
<h2>Information</h2>
<p>
It seems like you're already logged in.
Do you want to <a href="transact_user.php?action=logout">log out</a>?
</p>
<?php else: ?>
<h2>Sign in</h2>
<form action="transact_user.php?action=login" method="post">
<p>
<label for="username">Username</label>
<input type="text" name="username" id="username">
</p>
<p>
<label for="password">Password</label>
<input type="password" name="password" id="password">
</p>
<p>
<input type="submit" name="submit_login" value="Login">
</p>
</form>
<?php endif; ?>
</section>
<?php
require_once 'footer.php';
transact_user.php
<?php
require_once 'header.php';
require_once 'config/db.php';
require_once 'lib/user.php';
?>
<section>
<?php
if (!isset($_GET['action'])) {
?>
<h2>Error</h2>
<p>No action chosen for user.</p>
<?php
} else {
switch ($_GET['action']) {
case 'login':
if (isset($_POST['submit_login'])) {
$username = $_POST['username'];
$password = $_POST['password'];
if (userExists($username, $password)) {
$_SESSION['username'] = $username;
$_SESSION['auth_user'] = true;
?>
<h2>Success</h2>
<p>You're logged in.</p>
<?php
} else {
$_SESSION['auth_user'] = false;
?>
<h2>Login failed</h2>
<p>Incorrect login or password. <a href="login.php">Try again</a></p>
<?php
}
}
break;
case 'logout':
if ($_SESSION['auth_user']) {
$_SESSION['auth_user'] = false;
?>
<h2>Success</h2>
<p>You're successfully log out!</p>
<?php
} else {
?>
<h2>Information</h2>
<p>
It seems you're not logged in. Do you want to
<a href="login.php">log in</a> again?
</p>
<?php
}
break;
default:
?>
<h2>Error</h2>
<p>Invalid action <code><?php echo $_GET['action']; ?></code>.</p>
<?php
}
}
?>
</section>
<?php
require_once 'footer.php';