I am in the outlining phase of constructing a Routing system for a PHP Framework I am building.
I will need to use mod rewrite, for pretty urls. I got that part covered.
But say I want to make a page with the url like:
www.domain.com/news/10(News-id)/
and I want this dynamic variable ( This news id ) to have a name when rewriting.
What I want to achieve is;
Frameworks routes to news controller, and passes 10 as argument as:
$args = array ( 'news_id' => 10 )
You can use the $_SERVER super-global to inspect the requested URI. In your example, $_SERVER['REQUEST_URI'] will be set to something like:
/news/10/
You can then get the requested news-id from that string.
Update
// Use substr to ignore first forward slash
$request = explode('/', substr($_SERVER['REQUEST_URI'], 1));
$count = count($request);
// At this point, $request[0] should == 'news'
if($count > 1 && intval($request[1])) {
// The second part of the request is an integer that is not 0
} else {
if( $count == 1) {
// This is a request for '/news'
// The second part of the request is either not an integer or is 0
} else if($request[1] == 'latest') {
// Show latest news
} else if($request[1] == 'oldest') {
// Show oldest news
} else if($request[1] == 'most-read') {
// Show most read news
}
}
See the manual entry for $_SERVER
Related
I need to detect the language the user is using to include the correct file using PHP if elseif or else like this:
users are comming from:
example.com/EN/nice-title-url-from-database-slug
example.com/DE/nice-title-url-from-database-slug
example.com/ES/nice-title-url-from-database-slug
the php I need is something like this:
PHP
document.location.toString().split(...) etc
detect the url paths
if url path <starts with /DE/>
include de.php
elseif url <path starts with /EN/>
include en.php
else url <path starts with /ES/>
include es.php
so what I need is to detect the url after the domain (/ES/ or /EN/ or /DE/)
Any idea how to achieve this?
what about
$check = "example.com/EN/";
if (substr($url, 0, strlen($check)) === $check) { ... }
?
To achieve what we want, we need to:
Find the URL of the current page - we can use $_SERVER['REQUEST_URI'] (Get the full URL in PHP
From this, we want to figure out if it contains the language part. One way to do this, is to split the string, as you kindly suggest, and get second result (which is key 1): explode('/', $_SERVER['REQUEST_URI'])1
Then we can do the include or what logic you need.
So following would be my suggestion.
// Get the uri of the request.
$uri = $_SERVER['REQUEST_URI'];
// Split it to get the language part.
$lang = explode('/', $uri)[1]; // 1 is the key - if the language part is placed different, this should be changed.
// Do our logic.
if ($lang === 'DE') {
include 'de.php';
} else if ($lang === 'EN') {
include 'en.php';
} else if ($lang === 'ES') {
include 'es.php';
}
To get the page URL, use $_SERVER['REQUEST_URI']. Then use explode by /
to get URL different parts.
$parts = explode('/',$_SERVER['REQUEST_URI']);
$parts now contain the below elements.
Array
(
[0] =>
[1] => EN
[2] => nice-title-url-from-database-slug?bla
)
As you can see index 1 of the $parts array is what you need.
Scenario: As you know, StackOverflow checks the title in the question. I mean when you open this URL:
http://stackoverflow.com/questions/38839016/should-i-store-the-result-of-an-function
automatically it will be replaced with this:
http://stackoverflow.com/questions/38839016/should-i-store-the-result-of-an-function-into-an-array
That replacement is because of being incomplete the first URL.
Ok well, I'm trying to make such a system by PHP. Here is my attempt:
// getting this from the URL
$id = '38839016';
// fetching this from database based on that id (38839016)
$real_title = $result['title'];
//=> Should I store the result of an function into an array
$real_title = str_replace("-"," ",strtolower($real_title));
//=> should-i-store-the-result-of-an-function-into-an-array
// getting whole uri
$current_uri = $_SERVER["REQUEST_URI"];
//=> /questions/38839016/should-i-store-the-result-of-an-function
What I want to do: I need to compare $real_title with title-part of the $current_uri. How can I determine "title-part"? It is everything which is after $id.'/' until / or ? or $ (end of string). How can I do that comparison?
And then:
if ( preg_match("//", $current_uri) ) {
// all fine. continue loading the page
continue;
} else {
// replace title-part of the $current_uri with $real_title
preg_replace("//", $real_title, $current_uri);
// redirect to this post with correct slug
header('Location: '.$_SERVER["HTTP_HOST"].);
}
briefly, I want to complete these:
if ( preg_match("//", $current_uri) ) {
preg_replace("//", $real_title, $current_uri);
Ok, in simple words, there is a good url and a requested url
if the requested url not equal the good url
redirect the visitor to the good one
<?
$id = '38839016';
$good_url = '/questions/'.$id.'/'.str_replace("-"," ",strtolower($result['title']));
preg_match( '/\/[0-9]+\/([a-z0-9-]+)\/.*/', $_SERVER[REQUEST_URI], $matches);
if ($matches[1] != str_replace("-"," ",strtolower($result['title'])))
header('Location: '.$good_url);
I am using Codeigniter and want to have SEO-friendly URLs. There will be 2 types of URI segments, http://www.domain.com/view/193847 and http://www.domain.com/view/193847-canon-5d-mark-iii.
If the first URL is used, function view_mini is called and passed the product id 193847. If the 2nd one is used, function view_full will be called and passed the same product id 193847.
Problem: How can I differentiate between the 2 URLs? Or is this an inferior approach to solve the problem?
PHP How should the if condition be structured?
function view($pid) {
if($this->uri->segment(2) == something) {
$this->view_mini($pid);
} else {
$this->view_full($pid);
}
}
function view_mini($pid) {
// ...
}
function view_full($pid) {
// ...
}
EDIT
I am using URL routing to route http://www.domain.com/controllername/view/1234 to http://www.domain.com/view/1234
you can use the regular expression to check the segment if it has anything other than numbers, then you can execute the view that you want for example
$pattern = '\d[0-9][^a-zA-Z]';
$url = $this->uri->segment(2);
if(preg_match($pattern,$url))
{
//this will match only the numbers
$this->view_mini($pid);
} else {
$this->view_full($pid);
}
i hope this will help ..
Is there any definitive structure to the different URLs?
ie.
http://www.domain.com/view/[numbers]-[text]
If so, you could test the URL for that dash between the numbers and the dash?
Edit: un-tested
$route["view/(\d+)"] = "class/view_mini/$1";
$route["view/(\d+)-([\w'-]*)?/g"] = "class/view_full/$1/$2";
Use
$result = explode('-', $this->uri->segment(1));
If(isset($result[1]))
{
// show full view
} else {
// show mini view
}
$pid will always be $result[0]
I have been working on a fancy router/dispatcher class for weeks now trying to decide how I wanted it, I got it perfect IMO except performance is not what I am wanting from it. It uses a route map arrap = /forums/viewthread/:id/:page => 'forums/viewthread/(?\d+)' and loops through my map array with regex to get a match, I am trying to get something better on a high traffic site, here is a start...
$uri = "forum/viewforum/id-522/page-3";
$parts = explode("/", $uri);
$controller = $parts['0'];
$method = $parts['1'];
if($parts['2'] != ''){
$idNumber = $parts['2'];
}
if($parts['3'] != ''){
$pageNumber = $parts['3'];
}
Where I need help is sometime an id and a page will not be present sometime one or the other and sometimes both, so obvioulsy my above code would not cover that, it assumes array item 2 is always the id and 3 is always the page, could someone show me a practical way of matchting up the page and id to a variable only if they exist in the URI and without using regular expressions?
You can see what I have so far on my regular expressions versions in this question Is this a good way to match URI to class/method in PHP for MVC
This seems more extendable:
$parts = explode("/", $uri);
$parts_count=count($parts);
//set default values
$page_info=array('id'=>0,'page'=>0);
for($i=2;$i<$parts_count;$i++) {
if(strpos($parts[$i],'-')!==FALSE) {
list($info_type,$info_val)=explode('-',$parts[$i],2);
if(isset($page_info[$info_type])) {
$page_info[$info_type]=(int)$info_val;
}
}
}
then just use $page_info values. You can easily add other values this way and more levels of '/'.
if ( ! empty($parts['2']))
{
if (strpos($parts['2'], 'id-') !== FALSE)
{
$idNumber = str_replace('id-', '', $parts['2']);
}
elseif (strpos($parts['2'], 'page-') !== FALSE)
{
$pageNumber = str_replace('id-', '', $parts['2']);
}
}
And do the same for $part[3]
EDITED
I'm trying to setup a random link at the bottom of all my pages. I'm using the code below, but want to make it so the current page is not included in the random rotation of links.
Example:
I need code to randomly select and display ONE of these links. The exception being, IF article1.php is currently being viewed, I want it to be excluded from the random selection. That way only links to OTHER articles are seen on any given article.
http://mysite.com/article1.php
http://mysite.com/article2.php
http://mysite.com/article3.php
I would use array_rand with something like:
<?php
$links = array(array('url' => 'http://google.com', 'name'=>'google'),
array('url' => 'http://hotmail.com', 'name' => 'hotmail'),
array('url' => 'http://hawkee.com', 'name' => 'Hawkee'));
$num = array_rand($links);
$item = $links[$num];
printf('%s', $item['url'], $item['name'], $item['name']);
?>
Where links makes it easier to build an array. Nevertheless, I think we miss some details about how you grab your links.
What is the mean of "current page"? because the simplest way to do, is just not add the page to the array.
And the use of array_rand avoids confusion with size of array and so.
Edit: I suppose you use a database, so you may have an sql request like:
SELECT myfieldset FROM `articles` WHERE id = 'theid';
So you know the id of the current article. Now you just have to build an array with some other articles with a query like:
SELECT id FROM `articles` WHERE id NOT IN ('theid') ORDER BY RAND LIMIT 5
And build the candidate array with those results.
Each time you randomly choose a URL to display, pop it off of the array and store it in a temporary variable. Then, on the next rotation make your selection and THEN push the previously used URL back into the array.
$lastUrl = trim(file_get_contents('last_url.txt'));
while($lastUrl == ($randUrl = $urls[rand(0, count($urls) - 1)])){}
file_put_contents('last_url.txt', $randUrl);
// ...
echo $randUrl;
Ensures that on each page load, you will not receive the previous URL. This, however is just an example. You would want to incorporate file locking, exception handling (perhaps) or an entirely different storage medium (DB, etc.)
To ensure the URL is not the same as the current, this should do the trick:
// get current URL
$currentUrl = 'http://' . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
// randomize URLs until you get one that doesn't match the current
while($currentUrl == ($randUrl = $urls[rand(0, count($urls) - 1)])){ }
echo $randUrl;
Google "PHP get current URL", and you'll get considerably more detailed ways to capture the current URL. For example, conditions on whether or not you're use HTTPS, to append an 's' to the protocol component.
try the codes below :
$links = array(
'http://mysite.com/article1.php',
'http://mysite.com/article2.php',
'http://mysite.com/article3.php',
'http://mysite.com/article4.php',
'http://mysite.com/article5.php'
);
$currentPage = basename($_SERVER['SCRIPT_NAME']);
$count = 0;
$currentIndex = NULL;
foreach($links as $link) {
if(strpos($link, "/".$currentPage)>-1) $currentIndex = $count;
$count++;
}
if($currentIndex) {
do{
$random = mt_rand(0, sizeof($links) - 1);
} while($random==$currentIndex);
} else {
$random = mt_rand(0, sizeof($links) - 1);
}
$random_link = $links[$random];