Rewriting URL's from a PHP Redirection - php

How can i rewrite this url:
http://localhost/?=register
To look like this?:
http://localhost/index.php/Register

Your redirection code:
header('Location: /index.php/Register/',true,302);
exit;
For accessing the /Register/ value, use:
$_SERVER['PATH_INFO']

After performing the redirection using the header command, you must remember to write your code to process that URL.
/index.php/Register will try to load a "Register" file inside "/index.php/" folder ... 404 error
So you will need to use apache modrewrite to redirect these "virtual folders" to a centralized script that can handle it.
Something like this on .htaccess:
RewriteEngine on
RewriteRule ^index.php/(.*)$ index.php
Then, at your index.php, you will treat the incomming URL to detect that file, and do whatever you want with it.
I usually work with a catch-all (redirects everything to /index.php) and then break the URL and treat it, so I can have any number of virtual folder/files. Here is my own function to treat any incoming request:
function extractUri($uri="") {
if ($uri == "") $uri = isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] != "" ? $_SERVER['REQUEST_URI'] : "";
if ($uri != "") {
# removes query from request
if ($uri[0] != "/") $uri = "/".$uri; # ALWAYS START WITH /
$uri = explode("?",$uri);
$uri = str_replace("..",".",array_shift($uri)); # little exploit remover
$uri = explode("/",str_replace("//","/",$uri));
} else
$uri = array("/");
$context = array();
foreach ($uri as $part)
array_push($context,preg_replace("/(\.){2,}/","\.",$part)); # prevents ..
$action = array_pop($context); # file (with extension)
$original_action = $action; # preserve the original file with extension (I work w/o them)
$ext = "";
if ($action == "") $action = 'index'; # so if you are accessing folder/, then you probably want the index
else if (strpos($action,".")!==false) { # remove extension
$action = explode(".",$action);
$ext = array_pop($action);
$action = implode(".",$action);
$action = removeSimbols($action,true,false); # makes sure it is a valid filename, this function removes any weird character
}
return array($context,$action,$original_action,$ext); # returns the folder structure (array), the page/action, the page/action with extension, and said extension (lots of repetition to speed up later)
}
so extractUri("/index.php/Register") would return:
Array ([0] => "/", [1] => "index.php"), "Register", "Register", ""

Related

Cannot redirect correctly with PHP

