PHP Routing on Apache Server - php

The following code, in index.php, gives the expected routing behaviour when I run it using the built in php web server:
<?php
$request = $_SERVER['REQUEST_URI'];
switch ($request) {
case '/' :
echo 'This is the Home Page';
break;
case '/about' :
echo ' This is the About Page';
break;
default:
echo 'Resource not Found (404)';
break;
}
The same code uploaded to my Ionos Linux web server running Apache does not work: If I access the root directory from a firefox browser (eg http://mywebsites.org.uk/root-directory) I get Resource not Found (404)in the browser. If I append something to the URL (eg http://mywebsites.org.uk/root-directory/about) the browser just gives some page with advertising on which is what you get when there is nothing corresponding to that path on the server). Same happens if you change 'about' for any other word.
I tried with the following .htaccess file in the root directory along with the index.php file:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php [QSA,L]
Now I get the same result with http://mywebsites.org.uk/root-directory. That shows Resource not Found (404) in the browser as before. However, with http://mywebsites.org.uk/root-directory/about or any word substituting 'about' I now get an error message in the browser:
Multiple Choices
The document name you requested (/index.php) could not be found on this server. However, we found documents with names similar to the one you requested.
Available documents:
/index.html (common basename)
When I click on index.html (which is hyperlinked) I find that it is in the directory above the root-directory with the index.php file in it. Ie it is in the mywebsites.org.uk directory. Obviously it is not what I am after.
I also tried replacing the content of the .htaccess file with FallbackResource /index.php. The result was the same as when I had no .htaccess file at all which I described earlier.
I am finding it very difficult to understand my Ionos web server. I do not know if I can change configuration files for Apache or not and I have little understanding of .htaccess files. I have thought of changing to AWS over this issue as the documentation there seems more thorough. However I would prefer not to change if I can sort this issue out. Basically I want to be able to build a PHP router on my Ionos server which runs Apache.,

You are correct that the built-in PHP web server enables you to use a routing script. However, in environments such as your hosting on Ionos, this function is generally performed by whatever web server is running.
Unfortunately, I'm having trouble finding which web server Ionos offers by scanning their web site. Are you certain that they are running Apache and that they have mod_rewrite and local .htaccess overrides enabled? Any of these could explain why you're having issues there.
From your description of your issues, it also sounds like your web site may not have its document root path configured correctly, or that it is not set up to use index.php as a directory index file (e.g. via the DirectoryIndex Apache configuration setting).
The best I can suggest is contacting Ionos techical support or seeking out any technical documentation they offer to customers. I can't even tell if or what configurations they may allow you to override.

Related

Change Wordpress page URL with parameter

I have created a dynamic content page on my Wordpress site. The content is taken from the MySQL database and will be shown based on the GET URL parameter. I created this dynamic page by inserting a PHP code to a Wordpress Page (I use Advanced Ads plugin to insert the code)
I want to change the URL without an URL parameter.
Example:
DomainName.com/hotel-details/?hotelcode=First-Hotel
I want to change it to
DomainName.com/hotel-details/First-Hotel
or
DomainName.com/sometext/First-Hotel
I have tried to adding mod_rewrite to the .htaccess file in the root folder.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^hotel-details/([A-Za-z0-9-]+)$ hotel-details/?hotelcode=$1 [NC,L]
</IfModule>
But it seems doesn't work, when I access DomainName.com/hotel-details/First-Hotel I got an error 404 Page Not Found.
Any help much appreciated!
You are using the rule the wrong way 'round. Instead try that:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?hotel-details/(\w+)/$ /hotel-details/?hotelcode=$1 [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

How to change the link of a file in a sub-directory to be accessible from the root director?

I'm currently coding an Admin Panel, and for the sake of organization, I've made it so that all of the pages are located in a sub-directory instead of the root directory and I want to access these pages in the sub-directory from the root link. For example, the index.php is in the root directory and is accessible from:
http://localhost/index.php
But the rest of the pages are located in a sub-directory like so:
//What the current link is
http://localhost/pages/page.php
//What I want the link to be
http://localhost/page.php
Some of my pages are in sub-directories of the sub-directory like so:
//What the current link is
http://localhost/pages/page1/page.php
//What I want the link to be
http://localhost/page1/page.php
As you can see, I simply want to eliminate the primary sub-directory from the link, which is pages.
I've looked around on the internet and from what I can tell, this is achievable through .htacess but I couldn't find anything that worked.
You certainly won't find a perfect solution you can simply copy and paste to solve all your tasks. That expectation is a strange on. Instead you are expected to actually understand how the tools you want to use work and to be able to find your own solution. For that there really are enough good examples here on SO and in addition there is an __excellent_ documentation of apache's rewriting module available with just two mouse clicks.
Anyway, her is a suggestion, you still may have to tweak it to your situation:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)$ /pages/$1 [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

http://example.com/portal/p/Logon/ not working after migration (Apache, php)

I have migrated a dynamic website (php, mysql) to a new host on a shared server plan.
The site is fully dynamic and has no fixed paths as such apart from the single entry point file "portal.php". The site exists as path-info to portal.php and is created from templates in a mysql database. There is no /portal directory, for example.
The homepage loads fine, but not subpages.The pathinfo is returned correctly, but the webserver is not translating it I guess:
http://example.com/portal/p/Logon = Fails with 404 error
http://example.com/portal.php/p/Logon = Works!
I have limited control over the apache server as the client has a basic, shared server plan.
I tried various options in a .htaccess file at the root of the website directory, but the best I could do was get an internal 500 error. At least I know the .htaccess is being read.
I'm hoping I can resolve this, otherwise I will have to migrate the site to a dedicated server instead.
Ok I found a solution. I see now why my initial post lacked information :)
I read this guide:
https://httpd.apache.org/docs/current/content-negotiation.html
And after trial and error, the following worked with a .htaccess file placed at root (I modified a html5boilerplate .htaccess file):
Options -Multiviews
RewriteEngine On
RewriteBase /
RewriteRule ^portal/(.*) /portal.php/$1
RewriteRule ^portal$ /portal.php

