Making PHP GET parameters look like directories - url-rewriting

I am trying to make it so:
http://foo.foo/?parameter=value
"converts" to
http://foo.foo/value
Thanks.

Assuming you're running on Apache, this code in .htaccess works for me:
RewriteEngine on
RewriteRule ^([a-zA-Z0-9_-]+)/$ /index.php?parameter=$1
Depending on your site structure you may have to ad a few rules though.

Enabling mod_rewrite on your Apache server and using .htaccess rules to redirect requests to a controller file.
.htaccess
# Enable rewrites
RewriteEngine On
# The following two lines skip over other HTML/PHP files or resources like CSS, Javascript and image files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# test.php is our controller file
RewriteRule ^.*$ test.php [L]
test.php
$args = explode('/', $_SERVER['REDIRECT_URL']); // REDIRECT_URL is provided by Apache when a URL has been rewritten
array_shift($args);
$data = array();
for ($i = 0; $i < count($args); $i++) {
$k = $args[$i];
$v = ++$i < count($args) ? $args[$i] : null;
$data[$k]= $v;
}
print_r($data);
Accessing the url http://localhost/abc/123/def/456 will output the following:
Array
(
[abc] => 123
[def] => 456
)

Assuming you are using Apache, the following tutorials are epically helpful:
.htaccess part one
.htaccess part two
The second tutorial has your answer. Prepare to dig deep into a dungeon called mod_rewrite.

Use mod rewrite rules if you are using Apache. This is better and secure way to make a virtual directory.

Related

How to make Magento understand we are on the subdomain?

Need your help. I made a multi-view (domain.com & sub.domain.com) store with Magento 1.9.2.1. Everything is fine! But! When you try to get the subdomain, magento show you information from the main domain.
On the other side when you try to get subdomain through the main domain (language switcher with GET "?___store=viewSubDomainCode&___from_store=viewDomainCode").
The reason is in setting Cookies I suppose.
How to make Magento set cookies when my request is directly http://sub.domain.com.
Index.php of subdomain:
/* Store or website code */
$mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : 'code of my WEBSITE';
/* Run store or run website */
$mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'website';
Mage::run($mageRunCode, $mageRunType);
Important thing: I need one COOKIES for both domains (one cart).
Simply say: I want to set CurrentStore of subdomain!
First of, you need to set your cookies correctly to make them work in domain/subdomain:
https://magento.stackexchange.com/questions/68070/whats-the-correct-cookie-config-for-a-magento-site-split-across-multiple-instan
Regarding the store switching to the correct view, you need either .htaccess modification:
RewriteCond %{HTTP_HOST} www\.domain1\.com [NC]
RewriteRule .* - [E=MAGE_RUN_CODE:domain1_com]
RewriteCond %{HTTP_HOST} www\.domain1\.com [NC]
RewriteRule .* - [E=MAGE_RUN_TYPE:website]
RewriteCond %{HTTP_HOST} www\.domain2\.com [NC]
RewriteRule .* - [E=MAGE_RUN_CODE:domain2_com]
RewriteCond %{HTTP_HOST} www\.domain2\.com [NC]
RewriteRule .* - [E=MAGE_RUN_TYPE:website]
Or modify index.php to switch based on domain:
switch($_SERVER['HTTP_HOST']) {
case 'domain1.com':
case 'www.domain1.com':
$mageRunCode = 'domain1_com';
$mageRunType = 'website';
break;
case 'domain2.com':
case 'www.domain2.com':
$mageRunCode = 'domain2_com';
$mageRunType = 'website';
break;
}
With this, don't forget to clear cache & sessions, it should work.

htaccess clean url syntax converts a pipe symbol to %7C

