htaccess mod_rewrite - php

I'm trying to put something with this, whenever I go to a page like:
http://www.example.com/character.php?id=3
I want the mod rewrite to change it to:
http://www.example.com/character/Jim_Carrey
Which of course, the ID is the row of the character name...
For that kind of example... I've tried to work with it, but don't seem to get most of the production of htaccess because I haven't worked with .htaccess a lot really.

It's actually the other way around:
On your website, you write all your links the way you want them to look. For instance http://www.site.com/character/Jim_Carrey
In your database, you add a field,
commonly called "slug" or
"post_slug" which refers to the
Jim_Carrey" part of the url. IT MUST
BE A UNIQUE ELEMENT, much in the way
of a primary key. So make sure you
have a function that does take care
of creating the slug based on a
given string (the post title for
example) and making sure there is no
duplicate.
Then in your .htaccess (on the root folder) you do
something like
RewriteEngine On
RewriteRule ^character/([a-z0-9_\-]+)/$ character.php?slug=$1 [L,NC]
Finally, in your character.php
script, you do a database query not
against the ID, but against the
post_slug field.

If you're only using the character's name, then something like the following would do
RewriteRule ^character/(.*)$ /character.php?slug=$1
with a URL of eg http://www.example.com/character/Jim_Carrey. You'll then need to look up the character's name in the database using the slug passed in, as you won't have the ID to look it up with.
Alternatively you could include the ID in the URL if you need it, vis:
RewriteRule ^character/([0-9]+)/.*$ /character.php?id=$1
This way you could have a URL like http://www.example.com/character/3/Jim_Carrey which would include the character name (for SEO reasons etc etc), but also the ID which you could then look up directly in your database.
Edit a small PHP example for you re the first one:
<?php
// ... database connection stuff here etc
$slug = $_GET["slug"];
// IMPORTANT: perform some data sanitization here
// I'm just going to make sure it's only letters, numbers and
// hyphens/underscores as an example.
$slug = preg_replace("/[^a-zA-Z0-9\-_]+/", "", $slug);
// Now look up in your database
// Ideally you'd have a slug column to compare this with, that you can fill
// when your record is created/updated
// You'd also be best off using bound parameters here, rather than directly
// adding the data into the query string. I personally use the MDB2 PEAR
// module but feel free to use whatever you normally use.
$qry = "SELECT * FROM characters WHERE slug='" . $slug . "'";
$result = mysql_query($qry, $db);
// do something based on this result, fail if none found
// or show details if OK etc
// ...
?>
Hope this helps! As always, use bound parameters where possible for your queries, and perform sanitization of your user data well. The PEAR MDB2 module has a nice page on how to do this here.
Edit 2 a quick and dirty setup :-)
.htaccess file as follows:
RewriteEngine On
RewriteRule ^character/(.*)$ /character.php?slug=$1
Your .htaccess file would ideally be in the root of your site. Eg /home/wayne/public_html/ or wherever your index file is served from
A URL to match that would be http://www.example.com/character/Jim_Carrey - with the phrase "Jim_Carrey" appearing in your $_GET array as $_GET["slug"]. NB apologies, wrote that PHP sleepy last night above so no wonder $_POST wouldn't work as its a GET request :-) I've updated it now!
Finally you need to make sure that your host supports the use of .htaccess files. The setup of this is out of the scope of SO so any Apache configuration questions you'd be best asking over at https://serverfault.com/

I'm fairly certain you can't do this through htaccess. You'll need to do it in PHP, querying the database using the information from the url (?id=3) and then calling the Header Function using what you've learned from the database.

Sounds like you might be able to use mod_rewrite rewritemap.

Related

PHP/HTACCESS Creating link without extensions

