Mod_Rewrite Complications - php

I have recently been doing a lot of redesign on my website, and one of these changes is SEO URL's, and I am doing Mod_Rewrite to do this. The problem is that I am not exactly familiar with reg expressions at all, nor am I exactly the best in the world when it comes to working with the .htaccess file.. Now, the problem I am having is that I have several variables on the same level and the RewriteRules I am using are cancelling each other out. I did find a work around by adding is tag, name, and page into the rewritten url, but that is not what I want. I would like the urls to be structured so it is /$lg/articles/[$tag|$name|$page]/ Again,doing is the way I want causes them to conflict because the document doesn't seem to know to read and process off three at the same time. Any tips and suggestions on how to do this? I would greatly appreciate it. :D
RewriteRule ^([^/]*)/articles/tag/([^/]*)$ /articles.php?lg=$1&tag=$2
RewriteRule ^([^/]*)/articles/name/([a-zA-Z]+)$ /articles.php?lg=$1&name=$2
RewriteRule ^([^/]*)/articles/page/([0-9]+)$ /articles.php?lg=$1&page=$2
What I am wanting it so have the URL's structure like so : /language/articles/Variable Value. Say an integer is put in, I want the url to look like so: /en/articles/1 and it will then act as the page number for the pagination system. Or an article name is put in: /en/articles/random_article_name and that name is then used to all the specific article in a database. The same idea applies for the tags, but pulls all articles with that tag. The idea is to have the URLs short and clean. The problem is that if I do the code like so:
RewriteRule ^([^/]*)/articles/([^/]*)$ /articles.php?lg=$1&tag=$2
RewriteRule ^([^/]*)/articles/([a-zA-Z]+)$ /articles.php?lg=$1&name=$2
RewriteRule ^([^/]*)/articles//([0-9]+)$ /articles.php?lg=$1&page=$2
Only one of the $_GET values will be read, and the rest will be ignored regardless of the variable name or regex expression. I am looking for a way to format my urls like so, if possible. If it isn't, I understand. I just figured it doesn't hurt to ask those who are more experienced.

You can have your rules like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]*)/articles/([0-9]+)/?$ /articles.php?lg=$1&page=$2 [L,QSA]
RewriteRule ^([^/]*)/articles/([a-zA-Z]+)/?$ /articles.php?lg=$1&name=$2 [L,QSA]

I'm not sure what's not working as your rules seem good to me. You can try this one to group the 3 rules :
RewriteRule ^([^/]*)/articles/(page|name|tag)/([0-9]+)$ articles.php?lg=$1&$2=$3

Related

GET variables not received from PHP redirect, is it a rewrite issue?

I'm working on a basic blog and trying to create a method to edit already-created entries. I know the code to render the entry in the edit view (admin page) works by manually passing the necessary GET variables in the url, e.g. "localhost/simple_blog/admin.php?page=blog&url=first-entry". This pulls all fields from the database without issue.
I have an .htaccess file performing rewrites, though:
RewriteEngine On
RewriteBase /simple_blog/
RewriteRule \.(gif|jpg|png|css|js|inc\.php)$ - [L]
RewriteRule ^admin/(\w+)(|/)$ admin.php?page=$1 [NC,L]
RewriteRule ^admin/(\w+)/([\w-]+) admin.php?page=$1&url=$2 [NC,L]
RewriteRule ^(\w+)/?$ index.php?page=$1
RewriteRule ^(\w+)/([\w-]+) index.php?page=$1&url=$2
The link to edit an entry is in the format "/simple_blog/admin/blog/first-entry", and hovering over the hyperlink on the page shows the reference to "localhost/simple_blog/admin/blog/first-entry" which is correct. Clicking the link and viewing the source on the page that loads shows that no values are being received from the previous page, though.
I'm just hoping someone with a bit more mod_rewrite and RegEx experience can look at this with me and maybe point something out that I'm missing, either that or confirm that the issue is not with my rewrite rules and is definitely elsewhere. I've triple-checked my functions, I receive no errors in Apache, and the access log merely shows that "first-entry" is being accessed by GET.
If this question is a dupe, PLEASE feel free to let me know and point me in the right direction. If you feel like you need more info/code examples, let me know that, too. :)
(Yes, I'm using "PHP for Absolute Beginners" by Jason Lengstorf; I'm in chapter 7 right now.)
EDIT: 1 Aug 2013
I've tested my rules on http://htaccess.madewithlove.be/ and it appears that almost any url I test it on only matches the final rule, thereby only sending "index.php" back my way. I've checked my syntax both using the "PHP for Absolute Beginners" book and external resources. Everything seems to check out. Anyone have any idea why it's doing this?
Here's a screenshot of the Rewrite test results.
Even though you've declared a RewriteBase, you can't exclude it from the pattern matching side of the Rules. A lot of the online testers don't support things like RewriteBase. Try this and see if it works.
RewriteEngine On
RewriteBase /simple_blog/
RewriteRule \.(gif|jpg|png|css|js|inc\.php)$ - [L]
RewriteRule ^simple_blog/admin/([\w-]+)/?$ admin.php?page=$1 [NC,L]
RewriteRule ^simple_blog/admin/([\w-]+)/([\w-]+) admin.php?page=$1&url=$2 [NC,L]
RewriteRule ^simple_blog/([\w-]+)/([\w-]+) index.php?page=$1&url=$2 [L]
RewriteRule ^simple_blog/([\w-]+)/?$ index.php?page=$1 [L]