How to protect my php files on the server from being requested

I'm very new to php and web , now I'm learning about oop in php and how to divide my program into classes each in .php file. before now all I know about php program, that I may have these files into my root folder
home.php
about.php
products.php
contact.php
So, whenever the client requests any of that in the browser
http://www.example.com/home.php
http://www.example.com/about.php
http://www.example.com/products.php
http://www.example.com/contact.php
No problem, the files will output the proper page to the client.
Now, I have a problem. I also have files like these in the root folder
class1.php
class2.php
resources/myFunctions.php
resources/otherFunctions.php
how to prevent the user from requesting these files by typing something like this in the browser ?
http://www.example.com/resources/myFunctions.php
The ways that I have been thinking of is by adding this line on top of every file of them exit;
Or, I know there is something called .htaccess that is an Apache configuration file that effect the way that the Apache works.
What do real life applications do to solve this problem ?
You would indeed use whatever server side configuration options are available to you.
Depending on how your hosting is set up you could either modify the include path for PHP (http://php.net/manual/en/ini.core.php#ini.include-path) or restricting the various documents/directories to specific hosts/subnets/no access in the Apache site configuration (https://httpd.apache.org/docs/2.4/howto/access.html).
If you are on shared hosting, this level of lock down isn't usually possible, so you are stuck with using the Apache rewrite rules using a combination of a easy to handle file naming convention (ie, classFoo.inc.php and classBar.inc.php), the .htaccess file and using the FilesMatch directive to block access to *.inc.php - http://www.askapache.com/htaccess/using-filesmatch-and-files-in-htaccess/
FWIW all else being equal the Apache foundation says it is better/more efficient to do it in server side config vs. using .htaccess IF that option is available to you.
A real-life application often uses a so-called public/ or webroot/ folder in the root of the project where all files to be requested over the web reside in.
This .htaccess file then forwards all HTTP requests to this folder with internal URL rewrites like the following:
RewriteRule ^$ webroot/ [L] # match either nothing (www.mydomain.com)
RewriteRule ^(.*)$ webroot/$1 [L] # or anything else (www.mydomain.com/home.php)
.htaccess uses regular expressions to match the request URI (everything in the URL after the hostname) and prepends that with webroot/, in this example.
www.mydomain.com/home.php becomes www.mydomain.com/webroot/home.php,
www.mydomain.com/folder/file.php becomes www.mydomain.com/webroot/folder/file.php
Note: this will not be visible in the url in the browser.
When configured properly, all files that are placed outside of this folder can not be accessed by a regular HTTP request. Your application however (your php scripts), can still access those private files, because PHP runs on your server, so it has filesystem access to those files.

Apache site root for development directories on localhost

I think I'm missing something and don't think I really understand how rewriteBase works.
The problem I have is that I have a production site where the site is in the root directory yet I have my development site in a localhost subdirectory. Eg http://www.sitename.com/ vs http://localhost/sitename/
If I have for example an images folder I want to reference the images from the site root by using the initial slash in the href. Eg Using a relative href (without the initial slash) is not an option. This will work on the production site but the development site is looking for http://localhost/images/imagename.jpg instead of http://localhost/sitename/images/imagename.jpg
So I thought all I needed to do was setup the following in my .htaccess file to force the site root to my subdomain within the development environment:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /sitename
But this still uses localhost as the site root instead of localhost/sitename.
Can anyone please give me some pointers?
-------------------------EDIT---------------------------
I stopped trying to do this in the .htaccess file and tried to just use the html command but this also didn't work.
In the end I set up Virtual Hosts in Apache on the local server but it seems like such an awful lot of overkill to just change the site root. I'm also concerned that other developers on the LAN network won't be able to access the site properly via the virtual host.
I'm really needing some 'best practice' advice please on setting up a workable development environment in WAMP.
RewriteBase alone, basically, tells Apache where to apply the RewriteRules. Here you don't have any. By the way, you can either remove the RewriteBase directive altogether, or change it to:
RewriteBase /
The following two lines should get it to work for your development environment only:
RewriteCond %{ REQUEST_FILENAME } !-f
RewriteRule ^(.+)$ /sitename/$1 [L,QSA]
These two directives mean: "if the requested file does not exist (-f), and only in that case, rewrite the url prepending /sitename/ to the requested URI ($1)".
For more info you can have a look at Apache mod_rewrite docs and Apache URL rewriting guide.

Categories