I want to make user-friendly API for my service. I am trying to make it like Discord API - https://example.com/api/accounts/<account ID>/<stuff>/, some expected link examples below:
https://example.com/api/accounts/1234567890/data/
https://example.com/api/accounts/1234567890/inventory/
https://example.com/api/accounts/1234567890/servers/
I tried to make some htaccess tricks, but without any result - website got corrupted (just white page without anything) or account ID was considered as folder (HTTP 404, because I don't want those IDs as folders).
Thank you in advance for your response
Edit 1:
File structure can be really any, I just want it working. But most expected by me would be
api
- accounts
- data
- inventory
- ...
- server (example)
- game (example)
Edit 2:
My API is OOP - so I can call it from any place. I just need to get data and create new object and call some functions. In my bad-looking API, link was like: https://example.com/api/accounts/data.php?id=123456789 and in that script I call $stuff = new StuffObj($id, $other, $stuff, $from, $post); and function like $stuff->execute();. But with new API I can just make GET var, like action and in switch choose what object to use.
In my bad-looking API, link was like: https://example.com/api/accounts/data.php?id=123456789
In that case, to implement a "pretty" URL of the form /api/accounts/<id>/data/, you would do something like the following using mod_rewrite in your /api/.htaccess file:
Options -MultiViews
RewriteEngine On
RewriteRule ^accounts/(\d+)/data/$ accounts/data.php?id=$1 [L]
To make this more "generic", to rewrite a URL of the form /api/accounts/<id>/<action>/ to /api/accounts/<action>.php?id=<id>, assuming <action> would only consist of lowercase letters then you could change the above RewriteRule to read:
RewriteRule ^accounts/(\d+)/([a-z]+)/$ accounts/$2.php?id=$1 [L]
Although in your file structure you appear to have "subdirectories"(?) of the /accounts directory that also match the basename of the .php file? If so, this could be problematic, hence why I have disabled MutliViews above.
But with new API I can just make GET var, like action
Yes, you could - and would perhaps be preferable - everything is managed by a single entry point (eg. index.php - but you can call it anything your like) - However, you need to be specific and decide on this before implementing the "pretty URL" - which is really just cosmetic fluff. In fact, if this is just an API, do you need to implement a "pretty URL" at all?

PHP MySQL - URL Structure

I have a semi-professional website about my travels where I present all the pictures for each country.
For that I have a MySQL-Database containing the following attributes:
- country
- country-id
- pictures (links)
I am using a PHP-file which requests the pictures: "country.php"
So I get the URL-Structure: www.url.com/country/spain/ or www.url.com/country/usa/.
What I need is to change the URL Structure to www.url.com/spain but still maintain that "central" country.php-file.
I know a method which only works, when I have a folder for each Country in my webspace and an index.php-file which simply loads the country.php-file (I did that on another website). But in this case I would have way too many folders, which makes it all too complex since there are not only countries but also "special places and cities".
Is there another way to do that?
EDIT:
I got it with this code:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9-/]+)$ country.php?url=$1
But now the problem is, that whatever I type in, eg. www.url.com/xyz, the server thinks that I want to open the country "xyz". What can I do, to only rewrite, when the entered country is in my database?.
I am sorry if I ask too complicated, but I just didn't know how explain my problem better.
If you dont have any framework in use, which handles your routing, you could simply use the .htaccess file and set a rewrite rule.
Look here for example: how to remove folder name from url using htaccess
$url ="******YOUR URL HERE***********";
$urlArr = parse_url($url);
$urlbase = $urlArr['host'] . #$urlArr['path'];

PHP: Resolve Internal File Path using Shortened URL

My DocRoot:
/var/www/project/templates/index.html
/var/www/project/templates/about.html
/var/www/project/templates/contact.html
/var/www/project/templates/press/2013/01/01/mypresspost1
/var/www/project/templates/press/2013/01/02/mypresspost2
/var/www/project/templates/blog/2013/01/01/myblogpost1
/var/www/project/templates/blog/2013/01/02/myblogpost2
The Goal:
Find internal file path using shortened URL.
So if I hit mysite.com/myblogpost2 I will actually be loading /blog/2013/01/02/myblogpost2
I am using a templating engine so the path becomes usable in front end like: {include file="{$path}"}
My Bootstrap:
RewriteCond %{REQUEST_URI} !=/index.php
RewriteRule .* /index.php
Let's assume I already have a method to snag myblogpost2 string from the URI.
Now this just becomes a matter of resolving the internal path so I can set $path
Ideas:
I have a couple ideas, these are just to illustrate my problem better. Ultimately I am looking for the best route so any advice is welcome.
Use JSON from a flat file:
{
"myblogpost1": {longpath:"/blog/2013/01/01/myblogpost1"},
"myblogpost2": {longpath:"/blog/2013/01/02/myblogpost2"}
}
$string = "myblogpost1";
$path = objJsonResp[$string]->longpath;
Query a table:
$path = SELECT longPath FROM shortUrls WHERE name = :name
Since you will have dynamic created entries, i would do this with a mysql table.
within creation of the "alias":
Create the alias of the title, remove special chars and so on. spaces to underscores ... etc.
Check if there already exist an alias of that string
if so place a -1 at the end, check again, if it still exist increment the number till a unique one found.
Save the alias and and the destination.
I think you have a unique ID, so store this ID because maybe you change the date and the destination url is not the same as it was.
Within the .htaccess it should be clear that you need to rewrite all incoming requests to a specific file which check the string if it is an alias.
If so you got the unique ID from that "page" then you could redirect with the location header by reading out the date of the post and build with this information the actual url.
would cache this "build up" in order to not loose performance.