i've spent the last 10 hours to figure out what am I doing wrong but no effect so far unfortunately...
so this is my case:
RewriteRule ^party/(.*)$ party.php?party=$1 [L]
is my working rule for clean url in htaccess.
It works perfectly, but now I have some special chars in the $_GET parameter , * for example is not converted but pipe symbol does into %7C.
I checked party.php?party=$1 and it displays all the characters correctly, so i guess my htaccess syntax is causing the failure....
I also tried the [NE] flag but it doesn't work...
Any ideas anyone?
Thank you very very much!
I've also just realised that url is displayed properly in mozilla...
I use:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(.+)?\.testynarkotykowe.xernt.com$ [NC]
RewriteRule ^(.*)$ http://testynarkotykowe.pl/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php
PLUS YOU do.
function sUrl() {
$_GET = explode('/',substr(getenv('REQUEST_URI'),1)); $_pth = PTH;
if(!empty($_pth)) {
$pth = explode('/',PTH);
for($i = 0; $i < count($_GET); $i++) if($_GET[$i] == $pth[$i]) unset($_GET[$i]);
array_splice($_GET,0,0);
} foreach($_GET as $k=>$v) $_GET[$k] = htmlspecialchars($v); /* SECURITY: check for addslashes */
}
}

Mod-Rewrite Dynamic URLs

I've searched and searched and tried and tried for 2 days solid now on how to make myself some friendly URL's on a CMS I am making to teach my self php.
I am trying to change:
www.mydomain.com/cms/index.php?id=30
To:
www.mydomain.com/cms/30
to begin with, I already have created another function to change it from id to a seourl but I can't even get the basic number version working yet.
I have tried hundred of combinations of how to write my .htaccess file this is my current one which seemingly does nothing:
Options +FollowSymLinks
RewriteEngine on
RewriteRule cms/index/id/(.*) cms/index.php?id=$1
RewriteRule cms/index/id/(.*)/ cms/index.php?id=$1
How my urls are dynamical created:
$sqlCommand = "SELECT id, linklabel, seourl FROM pages WHERE showing='1' ORDER BY pageorder ASC";
$query = mysqli_query($myConnection, $sqlCommand) or die (mysqli_error());
$menuDisplay = '';
while ($row = mysqli_fetch_array($query)) {
$pid = $row["id"];
$linklabel = $row["linklabel"];
$seourl = $row["seourl"];
$menuDisplay .= '<a href="index.php?id=' . $pid . '">' . $linklabel . '<a><br .>';
}
mysqli_free_result($query);
Does anyone have any idea or solutions on what I could be doing wrong?
Thanks
How about:
RewriteRule cms/([/d]+) cms/index.php?id=$1

Apache: just rewrite if external ressource exists

