Reputation: 33
I have tried to get a cleaner URL by adding a .htaccess file to my directory. However I have stumbled upon a small problem which I haven't been able to figure out yet how to solve. I provide an opportunity for my members to post content on my website. When posting the content, the title is saved and modified to be used to get a cleaner URL. For example
/dir/post.php?id=362 with the title [Hello friends] becomes ->
/dir/Hello-friends
My problem is how can I prevent that the same URL gets produced over and over again. I want that the following URLs with the same title, to get something added to it, like a number. For example
/dir/Hello-friends (The first post)
/dir/Hello-friends-2 (The second post, but here a number is added).
This is my php code
$conn = new mysqli($servername, $username, $password, $dbname);
if (mysqli_connect_error()) {
die("Database connection failed: " . mysqli_connect_error());
}
function php_slug($string)
{
$slug = preg_replace('/[^a-z0-9-]+/', '-', trim(strtolower($string)));
return $slug;
}
$title = mysqli_real_escape_string($conn,$title1);
$text1 = mysqli_real_escape_string($conn,$text0);
$text2 = mysqli_real_escape_string($conn,$text00);
$text3 = mysqli_real_escape_string($conn,$text000);
$text4 = mysqli_real_escape_string($conn,$text0000);
$text5 = mysqli_real_escape_string($conn,$text00000);
$text6 = mysqli_real_escape_string($conn,$text000000);
$pid = $_POST['pid'];
$post_title = $title;
$post_title = htmlentities($title);
$sql_titel = "SELECT post_title FROM posts WHERE title = '$title'";
$result_titel = mysqli_query($con, $sql_titel);
$resultsFound = mysqli_num_rows($result_titel);
if ($resultsFound > 0) {
$resultsFound++;
$post_title .= '-'.$resultsFound;
}
$sql = "INSERT INTO posts (title, text1, text2, text3, text4, text5, text6, post_title, pid)
VALUES ('$title', '$text1', '$text2', '$text3', '$text4', '$text5', '$text6', '".php_slug($post_title)."', '$pid')";
if ($conn->query($sql) === TRUE) {
echo "<script>alert('controlling post...!')</script>";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
}
Upvotes: 0
Views: 47
Reputation: 3789
A simple extension to your code is to use the number of rows returned, like this:
if($_POST['submit']) {
$post_title = htmlentities($title);
// !!! You should use parameterized queries here !!!
$sql_titel = "SELECT post_title FROM posts WHERE title = '$title'";
$result_titel = mysqli_query($con, $sql_titel);
// Using the number of rows returned as our collision ID:
$sameNameID = mysqli_num_rows($result_titel);
if ($sameNameID > 0) {
// Bump it up by 1 (so we essentially get 0,2,3,4,5..):
$sameNameID++;
// Add it to the post title:
$post_title .= '-'.$sameNameID;
}
}
Importantly, notice that it's checking the title
field rather than post_title
.
Also be aware that you're probably vulnerable to SQL injection. I.e. a random person on the internet could do whatever they want to your database. htmlentities
does not protect you from injection. You should use PDO instead.
But having said that, you might want to take inspiration from websites like StackOverflow itself, where a number (the article ID) is always present in the URL.
In StackOverflow's case, it's the ID which actually routes the request - this makes it possible to change the question (or title, in your case) later. For example, all of these link to this question:
https://stackoverflow.com/questions/41537052/
https://stackoverflow.com/questions/41537052/prevent-the-same-url-occuring
https://stackoverflow.com/questions/41537052/prevent-the-same-url-occuring-renamed
Upvotes: 1
Reputation: 43
If you want to add a random number:
if($_POST['submit']) {
$post_title = $title;
$post_title = htmlentities($title);
$sql_titel = "SELECT post_title FROM posts WHERE post_title = '$post_title'";
$result_titel = mysqli_query($con, $sql_titel);
if(mysqli_num_rows($result_titel) > 0) {
$post_title = $post_title . '-' . mt_rand(1, 1000);
}
}
Upvotes: 1