Got stuck in a htaccess and rewrite

This is my first question here, so thank you all in advance and also sorry for my bad english.
I'm trying to apply htaccess and rewrites to one project I'm worknig on, but the problem is that I'd never done this before. I've been reading a lot of post (like http://corz.org/serv/tricks/htaccess2.php or this one http://www.the-art-of-web.com/system/rewrite/1/#.UW7mHqJhXCd) and articles about this, but combined with no previous experience on regular expressions I can't get it done...
I've been with this for 2 days now and I'm running out of time to finnish it, so I was wondering if someone could give me a hand, so here it goes:
WHAT I HAVE:
3 files at my root:
index.php
home.php
404.php
On the database:
On the users table there is a field called user_url
HOW NEED THIS TO WORK:
I want to display every user personal page like this www.example.com/user_url
I'm doing it like this at the moment www.example.com/?id=user_url
But I also need this to be able to go directly to the files in some cases, like with home.php instead of having to make something like ?id=home
Try adding these rules to the htaccess file in your document root, preferably above ones that do other kinds of routing:
Options -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /index.php?id=$1 [L,QSA]
As far as this:
But I also need this to be able to go directly to the files in some cases, like with home.php instead of having to make something like ?id=home
I have no idea what you're talking about. If you mean you'd like to go to http://www.example.com/home.php without it getting rewritten to /index.php?id=home.php, then that's what the 2 conditions above do.

mod_rewrite ignore variable if empty

Ok so i have a project that has product listing by categories,but also listing all products. I created a pagination for it,that works good. I set up mod_rewrite to work with paging on categories,but i cant manage to set it up for all products. The working one is www.domain.com/catalogue/catid/catname/pagenumber, and i also want to make www.domain.com/catalogue/pagenumber, but mod rewrite comes to problem here.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)$ index.php?p=$1&cid=$2&cname=$3&page=$4 [L]
and when i try to call second link,he treats that page number as cid. So i want to set up mod rewrite to read what is needed,and ignore cid and cname in this case.
I'd like to give you an alternative for this one..
Instead of using regexes, which you seem to have a bit of a problem with still.. There's a much easier way.
If you redirect everything to index.php, no exceptions.
Then within index PHP, you can read the current url using $_SERVER['REQUEST_URI'], and it becomes very easy with explode('/', $url);' to do all this processing..
It's a much more natural way to do routing.
There is not an ultra reliable way to do this in mod_rewrite.
The most reliable method is check for this in PHP.
There are two main methods:
One as Evert mentions redirect all to the page in question and decipher the url from there, which is what most do
two, detect the amount of $_GET vars you receive and judge how the page should react to what it gets within the PHP.
What you ask is not very straight forward, nor very fast in regex so I would recommend slapping this clause onto PHP rather than trying to get regex to do it for you.
Why not use two rules, if you're sure you'll never get a link like catalogue/catid/pagenumber ?
RewriteRule ^([^/]*)/([^/]*)$ index.php?p=$1&page=$2 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ index.php?p=$1&cid=$2&cname=$3&page=$4 [L]

php url rewriting and htaccess

I wonder if you can help me with a problem I am having, and give some advice on best practices.
I have a mysql table as follows
teams
columns: id, name, description
data : 1, Aston Villa, text here
I need to do dynamic rewrites to pull out data from the table. The only way I could think to do this was to use _GET as a variable and and look up the name, and change the case to lower case and swap spaces for -. I know there are a few security issues around doing it this way, but its a nice looking url www.mydomain.com/clubs/aston-villa
I have been looking at some frameworks such as yii and they seem to do it php side as apose to in the htaccess file.
Could anyone give me some pointers on the best way to achieve this, I havent managed to find any decent info on the web about best ways to achieve this.
Thanks in advance
Richard
The best solution is to redirect all request to a single file (this is called bootstrapping). The redirect is done in .htaccess like so
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule ^(.*)$ index.php/$1 [PT,L]
</IfModule>
Then, in index.php parse the request url, for example, via the $_SERVER values.
Even better, just google PHP bootstrap and get one of the very simple functioning samples/demos
What I use is an .htaccess file with mod_rewrite rule that will redirect all 404 errors to a specific script. From there on, since you have access to the original URL (the pretty one that just triggered a 404), you can parse it and figure out what was intended.

How to beautiful query string URLs

