How to solve the case when users surf to index.php - php

In Zend framework, using the MVC, if A user surf explicitly to http://base/url/index.php instead of just http://base/url, The system thinks the real base url is http://base/url/index.php/ and according to that calculates all the URLs in the system.
So, if I have a controller XXX and action YYY The link will be
http://base/url/index.php/XXX/YYY which is of course wrong.
I am currently solving this by adding a line at index.php:
$_SERVER["REQUEST_URI"]=str_replace('index.php','',$_SERVER["REQUEST_URI"]);
I am wondering if there is a built-in way in ZF to solve this.

You can do it with ZF by using Zend_Controller_Router_Route_Static (phew!), example:
Read the manual page linked above, there are some pretty good examples to be found.
$route = new Zend_Controller_Router_Route_Static(
'index.php',
array('controller' => 'index', 'action' => 'index')
);
$router->addRoute('index', $route);
Can't say I totally disagree with your approach. That said, others may well point out 5000 or so disadvantages. Good luck with that.

Well it really depends on how you want to solve this. As you know the Zend Frameworks build on the front controller pattern, where each request that does not explicitly reference a file in the /public directory is redirected to index.php. So you could basically solve this in a number of ways:
Edit the .htaccess file (or server configuration directive) to rewrite the request to the desired request:
RewriteRule (.*index.php) /error/forbidden?req=$1 // Rewrite to the forbidden action of the error controller.
RewriteRule index.php /index // Rewrite the request to the main controller and action
Add a static route in your bootstrapper as suggested by karim79.

Use mod_rewrite. Something like this should do it:
RewriteRule ^index.php/(.*)$ /$1 [r=301,L]

I don't think you should use a route to do this.
It's kind of a generic problem which shouldn't be solved by this way.
You better should have to do it in your .htaccess, which will offer you a better & easier way to redirect the user to where you want, like to an error page, or to the index.
Here is the documentation page for the mod_rewrite

I've never faced this problem using Zend Framework. just do not link to index.php file. that's it. and when your are giving your application's address to users, just tell them to go to http://base/url/
when the user enters http://base/url/ her request URI is base/url and your .htaccess file routs the request to index.php, but the request IS base/url. you do not need to remove 'index.php' from the request. because it is not there.
when you are trying to generate URLs for links and forms and ..., use the built-in url() view helper to generate your links. like this:
// in some view script
<a href="<?php
echo $this->url( array('controller'=>'targetController','action'=>'targetAction') );
?>" >click</a>
do not worry about the link. Zend will generate a URL for you.

The way I look at this is that if I have a website powered by PHP and a user goes to http://site/index.aspx then I would send a 404.
Even though index.php does exist in theory, it's not a valid URL in my application so I would send a 404 in this case too.

Related

.htaccess How to routing from /a/b/c.php to /a/c.api

I am very newbie on .htaccess and such a things
i really need to route my files
when accessed :
http://blabla/api/bla.api
but the real file source is
http://blabla/api/files/test/test.php
if i use Fat-Free-Framework, that might be possible.
but how to implements it on .htaccess ??
Thanks!
i think that you're mixing up some stuff ...
.htaccess file cannot real route an uri . You can redirect, rewrite, ... but real routing is not an option, you just make your URI 'nicer' to read
A router (usually) will talk to controller witch will fetch, calculate, do stuff and pass the result to a view that will generate your page with the info passed from controller.
But anyway, here are some code snippets for redirecting with .htaccess or/and follow this tutorial for .htaccess redirects and easy php example that gives you more power to supports more complex logic.

How to make a URL link like this http://stackoverflow.com/questions/tagged/php [duplicate]