I have a blog in a website that I want to redirect.
For example this URL https://example.com/blog/june-2021/name-of-blog-post should redirect to https://example2.com/blog/june-2021/name-of-blog-post
There are hundreds of blog posts so I can't use an array to redirect them one by one.
I'm using Pantheon as the host. I added the script to settings.php.
Currently everything from example.com goes to example2.com, so it's not working correctly.
Here's my script:
$url = $_SERVER['REQUEST_URI'];
$uri_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri_segments = explode('/', $uri_path);
$blog = $uri_segments[0];
$post_date = $uri_segments[1];
$post_name = $uri_segments[2];
if ((stripos($url, "/blog/") === 0) && (php_sapi_name() != "cli")) {
header('HTTP/1.0 301 Moved Permanently'); header("Location: https://example2.com".$blog.$post_date.$post_name);
if (extension_loaded('newrelic')) {
newrelic_name_transaction("redirect");
}
exit(); }
Thanks in advance!
You can check for /blog/ by checking that it is found !== false anywhere in $_SERVER['REQUEST_URI']:
if ((stripos($url, "/blog/") !== false) && (php_sapi_name() != "cli")) {
Or check to see if it is found at the first 0 position of $_SERVER['REQUEST_URI']:
if ((stripos($url, "/blog/") === 0) && (php_sapi_name() != "cli")) {
Notes:
stripos only takes three arguments and you only need the first two.
Location header should consist of a single absolute URI like https://example2.com/blog/june-2021/name-of-blog-post, so you might look at the other $_SERVER variables to construct one.

htaccess rewrite with subdomain as variable

I have a sitename.net and in a root directory i have .htaccess and index.php
.htaccess is:
FallbackResource /index.php
so basically as it's empty site (no sub directories, no files etc...) I will get a fallback to index.php which contains this:
$path = ltrim($_SERVER['REQUEST_URI'], '/'); // Trim leading slash(es)
$elements = explode('/', $path); // Split path on slashes
echo "Domain is: $domain <br>";
if(empty($elements[0])) { // No path elements means home
echo "ShowHomepage()";
}
else switch(array_shift($elements)) { // Pop off first item and switch
case 'tests':
echo "First is test";
case 'sample':
echo "First is sample";
default:
header('HTTP/1.1 404 Not Found');
Show404Error();
}
my problem is that when visitor enters: https://username.sitename.net/tests/test1
I get error as subdomain doesn't exist...
When I go to "https://sitename.net/tests/test1" i get what I want but I need username as a variable as well.
Should I first do rewrite in .htaccess so it translate https://username.sitename.net/tests/test1 as https://sitename.net/username/tests/test1 and than redo index.php so it pickup a first array element as username or there is another option ?
Can somebody help me out ?
------------- EDIT ----------------
I've ended up pointing A record *.sitename.net to server IP
I've changed .htaccess so it's:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^(.*)\.sitename\.net
RewriteRule ^(.*)$ subdomains/%1/$1 [L,NC,QSA]
FallbackResource /index.php
...and still getting 404 error... still can't get:
https://username.sitename.net/tests/test1 to act like https://sitename.net/username/tests/test1 so index.php will do it stuff...
I think wildcard DNS records is what you're looking for.
https://en.wikipedia.org/wiki/Wildcard_DNS_record
All subdomains will then redirect to your DNS, which you can redirect to your server.
EDIT:
Once the subdomains are up and running, you can use
.htaccess rewrite subdomain to directory
to fix the htaccess.
This work with php redirect too:
$url = "https://gbr8295.sitename.net"; //$_SERVER['HTTP_HOST']
if (substr($_SERVER['HTTP_HOST'], 0, 16) != 'https://sitename') { // You need edit 16 to a correct number for your domain
$username = substr($url, 8, ((strpos($url, '.') - 8)));
$new_url = "https://sitename.net/".$username."/";
echo $url."<br>"; // Output: https://gbr8295.sitename.net
echo $new_url; // Output: https://sitename.net/gbr8295/
header("Location: $new_url");
exit;
} else {
echo 'ok';
}

Error TOO MANY REDIRECTS debbuged

I'm spending a few hours trying to solve this ERR_TOO_MANY_REDIRECTS without success.
It happens when I access my website URL without being logged in. So if I do not have a session started I will be redirect to -> mywebsite.com/site/login or just /login
The PHP code that makes that is below:
if ( isset($_GET['p2k_url']) && $_GET['p2k_url'] ) {
if ( strstr($_GET['p2k_url'], '/') ) {
$url = explode('/', $_GET['p2k_url']);
} else {
$url[0] = $_GET['p2k_url'];
}
if ( !isset($url[1]) || !$url[1] ) {
$url[1] = 'index';
}
}
if ( $url[0] != 'login' && !$__usuCod ) {
header('Location: /site/login.php');
die();
}
if ( file_exists(SITE_DIR.DS.'_'.$url[0].DS.$url[1].'.php') ) {
include SITE_DIR.DS.'_'.$url[0].DS.$url[1].'.php';
} else {
if ( file_exists(SITE_DIR.DS.'_'.$url[0].DS.'no404.php') ) {
include SITE_DIR.DS.'_'.$url[0].DS.'index.php';
} else {
include SITE_DIR.DS.'_404'.DS.'index.php';
}
}
Right here: if ( $url[0] != 'login' && !$__usuCod ) {
My login.php is just a simple html page with form. Nothing there to worry about.
Although my main .htaccess is below and I think it might have something there:
Options -indexes
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ index.php?p2k_url=$1 [QSA,L]
</IfModule>
In order to debug and find the error, when I run tail -f access_log I get just simple access requests:
127.0.0.1 - - [01/Nov/2016:11:16:28 -0200] "GET /site/login.php HTTP/1.1" 302 -
Nothing coming on error_log tough.
Doing reseraches I see that is a very comum problem on WP - which is not the case here. Any ideas?
Thanks
So you're redirecting to /site/login.php which your rewrite changes to index.php?p2k_url=site/login.php
$url will be an array of ['site', 'login.php'] (i'd trim($x, '/') the string before exploding to be sure).
Then you test if $url[0] != 'login' which will always be true as [0] is site. You need to test if $url[1] != 'login.php' or trim the file extension from the string first.
if you want to allow /site/login and /login then you just need to work out a rule for that. If /site/xxx is always equal to /xxx then just remove the first array index from $url if $url[0] == 'site' (or normalise your url's properly)
A really useful debugging technique i used in my early days was var_dump or print_r along with die() or exit. Use something like die('xxx') and move it up and down your script to identify where the redirect is occuring, then print out the variables to see what they contain and check your comparing them correctly. It's a crude method, but it works

Use PHP to rewrite URLS?

I want to make my own url rewriting rules using couple of PHP-MySQL. The concept is to have a rule in my .htaccess that send all request to my index.php file like :
RewriteRule ^([a-zA-Z0-9_-]+)/$ index.php
RewriteCond %{REQUEST_URI} !\.(.+)$
RewriteRule ^(.*)([^/])$ http://%{HTTP_HOST}/$1$2/ [L,R=301].
And php will take all params via a super global var like $_SERVER['REQUEST_URI'] and explode("/", $_SERVER['REQUEST_URI']).
function rewrite(){
$paramKeys = array("", "locale", "page", "par1", "par2", "par3", "par4", "par5");
$paramValues = explode("/", $_SERVER['REQUEST_URI']);
foreach($paramValues as $key => $value){
if (!is_array($key)) {
$paramValues[$key] = htmlspecialchars(stripslashes(trim($value)));
if($key == 0){ //but the 1st slash is in the end of URL
continue;
}
elseif($key == sizeof($paramKeys)){
break;
}
else $params[$paramKeys[$key]] = $value;
}
else continue;
}
return $params;
}
And compare the requested URL with URL's in my database to send http statut in order of the requested file is found 200, moved 301, or not found 404.
Have I a bad idea ? if not, how can I perfectionize it. Thank you !

Manipulate URL $_SERVER['REQUEST_URI']

This is my url:
http://localhost/framework/index.php
echo $_SERVER['REQUEST_URI'];
Would output: /framework/index.php
But If my url was:
http://localhost/framework/
The output would be:
/framework/
And If I move the file, yeah you get the idea.
How do I grab the content after folders/eventually index.php file? My idea is to have index.php as a front controller.
If I have:
http://localhost/framework/index.php/test/test
I only want the test/test part.
http://localhost/framework/test/test
I only want the test/test part.
You can automatically detect the base uri and remove it, leaving you with the test/test part.
if(!empty($_SERVER['PATH_INFO']))
{
// Uri info does not contain docroot or index
$uri = $_SERVER['PATH_INFO'];
}
else
{
if(!empty($_SERVER['REQUEST_URI']) && !empty($_SERVER['HTTP_HOST']))
{
$fullUrl = 'http://'
. ((isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : '')
. ((isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : '');
$uri = parse_url($fullUrl, PHP_URL_PATH);
}
else if(!empty($_SERVER['PHP_SELF']))
{
$uri = $_SERVER['PHP_SELF'];
}
}
$baseUri = substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], "/")+1);
$uri = str_replace($baseUri, '', $uri);
Edit: mAu's comment above is correct. I was under the assumption you was already using mod rewrite.

Categories