I have a very simple application where I intend to optionally accept a parameter on the index route such that the user can either go to http://example.com/ or http://example.com/somethingrandom I wish to be able to capture the somethingrandom as an optional parameter but I am having no luck. Here is my route:
$app -> get('/(:random)', function($random=null) use($app) {
... do some stuff
});
According to the Slim documentation, the / needs to be inside the parentheses. So try:
$app -> get('(/:random)', function($random=null) use($app) {
... do some stuff
});
So getting this working was not a lack of understanding of the slim framework but to do with my default apache2 setup on OS X. By default in later versions of OS X, PHP is not enabled. This was not MY issue but is part of the cause. I followed this tutorial to ensure my setup was correct. In addition to this article I had to uncomment the line that loads up the mod_rewrite module.
I then created a virtual host in /etc/apache2/extra/httpd-vhosts.conf
<VirtualHost *:80>
DocumentRoot "/Users/tbm/Sites/example.com"
ServerName shor.ty
<Directory "/Users/tbm/Sites/example.com">
Options FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>
and added 127.0.0.1 example.com www.example.com into my hosts file so that I was able to access the site with a domain name from my browser.
Last, thanks to enabling the mod_rewrite module, I created a .htaccess file that ensured that all requests go through index.php allowing the slim router to take over and display the correct page
Options -Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ /index.php [QSA,L]
Having done all this I was then able to solve my problem using the following syntax
$app -> get('/(:random)', function($random=null) use($app) {
... do some stuff
});
The difference now is that when I visit a page at /some_string apache is told to rewrite the request and run index.php that then invokes slim to find the correct route and render the correct page. I hope this makes sense
Related
I am new to htaccess, and really bad with regex, so here goes nothing...
I am building a pretty simple and basic web application.
I have 5 pages, that handle everything in the application.
home.php
login.php
content.php
admin.php
error.php
home handles just the homepage; login handles just the login and account creation; content handles all the other pages in the site; admin handles just the admin portion that is behind the login; error handle errors - clearly
In order to achieve this I have had to work out some quirky htaccess rules. The login form is submitted via ajax, so that was the first hurdle.
I have gotten the login to successfully redirect to the admin portal and the admin portal will show up, but the logout will not work and none of the ajax functionality inside the admin portal will work.
here is my htaccess so far:
#I have no idea what this line does
Options -Indexes
# Turn on rewritting
RewriteEngine On
# This will get the admin portal to load it needs to go through the admin controller
# not content, but nothing inside admin works
# /admin - works!
# /admin/save, /admin/logout, /admin/getPage all fail and are submitted via ajax
RewriteCond %{REQUEST_URI} ^/(.*)/admin$
RewriteRule ^(.*)$ index.php?url=admin/default/ [L,NC,QSA]
# this let's the login form submission via ajax work successfully, otherwise it gets
# processed by the last rule as a content page - it needs to go through the login
# controller, not content.
RewriteCond %{REQUEST_URI} ^/(.*)/login/login$
RewriteRule ^(.*)$ index.php?url=login/login/ [L,NC,QSA]
# this handles all the other pages in the site successfully
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=content/default/$1 [L,NC,QSA]
I have been searching the internet for answers to this all day, and what I have may be completely wrong, if so please let me know, and let me know why and how to fix it (those last two are optional I suppose). Once I get this working, my application will be ready. All help will be sincerely appreciated.
A much better alternative to using a query string variable (like your url) is the following:
Parse each request through index.php
Read the URI path from the REQUEST_URI value of the $_SERVER global variable and the HTTP method from REQUEST_METHOD. Save them together with the values of the other global variables ($_POST, $_GET, etc) into a Request object (e.g. an instance of a class named, for example, Request).
Get a router like FastRoute (my personal choice) and build your routes list - read the docs please. Each route is defined as an object with a HTTP method, a pattern, and a handler (e.g. a controller method, e.g. an action) as properties.
Compare the request components (the HTTP method and the URI path from the Request object) with the components of each route object (the HTTP method and the pattern properties) in the routes list.
If a match is found, e.g. if the request components are the same as the ones of a route, then call the corresponding route handler, e.g. the controller action. Pass the Request object as argument, in order to be able to read the POST, GET, etc values.
Now regarding the configuration (for Apache 2.2):
First of all don't forget to deny the access to all folders!
<Directory />
Options None
AllowOverride None
Order deny,allow
Deny from all
</Directory>
Then the virtual host configuration would look something like this - where demoproj refers to the MVC project:
httpd-vhosts.conf
NameVirtualHost *:80
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/path-to/htdocs"
</VirtualHost>
<VirtualHost *:80>
ServerName local.demoproj
DocumentRoot "/path-to/demoproj/public"
Include "/path-to/httpd-vhosts-demoproj.conf"
</VirtualHost>
httpd-vhosts-demoproj.conf
<Directory "/path-to/demoproj/public">
Allow from all
# When off then RewriteRule directive is forbidden!
# ---------------------------------------------------------------------------------------------
# https://stackoverflow.com/questions/12120035/what-is-options-followsymlinks/26732503#26732503
# https://stackoverflow.com/questions/12120035/what-is-options-followsymlinks/12129326#12129326
# ---------------------------------------------------------------------------------------------
Options FollowSymLinks
# Activate rewriting engine.
RewriteEngine On
# Allow pin-pointing to index.php using RewriteRule.
RewriteBase /
# Rewrite url only if no physical folder name is given in url.
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite url only if no physical file name is given in url.
RewriteCond %{REQUEST_FILENAME} !-f
# Parse the request through index.php.
# -----------------------------------------------------------------------------------------------------
# https://httpd.apache.org/docs/current/rewrite/flags.html "RewriteRule Flags"
# https://stackoverflow.com/questions/45997912/exposed-folders-in-mvc-application/45998123#45998123
# https://stackoverflow.com/questions/2102128/mod-rewrite-what-does-this-rewriterule-do/2102189#2102189
# -----------------------------------------------------------------------------------------------------
RewriteRule ^(.*)$ index.php [QSA,L]
</Directory>
I think this is an easy one, but i'm really confused myself.
myproject.com/index.php shows my project main page
myproject.com shows my project main page too.
In 1st case, after routing it works fine (i.e. : myproject.com/index.php/register)
In 2nd case, after routing it fails (i.e. : myproject.com/register) with following error : The requested URL /register was not found on this server.
So because of that, i thought that i had to re-route every request for myproject.com to myproject.com/index.php
app/config/app.php :
'url' => 'http://127.0.0.1/public',
etc/httpd/conf/httpd.conf :
<VirtualHost *:80>
DocumentRoot "/var/www/html/myproject/public/"
ServerName myproject.com
</VirtualHost>
Nothing's been configured in hosts file.
Goal: how can i re-route all requests from myproject.com to myproject.com/index.php with hiding index.php part of from users ?
Visitors should see that : myproject.com
but i want them to actually reach : myproject.com/index.php
Workaround:
<VirtualHost *:80>
DocumentRoot "/var/www/html/myproject/public/index.php"
ServerName myproject.com
</VirtualHost>
Result : I cannot reach the assets, (js, css files) results with 404 because my browser is not allowed to reach myproject.com/public/. Root has been set as myproject.com/public/index.php in this virtualhost settings.
Check if the .htaccess file is present in your public directory.
If not check the Pretty Url Section.
Also make sure that you put <Directory> directives in your vhost configuration just to be on the safe side.
Eg:
<Directory "/var/www/html/myproject/public/">
AllowOverride All
Allow from All
</Directory>
Concerning the 'url' => 'http://127.0.0.1/public', in app.php am pretty much sure the /public is kinda extra.
'url' => 'http://127.0.0.1', should be working fine.
You need rewrite rules for this:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Laravel docs: http://laravel.com/docs/5.1#pretty-urls
I started a php project based on http://www.php-mvc.net/ and i searched on Google how to set up my WAMP Server to enable URL rewriting.
I'm running the latest version of WAMP.
1) Enable mod_rewrite module on httpd.conf
2) On httpd-vhosts.conf i added a virtual host
<VirtualHost *:80>
ServerName phpmvc.test
ServerAlias *.phpmvc.test
VirtualDocumentRoot "C:\wamp\www\phpmvc"
ErrorLog "logs\errors.log"
<directory "C:\wamp\www\phpmvc">
Options Indexes FollowSymLinks
AllowOverride all
Order Deny,Allow
Deny from all
Allow from all
</directory>
3) On my hosts file i added the host 127.0.0.1 phpmvc.test
4) On .htacces file i have this lines
RewriteEngine on
RewriteRule ^(.*)\/$ index.php?url=$1 [QSA,L]
I restarted Apache after setting up the files and when i went to phpmvc.test it worked fine but when i tried phpmvc.test/test it shows an error that says that the requested URL is not found on this server.
EDIT: I tried with RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] but it shows the same error
EDIT2: I tried with EDIT: I tried with Rahil Wazir suggestion but it stills not working.
I have this controller file IndexController.class.php and it works if i access with this URL: phpmvc.test?url=index but if i try phpmvc.test/index it says that index is not found on the server.
<?php
class IndexController {
public static function index() {
echo "Index controller";
}
}
Printing $_GET and $_SERVER on root i get an empty Array() and the server array. If i go to phpmvc.test/index?url=index i get the value on $_GET["url"] and on $_SERVER [QUERY_STRING] => url=index.
This is because Apache thinks /test is a file or directory which you are trying to accessing which probably don't exist.
You need to apply those two famous condition which is used by most Front controller pattern frameworks:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
Which tells Apache Rewrite Module unless the file or directory from the requested uri is exist then apply the rewrite rule, otherwise render the contents of the file or directory.
Debug by checking what you are getting in $_GET and $_SERVER variables.
print_r($_GET);
print_r($_SERVER);
Compare the differences in the values for ['url'] index.
Also, it may depend on your sub-folder depth as seen on the URL before /index.
I have three web servers on three separate computers. I am trying to install a php application that rewrites all url requests to index.php (front controller pattern). The following .htaccess works on two out of the three web servers:
RewriteEngine On
# Redirect everything to the Front Controller
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(css|images|files)/ index.php [NC,L]
So, when I visit http://example.com/hithere, index.php is called and I can then parse the originally requested url (hithere) to figure out what controller to send it to.
However, for some unknown reason, the above .htaccess file doesn't work on the third webserver. Instead, when I access http://example.com/hithere, I get a 404 not found error in my browser that says this:
The requested URL /full/path/to/application/index.php was not found on this server.
So, based on the above error, I can tell that it's actually trying to redirect to index.php. But the file that the browser lists in the /full/path/... below is actually on my web server - so I have no idea why it can't find it. Could someone please help me and tell me what I'm doing wrong?
Edit: I don't know if something in the httpd.conf could be conflicting, but here are the settings I have in httpd.conf for the directory that this application is in
Alias /myapp /full/path/to/my/app
<Directory /full/path/to/my/app>
Order allow,deny
AllowOverride All
Allow from all
</Directory>
Edit 2: I noticed something peculiar in the Apache logs. It looks Apache is appending index.php, which I am trying to redirect traffic to, to the DocumentRoot:
File does not exist: /document/root/full/path/to/my/app/index.php
When it should be going to:
/full/path/to/my/app/index.php
So I basically need to tell htaccess to ignore the document root. I tried this by specifying this in my .htaccess file:
RewriteBase /full/path/to/my/app/
But it's still searching the document root for index.php :/ Is there a way to reset the DocumentRoot or tell htaccess to ignore it when rewriting to index.php? Even when I use the absolute path in the RewriteRule, it still appends it to the document root.
RewriteEngine On
# Redirect everything to the Front Controller
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(css|images|files)/ /full/path/to/my/app/index.php [NC,L]
It doesn't make sense to me... Can someone please help?
Thanks
So, based on the above error, I can tell that it's actually trying to
redirect to index.php. But the file that the browser lists in the
/full/path/... below is actually on my web server - so I have no idea
why it can't find it.
Assuming it's a *nix alike system, you might want to check file permissions and make sure that the webserver has read access to the file.
You also need to check the DocumentRoot parameter in httpd.conf
Look for something like this in the file and make sure it's correct. That is also where apache will be getting it from.
DocumentRoot "/var/www/html/path/to/whatever"
Also I would disable SELinux if it's on and you really don't need it because it causes weird problems too.
First enable rewrite module in apache by using $ sudo a2enmod rewrite then restart web server by $ sudo systemctl restart apache2
Put following code in your virtual host.
<Directory /var/www/html/your_app_folder>
Order allow,deny
AllowOverride All
Allow from all
</Directory>
then add following code in your .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
I am working with a custom MVC PHP framework and the index page (acting as a router) receives a GET variable "do" which contains the path that it will route to. If this variable is not set, it defaults to the Auth controller, method login.
require_once('config.php');
$controllerAction = isset($_GET['do'])?$_GET['do']:"auth/login";
require_once('core/main.php');
Then the index page (source code above) passes this $controllerAction to the main.php file, which autoloads the main controller and then loads the requested controller.
Thus, the URIs in this framework are of the form mysite.com/?do=controller/method/variable and I need it to be in the form mysite.com/controller/method/variable.
Here is the .htaccess file I tried to use, it just didn't work (I have other htaccess files working on the same server so it's not an Apache problem) :(
RewriteEngine On
RewriteRule ^([^/]*)$ /?do=$1 [L]
Someone suggested that I can do this using PHP but I am not sure how to go about that.
Edit:
The error is that I get "This page cannot be displayed", 404 errors, whenever I try to directly access the mysite.com/controller/method links rather than the default mysite.com?do=controller/method
Further Edit
(please note that other virtual hosts work fine on my localhost):
(XAMPP) Apache Virtual Hosting Info:
<VirtualHost *:80>
DocumentRoot "D:\sites\mysite.com\root\wwwroot"
ServerName mysite.com
ServerAlias mysite.com
<Directory "D:\sites\mysite.com\root\wwwroot">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
File structure (Windows):
D:\
--sites
----mysite.com
--------#client_details
--------root
-----------#devfiles
-----------#vars_pwd
-----------wwwroot
--------------config
--------------core
--------------application
------------------controllers
------------------libraries
------------------models
------------------views
----------------------css
----------------------javascript
----------------------images
----------------------icons
First of all, there are some issues with your .htaccess contents. It's always a good idea to not rewrite if a file with the requested name exists. This allows you to have an img/ folder for your images or any other static content like css files, javascript, downloads, etc.. The first RewriteCond tells Apache to only rewrite if no folder with this name exists. The second one does the same with files. Then you probably want the QSA (i.e. Query String Append) option, which will pass all other GET variables to your script.
Under this conditions you can simplify the regex and use this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?do=$1 [L,QSA]
You might be surprised because this is more or less the same as others posted. I use similar things for many of my projects and I've just tested it, I can guarantee that it works. There must be something wrong with your apache config.
When you have problems with mod_rewrite, the first thing you should try is to enable the module itself. Type these commands as root in your shell:
a2enmod rewrite
/etc/init.d/apache2 restart
The first one activates the module (or complains with Module rewrite already enabled if everything is ok) and the second one restarts your Apache server. The path may of course be different on your server.
Then you have to make sure that your VHost config allows you to use .htaccess files and do rewrites. This means AllowOverride must be set to at least FileInfo (or All). You could also try to put the rewrite rules right into the config file. Your config should look similar to this:
<VirtualHost *:*>
ServerName test.example.com
ServerAlias www.test.example.com
DocumentRoot /home/sites/test/
<Directory "/home/sites/test/">
Allow from all
AllowOverride All
Options +Indexes
</Directory>
</VirtualHost>
Note that you have to restart Apache if you change anything in there.
If that all doesn't help, it's always a good idea to have a look at the error logs. On my system they're located at /var/log/apache2/error.log (debian). They might give you more information on what's going wrong.
Try
RewriteEngine On
RewriteRule ^([^/]*)$ index.php?do=$1 [L]
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?do=$1 [L]
Check your apache logs, access logs specifically. If the folder is present in the web root, then you should be able to access it directly :). You might also want to check if you have duplicate virtualhost entries for the same site by chance.
This one is my customized MVC framework which is based on cake
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?do=$1 [QSA,L]
</IfModule>
May be this should help. The typical URL pattern for this site.com/controller/method
I don't know what your domain setup is like, but here are some suggestions.
If your code resides in the root of your folder, and the index file is called index.php try the following:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?do=$1 [L,QSA]
If your website exists in a subfolder e.g. www.example.com/site/, and the index file is index.php Then try the following (change /site/ to whatever your folder is).
RewriteEngine On
RewriteBase /site/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /site/index.php?do=$1 [L,QSA]
If you still get the 404 error message then do the following:
Make sure your site allows .htaccess files to be processed by checking AllowOverride is set to all. If you don't have access to the necessary config files to check, a simple test is to setup an .htaccess rule to redirect to a dummy file on your system. If it works, then your .htaccess is being executed fine.
Have a look at your MVC framework to see what page it's actually sending the request to. The problem may be that you haven't defined a handler for that particular request, and the default action of your MVC framework is to throw a 404 error.
Edit: Just reading your description, I notice you said that the URL should basically be something like mysite.com/?do=controller/method/variable. If it has be very strict about this format, then you'll also need to put in rules for removing any leading or trailing slashes, e.g. the following re-write rule should do it:
RewriteRule ^\?(.*)\?$ /index.php?do=$1 [L,QSA]
(This makes the leading and trailing slashes optional, but it should remove them from the actual value you pass to do).