3
votes

I have php application which have to be partially rewritten because of the customer request to have SEO frendly urls.

My links are as follow:

www.mysite.com/articles_en.php?artid=89, where I will have to change the url in this:

www.mysite.com/articleTitle

Then I have this url:

www.mysite.com/halls.php?fairid=65 which should become

www.mysite.com/fairname

And www.mysite.com/companies.php?fairid=65&hallid=23 which should become

www.mysite.com/fairname/hallname

You get the idea.

I need a help with the approach. Is it good idea in the tables of the fairs, halls and articles to create a field in the table named for example alias and then to attempt to rewrite the url? Anyone can help me with the steps how to create this script, or to point me to better approach?

I am good at php, but not good at all with regular expressions, so I will be lost on the .htaccess part.

Any help will be deeply appreciated.

Regards, Zoran

2

2 Answers

5
votes

.htaccess something like:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*) /url_rewrite.php?path=$1 [L,QSA]

database table something like:

+------+--------+
| path | url    |
+------+--------+

With the path as the PRIMARY KEY.

And a PHP script called url_rewrite.php that takes the path parameter from the URL, does a lookup on the database to find the real url and performs an HTTP 301 redirect.

The url_rewite.php page might look something like this (this is pretty much boilerplate code and will need adjusting to fit your requirements - realistically we shouldn't be using mysql_query() any more either - PDO or MySQLi are better and aren't well, deprecated).

<?php
// -- database connection and any intialisation stuff you may have might go here ...

//get the path
$sPath = !empty($_GET['path']);

// -> error trapping for empty paths here

//retrieve the "real" url from the database
$dbQry = mysql_query("SELECT `url` FROM `seourls` WHERE `path` = '" . mysql_real_escape_string($sPath) . "' LIMIT 0, 1");

// -> error trapping here for query errors here

$dbResponse = mysql_fetch_row($dbQuery);

// -> error trapping here for empty recordsets here

$sRealPath = $dbResponse[0]; # which might be "/articles_en.php?artid=89"

//redirect
header("HTTP/1.1 302 Found");
header("Status: 302 Found"); # for Chrome/FastCGI implementation
header("Location: {$sRealPath}");
die();

?>
1
votes

I suggest you to carefully look at the pretty URL of this question on SO and get some idea. Needless to add that SO questions rank very high on Google search results. So taking a clue from SO URL conventions, I suggest you these 3 pretty URL formats:

  1. /articles/89/mytitle for /articles_en.php?artid=89
  2. /halls/65/sometitle for /halls.php?fairid=65
  3. /companies/65-23/company for /companies.php?fairid=65&hallid=23

Now create 3 lookup tables articles, halls and companies like this:

Table: articles:

+-------+-------+
| artid | title |
+-------+-------+

Table halls:

+--------+-------+
| fairid | title |
+--------+-------+

Table companies:

+--------+--------+------+
| fairid | hallid | name |
+--------+--------+------+

Now for above 3 pretty URL handling add this code in your .htaccess under $DOCUMENT_ROOT:

RewriteCond %{QUERY_STRING} ^artid=\d+$ [NC]
RewriteRule ^articles_en\.php/?$ router.php?handler=article [L,NC,QSA]
RewriteRule ^articles/(\d+)/?(.*)$ router.php?handler=article&artid=$1&title=$2 [L,NC,QSA]

RewriteCond %{QUERY_STRING} ^fairid=\d+$ [NC]
RewriteRule ^halls\.php/?$ router.php?handler=hall [L,NC,QSA]
RewriteRule ^halls/(\d+)/?(.*)$ router.php?handler=hall&fairid=$1&title=$2 [L,NC,QSA]

RewriteCond %{QUERY_STRING} ^fairid=\d+&hallid=\d+$ [NC]
RewriteRule ^companies\.php/?$ router.php?handler=company [L,NC,QSA]
RewriteRule ^companies/(\d+)-(\d+)/?(.*)$ router.php?handler=company&fairid=$1&hallid=$2&name=$3 [L,NC,QSA]

Finally have your router.php code like this: (sample code)

<?php
// TODO: Add sanitization checks for presence of required parameters e.g. handler and lookup failures
$handler = mysql_real_escape_string($_GET['handler']);
switch ($handler) {
   case 'article':
      $artid = mysql_real_escape_string($_GET['artid']);
      $title = mysql_real_escape_string($_GET['title']);
      if (empty($title)) {
          #header("HTTP/1.1 301 Moved Permanently");
          header("Location: /articles/$artid/" . lookupArticle($artid));
          exit;
      }
      else
         require_once("articles_en.php");
   break;
   case 'hall':
      $fairid = mysql_real_escape_string($_GET['fairid']);
      $title = mysql_real_escape_string($_GET['title']);
      if (empty($title)) {
          #header("HTTP/1.1 301 Moved Permanently");
          header("Location: /halls/$fairid/" . lookupHall($fairid));
          exit;
      }
      else
         require_once("halls.php");
   break;
   case 'company':
      $fairid = mysql_real_escape_string($_GET['fairid']);
      $hallid = mysql_real_escape_string($_GET['hallid']);
      $name = mysql_real_escape_string($_GET['name']);
      if (empty($name)) {
          #header("HTTP/1.1 301 Moved Permanently");
          header("Location: /companies/$fairid-$hallid/" . lookupCompany($fairid, $hallid));
          exit;
      }
      else
         require_once("companies.php");
   break;
}
function lookupArticle($artid) {
   // $title = mysql_result(mysql_query("SELECT title FROM articles WHERE artid=$artid"), 0, "title");
   static $articles = array(89 => 'Title\'s A', 90 => 'Title, 1B', 91 => '@Article= C');
   return normalize($articles[$artid]);
}
function lookupHall($fairid) {
   // $title = mysql_result(mysql_query("SELECT title FROM halls WHERE fairid=$fairid"), 0, "title");
   static $halls = array(65 => 'Hall+ A', 66 => 'Hall B', 67=> 'Hall C');
   return normalize($halls[$fairid]);
}
function lookupCompany($fairid, $hallid) {
   // $title = mysql_result(mysql_query("SELECT name FROM companies WHERE fairid=$fairid and hallid=$hallid"), 0, "name");
   static $companies = array('65-23' => 'Company% A', '66-24' => 'Company B', '67-25' => '(Company) C');
   return normalize($companies[$fairid .'-'. $hallid]);
}
function normalize($str) {
   return  preg_replace(array('#[^\pL\d\s]+#', '#\s+#'), array('', '-'), strtolower($str));
}
?>

Once you verify that it's working fine uncomment 301 Moved Permanently lines to get better SEO results.

PS: I have used normalize PHP function to get all URL text in lowercase, cleaning up special characters and converting all spaces to hyphens.