When you edit a question on stackoverflow.com, you will be redirected to a URL like this:
https://stackoverflow.com/posts/1807421/edit
But usually, it should be
https://stackoverflow.com/posts/1807491/edit.php
or
https://stackoverflow.com/posts/edit.php?id=1807491
How was
https://stackoverflow.com/posts/1807421/edit
created?
I know that Stackoverflow.com was not created by using PHP, but I am wondering how to achieve this in PHP?
With apache and PHP, you might perform one of your examples using a mod_rewrite rule in your apache config as follows:
RewriteEngine On
RewriteRule ^/posts/(\d+)/edit /posts/edit.php?id=$1
This looks for URLs of the "clean" form, and then rewrites them so that they are internally redirected to a particular PHP script.
Quite often rules like this are used to route all requests into a common controller script, which might do something like instantiate a "PostsController" class and ask it to handle an edit request. This is a common feature of most PHP application frameworks.
It's called routing. Take a look at tutorials on the subject.
If you use a framework such as cake php it should be built in.
As #mr-euro stated you can use mod_rewrite but front controller is a far better solution.
You force every request to index.php and you write your application controlling in index.php.
You use Apache's .htaccess/mod_rewrite, and optionally a PHP file, which is the approach I like to take myself.
For the .htaccess, something like this:
RewriteEngine On
RewriteRule ^(.*)$ index.php
Then in your PHP file, you can do something like this:
The following should get everything after the first slash.
$url = $_SERVER['REQUEST_URI'];
You can then use explode to turn it into an array.
$split = explode('/', $url);
Now you can use the array to determine what to load:
if ($split[1] == 'home')
{
// display homepage
}
The array is starting from 1 since 0 will usually be empty.
It's indeed done by mod_rewrite, or with multiviews. But i prefer mod_rewrite.
First: you create a .htaccessfile with these contents:
RewriteEngine On
RewriteRule ^posts/([0-9])/(edit|delete)$ /index.php?page=posts&postId=$1&action=$2
Obvious, mod_rewrite must be enabled by your hostingprovider ;)
Using mod_rewrite this can be achieved very easily.
I am poor at this but i do know you can redirect urls using apache mod_rewrite and by touching config files. From what i remember htaccess can be used to redirect. Then internally when the user hits
http://stackoverflow.com/posts/1807421/edit it can use your page http://stackoverflow.com/edit.php?p=1807421 instead or whatever you want.
You could use htaccess + write an URI parser class.

Apache - Redirect All Traffic without ModRewrite

I'm trying to redirect all incoming requests to /index.php (except requests starting with ? like /?foo=bar)
ModRewrite could certainly solve this problem easily, but are there any other solutions?
For example I was thinking about creating a manual 404 page (in PHP) that would redirect to /index.php manually, but I'm not sure if/how this would work.
It would also be important to have the information from the original URI in index.php, e.g. when somebody is requesting domain.com/search-term then I need that information ("search-term") in index.php.
Interesting question. Even frameworks such as laravel will require a RewriteRule to push requests to index.php before doing any routing from within the framework itself.
I feel like to do a catch all as you are suggesting there would need to be some amount of Apache configuration changes.
your suggestion of redirecting the 404 page to index.php would work but the SEO implications id assume would be horrible. Any links to your site to any page other than index.php would give a 404 Not Found error in the HTTP headers (even though it shows index.php).
but.. with all that said, if you still want to do it that way, heres how you'd do it:
in .htaccess
ErrorDocument 404 /index.php
this will make your 404 not found page index.php
your redirect variables will be in the $_SERVER array and will be prefixed with REDIRECT_
print_r($_SERVER); from a redirect gives me (i removed any key value pairs without REDIRECT_ at the beginning):
Array
(
[REDIRECT_REQUEST_METHOD] => GET
[REDIRECT_STATUS] => 404
[REDIRECT_URL] => /blsah.html
)
so REDIRECT_URL would be what you would use to get "search-term" from domain.com/search-term
you can find a more complete list of the possible redirect variables here:
http://httpd.apache.org/docs/2.2/custom-error.html
You need to use some sort of routing component, such as those that exist in frameworks to handle redirect all routes. For example if you were using laravel 4 you could do something like this within the routes.php file:
Route::any('/', function(){
//Do Magic Stuff
});
Route::any('{all}', function($uri)
{
//Check query string here - redirect as necessary
if (stripos($_SERVER['QUERY_STRING'], '?') !== false)
//Redirect or do stuff depending on your use case
else
Redirect::to('/'); //Otherwise redirect to your homepage
})->where('all', '.*');
The all will match all routes and redirect them to the first route which would be your default. There are plenty of php frameworks out there that you could probably do this with or could even do it from scratch - this is just one framework that I find to be great to work with.
Credit to Jason Lewis: Get all routes, Laravel 4
Laravel Routing: http://laravel.com/docs/routing

How was a URL like http://stackoverflow.com/posts/1807421/edit created in PHP?