mod_rewrite php mysql

I'm really new at mod_rewrite and i have been trying to figure this out but really stuck. p
Here is my issue.
I have a page http://example.com/user/?s=81
?s=81 is reading from user id in the db.
What i would like to have is a link
http://example.com/nookie
In the database i have a field called whatuser
so on row 81 in that field i have user nookie
So what i would like is to read from databse what user it is in database
and create easi url from it.
i have also several php pages inside that user folder so i need to be able to link
to them like
example.com/nookie/step1.php
example.com/nookie/step2.php
To my knowledge you can not query databases with mod_rewrite.
how about putting a PHP-script to /user/?s=81, that looks up the user's name in the db and then relocates the user to $url = "/$username"; see PHP's header function passing "Location: $url" to it.
The other possibility (that I haven't thought through too much :) ) is that you add an extra field to the database e.g. user_home = /nookie/. So the logon script grabs it when verifying account details and thats where you send them to on successful validation? No rewrites /extra scripts needed.
Here's what I would suggest: if your username is only alphanumeric chars, you could pass the nick to all your Php files, after an internal rewrite, in the GET query.
Something like:
RewriteRule /([a-zA-Z0-9]+)$ /user/?s=$1 [QSA,L]
RewriteRule /([a-zA-Z0-9]+)/(.*)$ /$2?s=$1 [QSA,L]
And then, just have the "mother of mother" classes in Php that check for a value "s" in the query string ($_GET) which checks in the database if the user exists. If the user doesn't exists, make a 404 in Php.
I have almost sorted it out and here is the solution so far:
Here is the .htaccess row
RewriteRule ^([a-z0-9_-]+)$ user/?s=$1 [L,NC]
Then in the index file i have the following:
$trafikskola_id = mysql_real_escape_string($_GET['s']);
$vilken_trafikskola = mysql_query("SELECT * FROM users where slug='$trafikskola_id'") or exit(mysql_error());
In the database i have create slug field and inside that on row 81 added nookie and my url looks like
http://mypage.com/nookie instead of http://mypage.com/user/?s=81 =))
However i have the issue that i can not have link
http://mypage.com/nookie/ to have a forwardslash
And aswell non of my css - js - images are working.. Any ideas to solve those issues?

using seo user friendly in php

this is the URL path I currently use:
/index.php?page=1&title=articles
I want to get the URL path as
/index/page-1/title-articles
using SEO user friendly URLs in PHP.
And how to get the value of the "title"? Any one can help me pls.
Check out the mod_rewrite module, and maybe for a good starting point, this tutorial on how to take advantage of it with PHP.
You need to ensure two things:
your application prints out the new URLs properly, and
your webserver can understand that new URLs and rewrites them to your internal scheme or redirects them back to your application and your application does the rest.
The first part can be simply accomplished by using
echo ' … ';
instead of
echo ' … ';
The second part can be accomplished either with URl mapping features of your webserver (most webservers have a module like Apache’s mod_rewrite). With mod_rewrite, the following will do the rewrite:
RewriteEngine on
RewriteRule ^index/([^/-]+)-([^/]+)(.*) /index$3?$1=$2 [N,QSA]
RewriteRule ^index$ index.php [L]
The first rule will extract one parameter at a time and append it to the query. The second rule will finally rewrite the remaining /index URL path to /index.php.
I want to get the URL path as
/index/page-1/title-articles
Why? I’ve got two objections:
index is a no-information and I doubt that it belongs in the URI
page-1, as well as title-articles looks plain weird. Like with index, you should ask yourself whether this information belongs here. If it does, make clear that it’s the key of a key-value pair. Or remove it entirely.
Thus, I propose either:
/‹article›/1
or
/‹article›/page/1
or
/‹article›/page=1
or
/‹article›[1]
or
/articles/‹article›/page/1
Or any combination thereof. (In the above, ‹article› is a placeholder for the real title, the other words are literals).

Categories