I have an entire website built upon a link scheme of query strings (i.e. ?page=about or ?page=individual&i=johndoe). Of course, in retrospect we have decided to go with a different (beautified) scheme in order to be more SEO friendly (i.e. /about/ or /individual/johndoe/).
Is there a way to accomplish this change using mod_rewrite on an Apache .htaccess file without having to change all the links sitewide? For instance, if you click a link to ?page=about it would permanently redirect you to /about/.
The code I have tried will successfully display /about/ as ?page=about, however, there is no redirect involved. And to be honest, I've never done any work in mod_rewrite (and it's a bit intimidating), so I feel I'm going in the wrong direction. Nonetheless, here's the code I've been working with so far:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_]+)$ /$1/ [R]
RewriteRule ^([a-zA-Z0-9_]+)/$ /index.php?page=$1
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ /$1/$2/ [R]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/$ /index.php?page=$1&i=$2
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/$ /index.php?page=$1&id=$2
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/$ /index.php?page=$1&bctid=$2
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/$ /index.php?page=$1&bclid=$2
Any thoughts? I greatly appreciate any help.
First... The rewrite will only apply to rewriting requests. As a result your changes listed in your questions will now allow a page to be accessed in two ways:
/index.php?page=about
/about/
That means that unless you make changes throughout your site you will not really be making much of a change since everyone is pointing to the wrong URL.
I think instead you want to use mod_redirect, to redirect the user to the newer formed URL. I think you can then have that new url get mapped back to the version your site actually expects. I believe that this works, and doesn't cause a loop.
That being said i think there is some SEO ding since there is a redirect on all pages, and no one actually points to the nicer URLs directly. That might not give you the results you want. Another option would be to use those regex that you provide, and actually make the real code change in all your views. That might be easy or hard depending on how you are making your links.
Good luck.
Clarification
I read your questions as you want several different things:
you don't want to change anything huge in the way your site works but you want nice URLs (perhaps you are using a framework forces pages to be called like this). This means that you need to support both ugly and nice urls, which means you need mod_rewrite so that both versions work.
Your goal is to make better urls for search engines. That means that you should "encourage" users who use the ugly URLs to instead use the nice URLs. In that case you should probably clean up your old urls on your site. If not google will continue to crawl the ugly urls (since those will be the only ones it saw).
You can't clean up other peoples URLs so you should probably mod_redirect their links to ugly urls to your nice ones. That way google will find the nice urls nicely. (this is the part i'm not sure of. Will the mod_redirect and mod_rewrite cause a loop? I think not, but if it does then only #1 and #2 would be doable, and you'd just need to live with other people's sites pointing to your ugly urls
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_]+)$ /$1/ [NC,R=301]
RewriteRule ^([a-zA-Z0-9_]+)/$ /index.php?page=$1
RewriteRule ^(artists)/([a-zA-Z0-9_]+)$ /artists/$2/ [NC,R=301]
RewriteRule ^(artists)/([a-zA-Z0-9_]+)/$ /index.php?page=individual&i=$2
RewriteRule ^(photos)/([a-zA-Z0-9_]+)$ /photos/$2/ [NC,R=301]
RewriteRule ^(photos)/([a-zA-Z0-9_]+)/$ /index.php?page=photogallery&person=$2
RewriteRule ^(post)/([a-zA-Z0-9_]+)$ /post/$2/ [NC,R=301]
RewriteRule ^(post)/([a-zA-Z0-9_]+)/$ /index.php?page=post&id=$2
RewriteRule ^(rss)/([a-zA-Z0-9_]+)$ /rss/$2/ [NC,R=301]
RewriteRule ^(rss)/([a-zA-Z0-9_]+)/$ /index.php?page=post&rss=$2
RewriteRule ^(search)/([a-zA-Z0-9_]+)$ /search/$2/ [NC,R=301]
RewriteRule ^(search)/([a-zA-Z0-9_]+)/$ /index.php?page=post&q=$2
RewriteRule ^(video)/([a-zA-Z0-9_]+)$ /video/$2/ [NC,R=301]
RewriteRule ^(video)/([a-zA-Z0-9_]+)/$ /index.php?page=videogallery&bctid=$2
RewriteRule ^(playlist)/([a-zA-Z0-9_]+)$ /playlist/$2/ [NC,R=301]
RewriteRule ^(playlist)/([a-zA-Z0-9_]+)/$ /index.php?page=videogallery&bclid=$2
Here's what I ended up using. Not sure if all those flags are necessary... but it works using the previous code. I still need to change all links sitewide (front-end and back-end), but I should also put in redirects for all the old links incase I miss one or in case other websites link to the old pages.
I mean the best way how do this is:
RewriteRule ^([a-zA-z0-9-]+)/?([a-zA-Z0-9/-]+)?$ index.php?page=$1&par=$2
and in PHP:
$page = $_GET["page"];
$parm = split("/",$_GET["par"]);
// first par
$parm[0];

Categories