2

I have a problem concerning php,mysql, apache's mod_rewrite and a slug function for friendly urls.

I have a table in mysql with series.
This table has an auto_increment ID and an unique_key string that is the name of the serie.
What I want to do is:

The user could write something like

series/name-of-a-serie
(because I would prefer to use the unique string more than IDs in this case), and I would get something like
series.php?serieName=name-of-a-serie
but the name I have in the database is
"name of a serie"

then I was thinking about revert the slugged string to take back the original... but then I have other problem:

If I have a function that replace white spaces with hyphens, I would have problems with, for example, the string
"this - name"
,because if I revert the process, I would get
"this   name"
and that's not the original name.
Any ideas?

Thanks id advance and sorry because i'm not english and I can't express myself as well as I would like.

5 Answers5

2

You could always use a second column in your database where you store the already clean up version of the series name, like removing all special characters, substitute spaces with dashes and so on.

When using that link, you just have to check the database for that prepared text and get the real entry.

As far as i know wordpress does is exactly this way. They store a url-friendly post_name with every post that you can use. By passing all urls through a script (via .htaccess) they can check for all those variants and show the corresponding pages.

Please see How to rewrite urls in wordpress for some details.

some code to clean up your titles might be like:

// Define all the characters you want to get rid of / replace
$arrBadChars = array('Ä', 'Ö', 'Ü', 'ä', 'ö', 'ü', 'ß', ' ', '_', '~', '-/', chr(10), chr(13));

// define the corresponding characters/texts for the above ones
$arrGoodChars = array ('ae', 'oe', 'ue', 'ae', 'oe', 'ue', 'ss', '-', '', '/', '', '','');

// Replace the bad with the good ones
$strNewTitle = str_replace($arrBadChars, $arrGoodChars, html_entity_decode($strTitle));

// simply paranoia, to remove everything else you might not have thought of above...
$strNewTitle = preg_replace('#[^[:space:]~a-zA-Z0-9_-]#', '', $strNewTitle);

the $strNewTitle is the one you could save and use for your URL.

Olli
  • 1,708
  • 10
  • 21
0

If you are sure that you won't have any - in the Database Title, simply do that:

$id=str_replace("-"," ",$_GET['id']);

$stm=$db->prepare("SELECT * FROM movie WHERE movie_title=:movie");
$result=$stm->execute(array(":movie"=>$id))->fetchAll();

You can also use any other replacement character, like _ in the URL.

This way you can keep friendly URLs but also maintain your Database Titles. Another way which I have seen sometimes is to create a second database field which stores the URL.

D. Schalla
  • 655
  • 4
  • 9
0

The solution to this problem is to use numeric identifers in the URL. You said the table already has been implemented this way, so it is easy to do. The basic concept is to extract the numeric id from the url, and then verify that the slug is equal to the slug in your database. If not, then redirect to the correct one (301). This is the most popular pattern that I've recognized.

Your URL will look like this:

http://example.com/12345/name-of-a-serie

However you get that ID is up to you, but mod_rewrite, will work.

   $id   = $_GET['id'];
   $slug = $_GET['slug'];

   // verify the id 
   $record = getRecord($id);
   if(! $record) exit;
   if($record->slug != $slug) {
     $slug = $record->slug;
     // these values are NOT arbitary, because we have validated the record
     // against the arbitrary ID first, so we're safe. as long as your
     // internal API is using prepared statements.
     header("Location: /$id/$slug");
     exit;
   } 
Ryan
  • 14,392
  • 8
  • 62
  • 102
0

If you want to revert from a slugged string back to the original string, you have to ensure that the slugging function is bijective, then write the reverse function.

BTW, slugging functions can't be bijective since they map an extended charset (the one of your language) to a restricted charset (the one used in urls).

Hopefully, if the slug has a UNIQUE constraint in your table, you can use it in your PHP code as a key to retrieve your item, thus its name.

ChristopheBrun
  • 1,237
  • 7
  • 22
0

Thank you very much.
I have now an idea of what I could do.

Every time I Insert a new tittle in DB, I would check the original name.
If there is already an entry, then that means that this movie has already in the DB,
If not, I would insert the original tittle and the slugged one.

In the case that "A serie" and "A-serie" were a completely different series but the slugged tittle were the same

"A serie" -> "A-serie"
"A-serie" -> "A-serie"

then I would only have to change the slugged tittle, something like:

ID      |  original name  |   slugged name
----------------------------------------------
201     | A name          | a-name
----------------------------------------------
202     | A-name          | a-name1

Being the slugged name the one that the user would write in the URL.

The URLs would be something like:

series/a-serie
series/a-serie1