Создал свой однофайловый блог (php/mysql) - Обратная связь и инъекции?

Это моя первая попытка написать очень простой (однофайловый) блог-движок, построенный на PHP и MySQL. Я хочу сделать все просто и не хочу включать сотни файлов, классов и так далее, потому что я просто хочу опубликовать какой-то текст и все. Мне не нужны плагины, изменяющиеся шаблоны, API или что-то в этом роде. Сценарий теперь работает и работает нормально, но я действительно новичок и только начал с php/mysql. :)

Итак, я хочу получить отзыв, что я сделал не так, что может быть слишком сложно или есть ли возможность инъекций или чего-то подобного? Любая помощь и отзывы приветствуются (и извините за мой плохой английский!).

Я включил некоторые комментарии, чтобы было легче следовать моим мыслям:

<?php
///////////////////////////////////////////////////// BASE

// Whats the name of the blog and how many recent articles should shown on the front
$blogname = 'The basic blogname';
$anzahl = '3';

// Alright, let's connect to the database 
include_once 'include/connect.php';

// I use this to generate german date (e.g.: March --> März)
setlocale (LC_ALL, '[email protected]', 'de_DE.utf8', 'de.utf8', 'ge.utf8');

///////////////////////////////////////////////////// START >>> IF

// As we using htaccess with modrewrite, we want to know, what page-name the user requested
if (isset($_GET['slug'])) {

// I'm not sure, if it makes sense (mysqli_/mysql_?) to avoid injections? Any help is welcome!
$blog = mysql_escape_string($_GET['slug']);

// Alright, now we check the database and ask if the sitename exist and if the status is "online" (published/draft)
$result = mysqli_query($con,"SELECT * FROM entries WHERE slug='$blog' AND status = 'ONLINE'");

// We call the result and check, if there is a article in the database
$num_results = mysqli_num_rows($result); 
if ($num_results > 0){ 

// We now also include the header-file, because there we also have the $title-variable for the site / browsertab
include 'header.php';
include_once 'markdown.php';

// Create variables from the database-fields, also convert the content with markdown
while($row = mysqli_fetch_array($result)){
$title = $row['title'];
$content = $row['content'];
$my_html = Markdown($content);
$date = $row['date'];
    $date = strftime('%d. %B %G', strtotime($date));

// and final: show the article on the website
echo '<h2>' . $title . '</h2>';
echo '<div id="date">' . $date . '</div>';
echo '<div id="content">' . $my_html . '</div>';
echo '<div id="link"><a href="/simple/"' . $slug . '">Back to front-page</a></div>';

// we also inlucde the footer, so that we have a complete page - header/content/footer
include 'footer.php';
}

///////////////////////////////////////////////////// ELSE  >>>

// but if there is NO entry in the database with this pagename...
} else {

// again we need the header
include 'header.php';

// then we say:
echo '<h2>Error</h2>';
echo '<div id="content">There is no article with this name!</div>';
echo '<div id="link"><a href="/simple/"' . $slug . '">Back to front</a></div>';

// and include the footer
include 'footer.php';
}

///////////////////////////////////////////////////// ELSE >>>

// But if the user just open the blog and don't request a name, we want to show him the last articles (3 - see top)...
} else {

// So again we call the database and request the last published entries and sort them, limited by the amount of given entries
$result = mysqli_query($con,"SELECT * FROM entries WHERE status = 'ONLINE' ORDER BY id DESC LIMIT $anzahl");

// Again include header and markdown
include 'header.php';
include_once "markdown.php";

// We generate variables from the datebase during the loop, also convert the excerpt with markdown
while($row = mysqli_fetch_array($result)){ 
$title = $row['title'];
$slug = $row['slug'];
$excerpt = $row['excerpt'];
$my_html = Markdown($excerpt);
$date = $row['date'];
 $date = strftime('%d. %B %G', strtotime($date));

// And publish them on the website
echo '<h2><a href="/simple/' . $slug . '">' . $title . '</a></h2>';
echo '<div id="date">' . $date . '</div>';
echo '<div id="content">' . $my_html . '</div>';
echo '<div id="link"><a href="/simple/' . $slug . '">Read more...</a></div>';

}
// Last time, we include the footer again.
include 'footer.php';
}

///////////////////////////////////////////////////// <<< FINISH
?>

Спасибо - и да, я хочу учиться! :))


person user3454869    schedule 24.03.2014    source источник
comment
Почему вы используете расширение mysql_escape_string, а также расширение mysqli для своей БД? Придерживайтесь только одного из них. Кроме того, я настоятельно рекомендую использовать prepared statements вместо прямой конкатенации внутри запросов. Это значительно снижает вероятность SQL-инъекций.   -  person Tularis    schedule 24.03.2014
comment
Возможно, вы захотите включить разбивку на страницы на свою первую страницу или предоставить архив для блога.   -  person aurbano    schedule 24.03.2014
comment
Хочу сделать рукописный архив... Пишу не каждый день, поэтому достаточно просто вставить (скопировать) записи (заголовки и ссылку) в статью, с названием архив. :)   -  person user3454869    schedule 24.03.2014


Ответы (1)


Используя библиотеку абстракций SQL и шаблоны, вы можете сделать свой код более аккуратным.

$sql = "SELECT * FROM entries WHERE slug=?s AND status = 'ONLINE'";
$row = $db->getRow($sql, $_GET['slug']);
if ($row) { 
    $title   = $row['title'];
    $content = Markdown($row['content']);
    $date    = strftime('%d. %B %G', strtotime($row['date']));
    $tpl = 'single.tpl.php';
    include 'main.tpl.php'
} else {
    include '404.php';
}

и для списка

$sql  = "SELECT * FROM entries WHERE status = 'ONLINE' ORDER BY id DESC LIMIT ?i";
$data = $db->getAll($sql, $anzahl);
$tpl = 'list.tpl.php';
include 'main.tpl.php'
person Your Common Sense    schedule 24.03.2014
comment
Спасибо, присмотрюсь к этой идее...! :) - person user3454869; 24.03.2014
comment
Вот пример этого шаблона: stackoverflow.com/a/5183401/285587 - person Your Common Sense; 24.03.2014