PHP HipHop + rewrite to index.php - php

I wasted many hours to find, how to redirect all requests to index.php.
I mean:
site.com/some-url?param&1
will become
site.com/index.php and $_SERVER[REQUEST_URI] === some-url?param&1
I've one hip hop archive (based on Nette Framework) and one virtualhost (one hiphop isntance proxied from Nginx).
Edit:
Alternative question can be: how to setup nginx to modify REQUEST_URI field sent to PHP over FastCGI?

You have to add a rewrite rule to the main config.hdf file. hhvm does not support reading .htaccess files.
# In my app I have a public side and and admin
# side. All requests to the public side should
# be rerouted through a script. All requests to
# the backend .php and static asset files should
# be allowed.
* {
# rewrite every request onto
# /myapp/page.php/<original request>
pattern = ^(.*)$
to = /myapp/page.php/$1
# append any query strings.
qsa = true
}
I wrote an article about configuring hhvm.

If you use Nginx in front of HHVM then you probably want the static files to be served by Nginx (because it's faster) and everything else pass to index.php. In your Nginx site configuration you can do that as follows:
location / {
try_files $uri $uri/ index.php?$args;
}

I'm not familiar with HipHop but .htaccess on Apache can take care of this with RewriteRules

Related

Apache Redirect /api Requests To Directory

I come from a C# MVC background but I am currently working on a PHP project.
In C# you can setup decorators to specify the request URL using something along these lines:
[HttpGet]
[Route("/ControllerName/ActionName")]
public string MyAction() {
// ...
}
I am wanting to set something similar up in PHP, so I set my file structure like this:
+ assets
+ css
+ javascript
+ images
+ server
+ api
+ controllers
- index.php
+ ui
+ area1
- view1.html
- view2.html
+ area2
- etc.html
- .htaccess
- index.html
Where index.html is my login page, the other html pages live in their respective /ui/area directory, and my restful API pages live in /server/api/controllers. The /server/api/index.php follows a very similar pattern to this Stack Overflow answer: https://stackoverflow.com/a/1737903/1920035
In my .htaccess file, I have the following redirect rule setup:
# Redirect traffic starting with /api to the /server/api/index.php file
Redirect 301 ^(api/.*)$ /server/api/index.php [L,QSA]
The idea is that if I hit /api/account/get that it will redirect to the /server/api/index.php file and run its magic to run the respective controller/action.
The issue is that when I spin up my server and hit the pretty URL that it always returns a 500 response without any useful response text.
To complicate things, I'm running Docker for Windows using php:8.2.2-apache.
What am I doing wrong here? I do not have much experience setting up .htaccess files and with a vague 500 response, I don't have much to go off of.
You need to check Apache's error log for the details of the 500 error. However...
Redirect 301 ^(api/.*)$ /server/api/index.php [L,QSA]
This is syntactically invalid (which might account for the 500 error) and the wrong directive to use here. Redirect is a mod_alias directive that triggers an external redirect. [L,QSA] are "flags" used with the mod_rewrite RewriteRule directive. The Redirect directive does not take a regex as an argument (it uses simple prefix-matching).
But you shouldn't be triggering an HTTP external (301) redirect here, you need to internally rewrite the request instead (the user should not be aware of the underlying /server subdirectory).
For this (URL rewriting) you need to use mod_rewrite (so this needs to be installed if not already). For example:
RewriteEngine On
RewriteRule ^api/ server/api/index.php [L]
A request for /api/<anything> would be internally rewritten to /server/api/index.php.
No need for the capturing group and .* suffix on the original regex. So, ^api/ is essentially the same as ^(api/.*)$, but more efficient. The slash prefix on the substitution string (2nd argument) is not required with internal rewrites (and best omitted - so it is treated as a filesystem path and not a URL-path).
mod_rewrite (RewriteRule / RewriteCond directives) is capable of issuing (complex) external redirects as well as internal rewrites. mod_alias (Redirect / RedirectMatch directives) is for simple external redirects only. (Having said that, mod_alias also has some directives used for internal filesystem mapping.)
Reference:
https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule
https://httpd.apache.org/docs/current/mod/mod_alias.html#redirect

How to access directory's index.php without a trailing slash AND not get 301 redirect (NGinx)

I have been looking to rewrite my api URLs so they don't have a trailing slash. I use NGinx and not Apache. I did find this answer to the same question for an Apache server, but it is not going to work out of the box for NGinx.
I ended up taking this sample Apache config and used a config rewrite service to convert the config to Nginx format. It produces a mostly working, but slightly broken solution. It accesses the URLs like it is supposed to, but it breaks accessing resources and causes the /api/index.php to be dumped as a download when accessing a non-existent file or directory in /api/.
I played around with the config to produce the below config which uses the html 404 message provided to the whole server.
NGinx
location /api {
if (-e $request_filename){
rewrite ^/(.*[^/])$ /$1/;
}
}
My File structure is:
/api/index.php
/api/hotbits/index.php
/api/cryptography/index.php
With the new config option, this translates to these functional URLs:
/api
/api/
/api/hotbits
/api/hotbits/
/api/cryptography
/api/cryptography/

.html causes 404 error

I am running a joomla 2.5 site on ubuntu server with php/nginx/mysql (fairly new to nginx)
My problem is that when a user hits a url, I need it to ignore the .html file extension.
For example, if you hit mysite.com/page then it renders the page fine.
If you hit mysite.com/page.html then it will throw a 404 error. Which is because there isn't actually a 'page.html' page on my site. Its a K2 article alias. Yes, I could not put .html in but its not me adding content to the site, its the client. I have recently moved server and before it worked fine, now it doesnt so I know I have missed something in the config.
I know I can get nginx to do the opposite of what I want, with try files. Not sure how to get it to do the reverse.
This is my nginx config:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to index.html
try_files $uri $uri/ /index.php;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
Now I know if i had a page.html page and I wanted to hide the .html I could add $uri.html
What I want to know is how to get nginx to try page.html if it cant find it try page
So turned out to be a Joomla Config variable. Under SEO settings in global config set 'apply suffix' to yes. I feel quite stupid. Thanks to all those that tried to help, as always much appreciated.
Here's a potential solution I managed to come across:
location / {
# If /{foo} is not an existing file or directory, rewrite to /{foo}.html
if (!-e $request_filename) {
rewrite ^(.+)$ /$1.html break;
}
# Redirect all {foo}.html URLS to /{foo}
rewrite ^/(.*)\.html$ /$1 redirect;
}
If you can correctly write .htaccess rewrite lines, try using a htaccess-to-nginx converter
As commented, this will check for the existence of a directory, file, etc. using the current URL. If nothing exists, it will attempt to request the url with .html appended.
Additionally, if .html is already present in the URL, it will redirect to the URL without .html
Quick workaround:
rewrite ^(. *)\.html$ $1 break;
Should be the first rewrite in the stack, even before try_files.

Laravel quick start guide route not working

Ok I'm new to Laravel so went straight to the documentation to get started. There are massive holes in the documentation so it took a lot of effort and googling to fill the gaps in order to get Laravel set-up. I now have it set up and moved on to the next step in the quick start guide.I created my route
Route::get('users', function()
{
return 'Users!';
});
Now it says:
Now, if you hit the /users route in your web browser, you should see Users!
So I hit up:
http://localhost/laravel/users
but get a 404? I tried
http://localhost/laravel/public/users
but still a 404? I followed the steps on the quick start guide to the letter, what am I missing?
Seems like your Laravel app is accesible via an Apache HTTP alias, because your URL looks like: http://localhost/laravel/. If this is the case and assuming that http://localhost/laravel is pointing to your public directory, then follow these steps:
Try to navigate to your expected route prepend it with /index.php/, in your case: http://localhost/laravel/index.php/users. If it works (no 404) then you problem is with the Rewrite Module configuration of Apache HTTP, you should follow the next steps.
Edit the file public/.htaccess.
Under the line RewriteEngine On add RewriteBase /laravel/.
Try to navigate to an existing route.
Basically, if you app resides in a alias or virtual directory (say http://localhost/alias) you should add an entry in your rewrite rule to rewrite the base directory with alias.
The problem is well explained by Rubens above, A simpler solution is to use the supplied built-in PHP Server by issuing this command
php artisan serve --port=8080
Note that I am using port 8080 here, you can omit it.Now you can browse the site by going to
localhost/users
and it should work!
Apache isn't probably reading the public/.htaccess file due to the directive AllowOverride being set to None. Try to set it to All.
Laravel 4 simple route not working using mod_rewrite, and .htaccess
I had the same problem and spent hours to solve it.
I have several apps under the same domain, but in different segments. So Laravel's url is http://myhostname/mysubdir/
My controllers were only working as http://myhostname/mysubdir/index.php/mycontroller
On /var/www/.../public/.htaccess I put RewriteBase /mysubdir and worked!!!
I know this question is 4 years old but still it have its significance.Rubens Mariuzzo was answered it correctly but I want to add some points on it. You said
"There are massive holes in the documentation so it took a lot of effort and googling to fill the gaps in order to get Laravel set-up"
For beginners it is difficult to find correct way of configuring Laravel. Once it is mastered it is fun developing Laravel :) . There are certain correct way of doing this.
Download Laravel
Configure DB
Map DB in .env
Make auth: php artisan make:auth
Create model and migration together: php artisan make:model Todo -m
Migrate: php artisan migrate
Create controller and routes together: php artisan make:controller
TodoController --resource
Create view for each action
Code the controller
Detailed description is given in this blog http://masterlaravel.blogspot.in/2017/08/laravelquick-start-composer-create.html
please refer to this follow url and see RoboTamer's config:
http://forums.laravel.io/viewtopic.php?id=511
it solved my problem the same as yours
solution in nginx:
server {
server_name .laravel.dev;
root /home/tamer/code/laravel/public;
index index.php index.html;
#browse folders if no index file
autoindex on;
# serve static files directly
location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
access_log off;
expires max;
}
# removes trailing slashes (prevents SEO duplicate content issues)
if (!-d $request_filename)
{
rewrite ^/(.+)/$ /$1 permanent;
}
# enforce NO www
if ($host ~* ^www\.(.*))
{
set $host_without_www $1;
rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
}
# canonicalize codeigniter url end points
# if your default controller is something other than "welcome" you should change the following
if ($request_uri ~* ^(/lobby(/index)?|/index(.php)?)/?$)
{
rewrite ^(.*)$ / permanent;
}
# removes trailing "index" from all controllers
if ($request_uri ~* index/?$)
{
rewrite ^/(.*)/index/?$ /$1 permanent;
}
# unless the request is for a valid file (image, js, css, etc.), send to bootstrap
if (!-e $request_filename)
{
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
# catch all
error_page 404 /index.php;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/tmp/php.socket;
fastcgi_index index.php;
#include fastcgi_params;
include /home/tamer/code/nginx/fastcgi_params;
}
access_log /home/tamer/code/laravel/storage/logs.access.log;
error_log /home/tamer/code/laravel/storage/logs.error.log;
}
Thanks. Knowledge of the above by #rubens, and a comment by #GaryJ here made me do this to make it work from my Apache virtual hosts file.
Copied these lines from .htaccess file in laravel within node of the vhosts config.
Removed my .htaccess file (it was anyway not being applied, i am on a windows apache virtual host, laravel env)
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Better:
Later read #Ag0r0 's reply, that worked. i was missing the allow override, making the above neccessary. once allowoverride all was there, the default settings itself worked.
In my case (Ubuntu 14.04 LTS & Apache 2.2) I was stuck at #1 step of #Rubens' solution. I could see the page with this url: http://localhost/laravel/index.php/users but step #2 and others didn't work.
Also I've tried to add RewriteBase /laravel/public to .htaccess but it didn't work too.
Then I've set up a new virtual host with the help of this awesome tutorial: https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-virtual-hosts-on-ubuntu-14-04-lts (they rock with these tuts)
In addition to tutorial, I've set DocumentRoot (in example.com.conf file) like this:
DocumentRoot /var/www/laravel/public
Yes, public is the big deal here.
Btw, don't put RewriteBase /laravel/ to your .htacces file otherwise you'll get HTTP/500 error.
Now, I can see example.com/users page.
my previous post with the describtion of the problem was deleted, but it was similar to the situation that is described here.
anyway... simply i have tried all the possibilities that are described here as well as on other pages and I did not find solution to my problem.
The fresh installation of the Laraval simply did not worked.... after trying everythink from this post i decided to create yet another fresh installation and miracle happened this installation is actually working...
So my advice is: if you are not able to fix this problem just try to create another installation of the laravel and it might actually work.
This might be actually the easiest way how to fix your problem in case you are starting from the scrach.