I use Apache as a reverse proxy. There is no web content on the dedicated server itself. If a client requests a resource on the local Apache server, Apache should determine on which remote (proxied) server the resource exists and do a proxy rewrite to that server.
A snippet should (that currently does not work) should demonstrate, what i would do:
RewriteCond http://200.202.204.11:3000%{REQUEST_URI} -U
RewriteRule ^(.*)$ http://200.202.204.11:3000$1 [P]
I spared out the rest of my configuration (ProxyPass, ProxyPassReverse, other RewriteCond,...) to focus on my problem:
How could I check if an external resource exists / is available before rewriting?
The -U option for RewriteCond returns alwas true. The -F option returns alwas false. Is there a working solution for my intent?
After searching for weeks to get the solution I come to the conclusion: there is no reliable RewriteRule if an external ressource exists.
You go much better if you address your service behind an reverse proxy via subdomains. E.g. 'gitlab.youdomain.net' if you want to address a ressource on your gitlab server behind your reverse proxy. So the reverse proxy does not become confused if the ressource is lying in the root directory '/' of the gitlab server.
I had the same problem but, as far as I know, I got same results: it is not possible do it using only Apache httpd directives (at least with the version 2.2).
In my solution I did it using a RewriteMap and a PHP script able to check if the external resource exists.
In this example, when a new request comes, RewriteMap check the existence of requested path on Server A and, if successfully found, it reverse proxy the request on same server.
On the other hand, if the requested path is not found on Server A, it implements a rewrite rule to reverse proxy the request on serverB.
As said, I have used a RewriteMap with MapType prg: and a PHP script.
Here the Apache directives:
# Please pay attention to RewriteLock
# this directive must be defined in server config context
RewriteLock /tmp/if_url_exists.lock
RewriteEngine On
ProxyPreserveHost Off
ProxyRequests Off
RewriteMap url_exists "prg:/usr/bin/php /opt/local/scripts/url_exists.php"
RewriteCond ${url_exists:http://serverA%{REQUEST_URI}} >0
RewriteRule . http://serverA%{REQUEST_URI} [P,L]
RewriteRule . http://serverB%{REQUEST_URI} [P,L]
Here comes the interesting and tricky part.
This is the url_exists.php script, executed by Apache. It is waiting on the standard input stream and write into standard output.
This scripts return 1 if the resource is found and readable, otherwise 0.
It is so light even because it implements only an HTTP request using the HEAD method.
<?php
function check_if_url_exists($line) {
$curl_inst = curl_init($line);
curl_setopt( $curl_inst, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt( $curl_inst, CURLOPT_LOW_SPEED_LIMIT, 1);
curl_setopt( $curl_inst, CURLOPT_LOW_SPEED_TIME, 180);
curl_setopt( $curl_inst, CURLOPT_HEADER, true);
curl_setopt( $curl_inst, CURLOPT_FAILONERROR, true);
// Exclude the body from the output and request method is set to HEAD.
curl_setopt( $curl_inst, CURLOPT_NOBODY, true);
curl_setopt( $curl_inst, CURLOPT_FOLLOWLOCATION, true);
curl_setopt( $curl_inst, CURLOPT_RETURNTRANSFER, true);
$raw = curl_exec($curl_inst);
curl_close($curl_inst);
return ($raw != false) ? true : false;
}
set_time_limit(0);
$keyboard = fopen("php://stdin","r");
while (true) {
$line = trim(fgets($keyboard));
if (!empty($line)) {
$str = (check_if_url_exists($line)) ? "1" : "0";
echo $str."\n";
}
}

Simple MVC mod-rewrite

I'm not sure how to do a mod-rewrite for a modular MVC structure. What I want to happen is the URL captures:
http://domainname.com/index.php?model={model}&view={view}&parameters={parameters}
NOTE: parameters will be in a specific order and separated by pipes (unless there is a better way):
parameters=param1|param2|param3
http://domainname.com/{model}/{view}/{parameters}
Example:
http://domainname.com/faq/edit/13
Another Example:
http://domainname.com/faq/index/{sort}/{page}/{search}
http://domainname.com/faq/index/asc/3/How+to
Essentially anything after the model and view will and can be parameters; as many as needed. For each view I will know the possible parameters that area allowable and in what order.
Thank you in advance.
--
Using the code below this is what I have:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)/(.*) index.php?model=$1&view=$2&parameters=$3 [L,NS]
URL: http://localhost:8888/testing/faq/index/asc/5/How+to
PHP $_GET variables:
Array
(
[model] => faq/index/asc
[view] => 5
[parameters] => How to
)
Should be:
Array
(
[model] => faq
[view] => index
[parameters] => asc/5/How to
)
Please help
You could use a PHP function to do that. Quickly, with no default value or error handling:
list( $controller, $function, $params ) = explode( '/', $uri, 3 );
$params = explode( '/', $uri );
And in the .htaccess, redirect any non-existing query to your PHP query-handling file:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ mvc.php [L,NS]
Beware to filter your input though, not to include any file, etc.
You could also have your htaccess like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)/(.*) mvc.php?model=$1&view=$2&parameters=$3 [L,NS]
This is just another way to do it, although personally I prefer streetpc's way.

Resources