Problem with mod_rewrite and replacing spaces in URL

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David

    Problem with mod_rewrite and replacing spaces in URL

    Sent this to alt.php a couple of days back, but doesn't look like I'll
    get an answer, so trying here.

    I'm trying to convert a script to use friendly URLs, I've done this
    before, but my PHP skills are quite basic so far, far from proficient
    at this.

    ..htaccess file-

    DirectoryIndex default.php index.asp index.html index.htm index.php

    Options +FollowSymLinks
    RewriteEngine on

    RewriteRule ^([^/]+)/Artist/([^/]+)/$ search.php?typ= $1&search=$2 [L]
    RewriteRule ^([^/]+)/Artist/([^/]+)/([^/]+)/$
    search.php?typ= $1&search=$2&pa ge=$3 [L]

    RewriteRule ^([^/]+)/$ default.php?typ =$1 [L]
    RewriteRule ^([^/]+)/([^/]+)/$ default.php?typ =$1&page=$2 [L]

    RewriteRule ^([^/]+)/([^/]+)/$ default.php?typ =$1&cat=$2 [L]
    RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$
    default.php?typ =$1&cat=$2&page =$3 [L]

    RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$
    default.php?typ =$1&cat=$2&sct= $3 [L]
    RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$
    default.php?typ =$1&cat=$2&sct= $3&page=$4 [L]



    Each set of rules creates these URLs-

    example.com/$1/Artist/$2/
    example.com/$1/Artist/$2/$3/ ($3 is a page number)

    example.com/$1/
    example.com/$1/$2/ ($2 is a page number)

    example.com/$1/$2/
    example.com/$1/$2/$3/ ($3 is a page number)

    example.com/$1/$2/$3/
    example.com/$1/$2/$3/$4/ ($4 is a page number)

    It works.

    However when variable $2 or $3 (when not a page number), for example
    $2 of-

    example.com/$1/Artist/$2/
    example.com/$1/Artist/$2/$3/ ($3 is a page number)

    Includes a space I can't get the PHP script to create an hyphenated
    version that works even though at browser level the hyphen is there
    (click on it, but the right page does not load).

    So a starting URL like

    example.com/ringtone/Artist/Britney%20Spear s/ (works)

    Converted to-

    example.com/ringtone/Artist/Britney-Spears/ (doesn't work)

    Using a function (see later) that converts spaces to hyphens doesn't
    load what I see at example.com/ringtone/Artist/Britney%20Spear s/
    instead I see a 404 error page (blank script page) and I don't
    understand why (I've used the function before)

    Using urlencode instead of the function replaces spaces with + so I
    see

    example.com/ringtone/Artist/Britney+Spears/ (works)

    but it's not the format I want and there are other characters I'd like
    to remove including ( ) ! &.

    So what is wrong with this function (which I don't fully understand
    BTW)-



    function text2url( $string ){
    $string = ltrim($string);
    // remove unnecessary spaces and make everything lower case
    $string = preg_replace( "/ +/", " ", strtolower($str ing) );

    // special rule for dashes, I think it looks nicer :-p
    $string = str_replace(' - ', '-', $string);


    // removing a set of reserved characters (rfc2396: ; / ? : @ & = + $
    ,)
    $string =
    str_replace(arr ay(';','/','?',':','@',' &','=','+','$', ',','#'), '',
    $string);

    // replace some characters to similar ones (more readable uris)
    $search = array(' ', 'ä', 'ö', 'ü','ë','ï','é' ,'è','à','ç',);
    #$replace = array('_','ae', 'oe','ue','e',' i','e','e','a', 'c');
    $replace = array('-','ae','oe','ue ','e','i','e',' e','a','c');
    $string = str_replace($se arch, $replace, $string);

    // remove everything we didn't so far...
    $string = preg_replace("/[^a-z0-9_-]/", "", $string);

    // urlencode everything, in case we missed something ;-)
    return urlencode($stri ng);
    }



    When I use it like this

    $artist2 = text2url($artis t);

    echo'<a href="'.$site_u rl.''.$typ.'/Artist/'.$artist2.'/1/"><img
    src="'.$site_ur l.'button_more_ from.gif" alt="All Truetones from
    '.$artist.'" border="0"></a>'.$artist.' ';


    It converts spaces to hyphens, but within a browser it fails.


    This works but adds +

    echo'<a
    href="'.$site_u rl.''.$typ.'/Artist/'.urlencode($ar tist).'/1/"><img
    src="'.$site_ur l.'button_more_ from.gif" alt="All Truetones from
    '.$artist.'" border="0"></a>'.$artist.'' ;


    Thanks in advance for any help as I'm stumped.

    David
    --
    SEO Tutorial http://www.seo-gold.com/tutorial/
    More Earnings Blog http://www.morearnings.com/
  • Jeremy

    #2
    Re: Problem with mod_rewrite and replacing spaces in URL

    David wrote:
    Sent this to alt.php a couple of days back, but doesn't look like I'll
    get an answer, so trying here.
    >
    I'm trying to convert a script to use friendly URLs, I've done this
    before, but my PHP skills are quite basic so far, far from proficient
    at this.
    >
    <snip>

    One thing I immediately noticed: your text2url function lowercases
    everything, but your Britney Spears example is capitalized.

    At a more fundamental level, how are you using the URL to lookup the
    artists themselves? This is where the problem lies. You are going to
    have to do the same transformation to the artist name when looking up
    the artist that you did when creating the friendly URL.

    For example, here is a simple scheme which lowercases the URL and
    replaces spaces with dashes, and the corresponding database lookup.

    ..htaccess:
    -----------------------------------------
    RewriteRule ^artists/([^/]+) /artists.php?art istName=$1
    -----------------------------------------


    URL creation:
    -------------------------------------------
    $url = "/artists/" . strtolower(str_ replace(" ", "-", $artistName));
    -------------------------------------------


    Artist lookup (assumes PDO/PGSQL):
    ------------------------------------
    $artist_query = $pdo->prepare("selec t * from artists where
    LOWER(REPLACE(a rtist_name, ' ', '-')) = :artistName");

    $artist_query->bindParam(":ar tistName", $_GET["artistName "]);
    $artist_query->execute();
    $artist = $artist_query->fetch();
    -----------------------------

    This code will obviously not work verbatim; it's just an example of how
    you need perform the same transformation on artist names when you're
    looking them up, or the comparison won't work. Notice how in my SQL
    query I'm comparing the passed-in artist name (in the form of
    "britney-spears") with the artist name in the database (in the form of
    "Britney Spears") only AFTER I transform the database version to the
    proper format - LOWER(REPLACE(. ..)) transforms "Britney Spears" to
    "britney-spears", making the comparison successful.

    Jeremy

    Comment

    • David

      #3
      Re: Problem with mod_rewrite and replacing spaces in URL

      On Tue, 17 Oct 2006 11:55:44 -0700, Jeremy <jeremy@pinacol .comwrote:
      >David wrote:
      >Sent this to alt.php a couple of days back, but doesn't look like I'll
      >get an answer, so trying here.
      >>
      >I'm trying to convert a script to use friendly URLs, I've done this
      >before, but my PHP skills are quite basic so far, far from proficient
      >at this.
      >>
      ><snip>
      >
      >
      >One thing I immediately noticed: your text2url function lowercases
      >everything, but your Britney Spears example is capitalized.
      I'd tried it with and without lowercase, so that wasn't a major
      problem. Don't mind if the URls have upper case characters.
      >At a more fundamental level, how are you using the URL to lookup the
      >artists themselves? This is where the problem lies. You are going to
      >have to do the same transformation to the artist name when looking up
      >the artist that you did when creating the friendly URL.
      >
      >For example, here is a simple scheme which lowercases the URL and
      >replaces spaces with dashes, and the corresponding database lookup.
      >
      >.htaccess:
      >-----------------------------------------
      >RewriteRule ^artists/([^/]+) /artists.php?art istName=$1
      >-----------------------------------------
      >
      >
      >URL creation:
      >-------------------------------------------
      >$url = "/artists/" . strtolower(str_ replace(" ", "-", $artistName));
      >-------------------------------------------
      I've tried similar and it's worked fine with other sites, just this
      one fails!

      Tried a simpler function-

      function safeurl($name){
      $retVal = str_replace('/',' ',$name);
      $retVal = str_replace('-',' ',$retVal);
      return $retVal;
      }


      To replace a / with a space and spaces with a -

      Example code-


      $viewart = '<div style="clear:bo th; text-align:right;
      padding-right:15px;">
      <h4>View All <a
      href="'.$site_u rl.''.safeurl($ typ).'/Artist/'.safeurl($arti st).'/1/">Polyphoni c
      Ringtones by '.$artist.'</a></h4>
      </div>';
      }
      ?>

      <?php echo''.$viewart .'';?>


      It works at code level, the \ and spaces are removed/replaced with -
      when viewed in a browser but when clicking links they fail.


      This code on the other hand works fine-

      $viewart = '<div style="clear:bo th; text-align:right;
      padding-right:15px;">
      <h4>View All <a
      href="'.$site_u rl.''.urlencode ($typ).'/Artist/'.urlencode($ar tist).'/1/">Polyphoni c
      Ringtones by '.$artist.'</a></h4>
      </div>';
      }
      ?>

      <?php echo''.$viewart .'';?>


      This as expected replaces spaces with a + and characters like / are
      replaced with %2F etc... the + URLs work but the / and some other
      characters don't, so partial success.

      I don't understand why the function fails?
      >
      >Artist lookup (assumes PDO/PGSQL):
      >------------------------------------
      >$artist_quer y = $pdo->prepare("selec t * from artists where
      >LOWER(REPLACE( artist_name, ' ', '-')) = :artistName");
      >
      >$artist_quer y->bindParam(":ar tistName", $_GET["artistName "]);
      >$artist_quer y->execute();
      >$artist = $artist_query->fetch();
      >-----------------------------
      Does it make any difference that most of the data is from a CSV file
      (no database)?

      The code to get data is-

      $row=0;
      $file = fopen("$filepat h", "r");

      while (($data = fgetcsv($file, 1000, ";")) !== FALSE) {
      if ($sct==''){
      if ($data[$DATA["typ"]]==$typ and $data[$DATA["cat"]]==$cat or
      $data[$DATA["typ"]]==$typ and $cat==''){

      $row++;

      $nam[$row] = $data[$DATA["nam"]];
      $dsc[$row] = $data[$DATA["dsc"]];
      $dsl[$row] = $data[$DATA["dsl"]];
      $pth[$row] = $data[$DATA["pth"]];
      $ppl[$row] = $data[$DATA["ppl"]];

      } }

      if ($sct>''){
      if ($data[$DATA["typ"]]==$typ and $data[$DATA["cat"]]==$cat and
      $data[$DATA["sct"]]==$sct){

      $row++;

      $nam[$row] = $data[$DATA["nam"]];
      $dsc[$row] = $data[$DATA["dsc"]];
      $dsl[$row] = $data[$DATA["dsl"]];
      $pth[$row] = $data[$DATA["pth"]];
      $ppl[$row] = $data[$DATA["ppl"]];

      } }
      }
      fclose($file);

      First time I've worked with a site using a CSV file.

      Should I be replacing the spaces etc... in this code somehow?
      >This code will obviously not work verbatim; it's just an example of how
      >you need perform the same transformation on artist names when you're
      >looking them up, or the comparison won't work. Notice how in my SQL
      >query I'm comparing the passed-in artist name (in the form of
      >"britney-spears") with the artist name in the database (in the form of
      >"Britney Spears") only AFTER I transform the database version to the
      >proper format - LOWER(REPLACE(. ..)) transforms "Britney Spears" to
      >"britney-spears", making the comparison successful.
      I tried variations of your code, but couldn't get anything to work.
      >Jeremy
      Thanks very much for the advice so far, appreciated.

      David
      --
      Free Search Engine Optimization Tutorial
      It's a sad SEO fact that 98% of search engine visitors leave a website without buying or converting to a potential sales lead! SEO Gold makes sure your website is super fast, so Google sends you more free traffic.

      Comment

      Working...