Rewrite with Nginx and PHP fastcgi still sends old request_uri to backend (php and symfony)

I am trying to migrate a php-website running the symfony framework to nginx and php over fastcgi.
It all works well usining the Symfony howto from http://wiki.nginx.org/ but I run into trouble with a custom rewrite rule.
My goal is to rewrite urls of of the form /aaaa to /view/shorthand/aaaa. The request should then be handeled by php and symfony.
Old apache rewrite rule:
RewriteRule ^([0-9a-f]+)$ index.php/view/shorthand/$1 [L]
Nginx rules i have tried:
rewrite ^/([0-9a-f]+)$ /view/shorthand/$1 break;
rewrite ^/([0-9a-f]+)$ /index.php/view/shorthand/$1 break;
They all get sent to fastcgi but the request_uri still seems to be /aaaa since I get this error:
FastCGI sent in stderr: "Action "aaaa/index" does not exist" while reading response header from upstream
I have also tried using try_files without any luck. Please advice.
The problem is in default FastCGI variables set (fastcgi_params config file), where REQUEST_URI is equal to nginx's $request_uri. But if you carefully read Nginx documentation, you will notice the difference between $request_uri and $uri variables.
$request_uri = full original request URI (with arguments)
$uri = current URI in request, normalized
The value of $uri may change during request processing, e.g. when doing internal redirects, or when using index files. So, if you want to fix REQUEST_URI value before it passed to PHP, just change $request_uri to $uri?$args in fastcgi_params.
It's the way Nginx lead developer Igor Sysoev recommends in the official mailing list.

Categories