When you edit a question on stackoverflow.com, you will be redirected to a URL like this:
https://stackoverflow.com/posts/1807421/edit
But usually, it should be
https://stackoverflow.com/posts/1807491/edit.php
or
https://stackoverflow.com/posts/edit.php?id=1807491
How was
https://stackoverflow.com/posts/1807421/edit
created?
I know that Stackoverflow.com was not created by using PHP, but I am wondering how to achieve this in PHP?
With apache and PHP, you might perform one of your examples using a mod_rewrite rule in your apache config as follows:
RewriteEngine On
RewriteRule ^/posts/(\d+)/edit /posts/edit.php?id=$1
This looks for URLs of the "clean" form, and then rewrites them so that they are internally redirected to a particular PHP script.
Quite often rules like this are used to route all requests into a common controller script, which might do something like instantiate a "PostsController" class and ask it to handle an edit request. This is a common feature of most PHP application frameworks.
It's called routing. Take a look at tutorials on the subject.
If you use a framework such as cake php it should be built in.
As #mr-euro stated you can use mod_rewrite but front controller is a far better solution.
You force every request to index.php and you write your application controlling in index.php.
You use Apache's .htaccess/mod_rewrite, and optionally a PHP file, which is the approach I like to take myself.
For the .htaccess, something like this:
RewriteEngine On
RewriteRule ^(.*)$ index.php
Then in your PHP file, you can do something like this:
The following should get everything after the first slash.
$url = $_SERVER['REQUEST_URI'];
You can then use explode to turn it into an array.
$split = explode('/', $url);
Now you can use the array to determine what to load:
if ($split[1] == 'home')
{
// display homepage
}
The array is starting from 1 since 0 will usually be empty.
It's indeed done by mod_rewrite, or with multiviews. But i prefer mod_rewrite.
First: you create a .htaccessfile with these contents:
RewriteEngine On
RewriteRule ^posts/([0-9])/(edit|delete)$ /index.php?page=posts&postId=$1&action=$2
Obvious, mod_rewrite must be enabled by your hostingprovider ;)
Using mod_rewrite this can be achieved very easily.
I am poor at this but i do know you can redirect urls using apache mod_rewrite and by touching config files. From what i remember htaccess can be used to redirect. Then internally when the user hits
http://stackoverflow.com/posts/1807421/edit it can use your page http://stackoverflow.com/edit.php?p=1807421 instead or whatever you want.
You could use htaccess + write an URI parser class.

Zend Framework "under maintenance" page

I'm trying to figure out how to set up a holding/"under maintenance" page in Zend Framework for when I am upgrading the database or something and don't want anyone using the site. I'd like to have a static HTML page and have all traffic redirected to that.
I'd rather not use .htaccess and would like to do it via the bootstrap file.
Any ideas?
Thanks.
I've set Apache to show index.html in preference to index.php (which bootstraps the ZF). As long as you don't link directly to /index.php anywhere, then you can just drop in an index.html file, and it will show that in preference to the ZF site.
An alternative is to have an entry in your configuration .ini file, and as soon as you have read the configuration:
if ($config->maintenance) {
readfile(APPLICATION . '/../public/maintenance.html');
exit;
}
You may want to add another check in there for a particular IP address (your own) as well, so that you can get though even when everyone else is blocked.
I've done this by creating a plugin that check the validity of the request each time that a page is requested.
During the execution of the plugin in the "preDispatch()" you can analyze a variable from the config that it will hold your current status as active/under maintenance and let the request flow to the original destination or redirect it to a landing page for this purpose.
Code sample
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
// get your user and your config
if( $config->suspended && $user->role()->name != "admin"){
$request
->setModuleName( 'default' )
->setControllerName( 'index' )
->setActionName( 'suspended' )
->setDispatched(true)
;
}
}
You could check your configuration file for a maintenance_mode switch and redirect every request from within the bootstrap to your static html maintenance page.
I have a blog post that demonstrates how to do this. Setting up a maintenance page with Zend Framework
I would use plugin with dispatchLoopShutdown() and based on the config settings i would redirect the request to any controller you want.
I followed all of these suggestions to a TEE on Zend 1.12. I googled around. Tried using application.ini, setting the plugin path, using zend_loader_autoloader_resource(), using Zend_Loader_PluginLoader. NONE of these worked for me. I ended up writing a .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/maintenance\.php$
RewriteRule ^(.*)$ /maintenance.php [R=503,L]
This is why Zend is the worst framework. Tons of different options on how to do something simple, Official Documentation is extremely ambiguous and unclear, and nobody fully understands or can explain the correct way to do anything so I end up wasting an hour of my time trying to do things correctly.

Categories