Dynamic URL rewriting using codeigniter/php/htaccess when change in url - php

I have URL like base_url()/controller/rowtitle-rowid.
Where this URL is manipulated using function and arranged according to row in database.
As mentioned above I need to change whole URL when I am changing rowid in the URL, that means it should rewrite to particular id of row in database.
For example:
Consider following URLs
https://www.marketsandmarkets.com/Market-Reports/medical-device-testing-market-254474064.html
2.https://www.marketsandmarkets.com/Market-Reports/timing-relay-market-241993160.html
if I change bold numbers in number 2 URL to bold numbers in number 1 URL then it will rewrite the URL to URL number 1 and redirect to URL number 1
Can this possible?
Thanks in advance.

Your say you are modifying the rowid which I assume are the numbers you are bolding in your 1,2 statements, and at the same time you want to redirect to a different slug and rowid which is the dashed statement before the rowid at the end of the url e.g. some-page-name.
I'm not sure what the rowid has to do with anything, perhaps it's just a random int to make sure you don't have duplicate slugs, but it isn't strictly required as long as you increment your titles if you have duplicates like some-page-name and some-page-name-1.
In PHP and codeigniter what you are trying to do is indeed possible as long as you keep a database with all the iterations of the slug. Then in your Market-Reports controller you just look for the most recent iteration of the slug and serve that as a link to the user. Or if the user is coming from a search engine, on the say Market-Reports single page controller to timing-relay-market-241993160 you query the database where rowid = 'someid' and order by created or something and then redirect the user to that slug which would be medical-device-testing-market-254474064.
Further if your database table for keeping track of slugs has the following rows rowid, rowtitle, fullslug you could literally just use intval() to get the rowid from the fullslug and do the same type of thing as I just outlined in the previous paragraph.
NOTE: You cannot do this with static HTML pages. I am assuming since you tagged PHP and codeigniter you are using php and controllers.

Related

Friendly URL Database Strategies

I have a website that I want to start using friendly URLs.
So instead of:
http://server.com/company.php?id=12
I could use:
http://server.com/company/steaks_r_us
I know how to do this on the .htaccess side, but I don't know how to set it up on the backend with the database calls, especially if there is a chance that company name isn't unique (multiple locations for instance).
I've thought about inserting the friendly url into the database after checking for duplicates, but I'm curious if there is a better way
No matter if it's an ID or a user friendly string like company name, you need it to be a unique identifier. You won't avoid that.
There are couple of options.
Some websites adds ID (primary key) to the user friendly name like:
http://server.com/company/steaks_r_us_12
or in other part of URL like:
http://server.com/company/12/steaks_r_us
Then you can easily fetch the ID from the URL, but also it still looks nice.
Also as wheatin suggested, you could create a field in your DB that would be this unique identifier.
In this case you would need some additional logic at the time of creation of company row in database. That's of course because you have to handle duplicated names somehow.You could for example add a digit at the and of this value (facebook does something like that), so if a duplicate of steaks_r_us occurs, you would insert a value steaks_r_us2
Then you would have unique URL for these companies:
http://server.com/company/steaks_r_us
and
http://server.com/company/steaks_r_us2
You could create a unique index on the business key (in this case the company name) to prevent duplicates from being inserted in the first place.
Wheatin has the right idea. You'd want to have a table with two columns, the URL and the id it's referring to. If you made a unique key on the URL column, then you could just have a function/method that tries to insert the clean URL with the content id; I usually do something like
###(pseudocode)
function create_unique_url($url, $id) {
try to insert the url, id combination
if success:
return url
else:
key = 1
start a loop
try to insert the url+key, id combination
if success:
return url
key++
}
Adding a number to the end is a good fail-safe way to make sure you always get a unique url returned. Sort of how Drupal or Wordpress would handle a post url with an identical name.

Dynamic content without multiple pages

Let me start by saying i am new to mysql and php, and I'm sure this is a noob question but I've been searching google and can't find any solution.
Basically I want to create 1 template file that will read all of a table from a database with multiple rows and columns but only display one row at a time.
An example would be http://www.w3schools.com/php/php_mysql_select.asp scroll towards the bottom where it shows peter griffen and glen quagmire i would want it to only display 'glen quagmire' or only display 'peter griffen' depending on which link was previously clicked.
would i need to somehow assign an ID to the link url so php knew which row to parse etc.. ?
One straightforward way is to use the query string. Make the link <a href='stuff.php?id=1'>View #1</a>. Then use a where id='$id' clause in the SQL query, setting $id equal to the query string parameter $_GET['id'].

user-friendly URLs reliable with the database

I have a database containing a table named songs with a field title.
Now If my url is http://www.foo.com/songs/xxx (xxx = the title of the song),
apache is silently redirecting to a page that looks similar to : /song.php?title=xxx.
To embellish the URLs I convert spaces into underscores (cause I know some browser display %20 instead of space, not%20really%20user%20friendly%20ya%20know%20what%20i%20mean).
There's a snag cause if the title contains spaces and underscores (e.g. DJ_underscore fx) and the script converts it into DJ_underscore_fx the sql :
select * from songs where songs.title=xxx
can't find it.
here's the sketch to be more specific:
a script fetches the different titles in the database
converts all the space into underscore ( e.g. name_of the song ->
name_of_the_song )
echo them as links ( e.g. name_of_the_song )
the user clicks on the link and requests the document
apache is silently redirecting ( e.g. /songs/name_of_the_son ->
/song.php?title=name_of_the_song )
song.php fetches the specific data ( e.g. select * from songs where songs.title=name_of_the_song )
ok you see that there's no entry in the database that looks like name_of_the_song but name_of the song.
How can I manage the whole so that my URL remains clear and the title field is not restricted to a certain amount of values (can have spaces, underscore, dashes, well anything)?
Use something like /1234/name-of-page/ where 1234 is the primary key ID of the row and name-of-page is ignored by your script.
This gives a link directly to the primary key of the entry in the table, which will give you several benefits:
No need to have duplicate ID fields.
Fast indexing on SELECT queries.
You still get the readability and SEO benefits of a "pretty" URL.
You might notice that StackOverflow itself does exactly this:
/questions/8211267/user-friendly-urls-reliable-with-the-database/
Which probably gets re-written to something like:
question.php?id=8211267
Just add another field that will keep the exact name used in URL. And when you have some "duplicates" - just append them with _2, _3 etc or give a way for user to edit and give another name manually.
What your trying to achieve is definetly the wrong way, you could have hundreds of variations to lookup in your database and is also bad for SEO.
Start by setting a rule that all URL's have _ to seperate the space, that's how most site URL's are done (digg.com being an example).
Then create a seperate field that stores the URL e.g.
title | url
song name | song_name
Then do your lookup based on the URL field.
For legacy reasons you could also replace any spaces with _ in your lookup script when you receive the title from the GET before doing the database query.
well, if you want spaces in the url, people will have it uri encoded for transit. if rather than replacing all _ with spaces, just use a uridecoder (can't remember the exact title). it would still allow for spaces to be typed. On the displayer, the shown text in the link, cant you do an str_replace to convert %20 in spaces?
Either that of have a computer friendly version of the title (that doesn't use spaces, but underscores) and a user friendly column that does have the spaces

Constructing URL without item ID and getting right item

I have had this problem for a while,
Let say we have a movies website
And we have a movie named Test-movies123! in the database,
now what I would do is make a URL watch/test-movie123-{$id}/ and then query DB with the ID,
Now the issue with this is that the ID shouldn't be there, how can I go around this ?
if I get the test-movie123 from url and search it, I wont find it because it has no ! unless I use LIKE but thats not very trusty...
Anyone could suggest anything ? Would be much appreciated
Well, you could create a rule for taking the movie title and turning it into a slug. So, you'd know that you always lowercased the title, removed anything other than letters, numbers and dashes, and converted whitespace into a single dash.
Then store that in another column in your database, and be sure you are forcing uniqueness. Take the URL and search that column from that.
From that point you just have to deal with what happens if you have a second video uploaded that produces the exact same slug. There are a number of options for this ... append a random number slug, increment a number and append it, etc.
To do that, you may have in your database something like the primary_key as
"test-movies123".
Imagine you have a control panel, you insert movies in a form.
Then use the title Test Movies123! to save it in the database like this example:
id: AUTO_INCREMENT NUMBER
keyname: sanityTitle("Test Movies123!") <-- this should save "test-movies123"
title: "Test Movies123!"
stuff: "blablabla"
note sanityTitle() will be your function to prepare friendly url's from titles.
Then your url will look like
watch/test-movie123/ using regex control in url's
or
watch/?id=test-movie123 raw
You will search for the INDEXED or PRIMARY key, "keyname" in the table, it will output 1 row, with all your stuff.

Mysql query based on string within a preg_match or preg_replace?

In a previous question, I managed to get some text replacement working for my wiki. Which works great with titles. But now I'd like to replace titles with IDs. For my wiki, I simply replace [[wiki::Title]] with a link to that title. How can I get links from IDs in that title spot?
The below code works, but only outputs the ID. Example text includes [[tdh::1]] and [[tdh::5]]. I would now like to take that ID and query my database for it and use that result to build a link.
$text = preg_replace("/\[\[tdh::(.+?)\]\]/","\\1", $text);
Pointing me in the right direction would be helpful. Thanks.
You can use preg_replace_callback and for the callback parameter use a function that uses the ID to fetch the name from the database.
Note that above approach, while simple, could potentially result in a lot of database calls. An improvement is to first find all the IDs using preg_match_all and store them in an array. Then you can fetch all the names in a single database call. The SQL you need will be something like this:
SELECT id, name
FROM links
WHERE id IN (?, ?, ?)
Watch out for SQL injection vulnerabilities if you aren't using parameterized queries. Store the results in an associative array with the ID as the key and the name as the value.
Finally you can use preg_replace_callback where the callback function finds the name from the array.
You should first read the id and any other association necessary from the database and cache them in some sort of array.
The you use a preg_replace_callback to to the actual replacement based on that cached data.
Alternatively you could to a two step process: try once and record the id's found (not replacement). Use those to query the db for additional data. Do another search and replace the results.
You could also do what #Mark suggested but if the page you are editing has 15 title you will make 15 queries to the db and that might work or not for you. In some high load it will probably not work. This means slow pages usually.

Categories