Zend Framework, mod_rewrite and public dir in shared hosting

Here's a short tip for those who need to publish a Zend Framework project on a shared hosting. The typical project structure for a Zend Framework project is something like this:


The public directory contains all the files that should be directly accessible via the web server, so you must set your web server's document root to this directory.
The problem is, in most shared hosting setups you can't change the document root, and the root directory of your account (i.e. the uppermost level you see when you connect via FTP) is the public document root.

To solve this problem without changing the above directory structure, you can remove the .htaccess file from the public directory, and place this one in the root directory instead:

RewriteEngine On
RewriteRule ^\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]
RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^public/.*$ /public/index.php [NC,L]

This is an effective way to "move" the document root up one level to the public directory.

62 responses to "Zend Framework, mod_rewrite and public dir in shared hosting"

Thanks so much, helped a lot!!

Thank you for the tip, very helpful.

I can keep on developing Zend Framework projects on low-budget shared-hostings. Thanks so much, really interesting trick !!!

I am create .htaccess in project document root and delete .htaccess in public folder but sorry to say that its not working . you need to mention the location of index.php is it in public folder or document root .

You don't have to touch anything else. The index.php file remains in the /public folder.

Use your Technique i Get This result. Can you attached it. That will be helpful
Object not found!
The requested URL was not found on this server. If you entered the URL manually please check your spelling and try again.
If you think this is a server error, please contact the webmaster. Error 404

I tried your solution on a wamp installation but i've got a HTTP 404.
Any idea

I tried this, but it only kinda half-worked.
i'm using http://www.abc.com/TestProject
so I placed the .htaccess into the "TestProject" folder on my web host. The .htaccess didnt work for my host, so I modified it as such:
RewriteEngine On
RewriteRule ^\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /home/abc/public_html/TestProject/public/index.php [NC,L]
RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /home/abc/public_html/TestProject/public/$1
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^public/.*$ /home/abc/public_html/TestProject/public/index.php [NC,L]
Now if I type http://www.abc.com/TestProject/index.php it works. So does http://www.abc.com/TestProject/public/
However I get a Zend File not found error when I try http://www.abc.com/TestProject. Any help will be greatly appreciated.

> RewriteCond %{REQUEST_URI} =\"\" > RewriteRule ^.*$ /public/index.php [NC,L]
Why not:
RewriteRule ^$ public/index.php [L]

for zend within a folder you should use virtual hosts here's a link which provides a nice tutorial. http://johnbokma.com/windows/apache-virtual-hosts-xp.html

Great article and great setup! Thanks for the post. @Marius, some shared hosting environments do not allow for virtual hosts but instead only subdomains.

Many thanks! One question: If the project is not in the webroot zend, but in a subfolder?
Example webroot: - Files - Project zend --- .htaccess --- application --- library --- public --- tests
I tried to put the htaccess in the subfolder you reported zend project, but by error 404!
How can I fix? Thanks

@JellyBelly, I don't know, try moving the .htaccess file one level up (to the root), and replacing public/ with zendproject/public/ in the .htaccess rules.

I finally found what I wanted. Excellent guide.

RewriteEngine On RewriteRule ^\\.htaccess$ - [F] RewriteCond %{REQUEST_URI} ^\\/$ RewriteRule ^.*$ /public/index.php [R=301] #RewriteCond %{REQUEST_URI} !^/public/.*$ #404 error #RewriteRule ^(.*)$ /public/$1 #404 error RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^.*$ - [NC,L] #RewriteRule ^public/.*$ /public/index.php [NC,L] # 550 error what can i do

Thank you so much.

Hi Lorenzo, this snippet of code doesn't work in my case. It creates an infinite loop of redirects. Regards

I moved the file as you suggested and it did not work.
my site reside on a shared server and the root is inside a \\\'www\\\' folder
Any other ideas for how I can get this to work?
Thanks for any help.

I tried this on fresh install apache. I generated some \'Test\' project using Zend Tool. I applied these .htaccess settings in root folder: Test/.htaccess and I got:
- 404 error in browser - apache error log:
[Sat Jun 12 15:01:54 2010] [error] [client] File does not exist: C:/Users/Domowy/Desktop/Serwer/public, referer: http://localhost/ [Sat Jun 12 15:01:54 2010] [error] [client] File does not exist: C:/Users/Domowy/Desktop/Serwer/favicon.ico
I see that \'Test\' folder in path is missing. It should be: C:/Users/Domowy/Desktop/Serwer/Test/public .
Any suggestions? Please help me. This is making me freak :)

Thank you very much!!! It works!

I tested it on dreamhost and It works great. Thank you!

This does not work on godaddy. It creates an infinite loop.

infinity loop too.

I uploaded a ZF site on Media Temple and on Network Solutions using these .htaccess settings. On Media Temple it\'s working perfectly, but on Network Solutions an infinite loop happens. Does anyone have an idea how to solve the problem?
PS: a fragment of the log:
[Thu Sep 23 09:48:21 2010][error] [client xxx.xxx.xxx.xxx] Request exceeded the limit of 10 internal redirects due to probable configuration error. Use \'LimitInternalRecursion\' to increase the limit if necessary. Use \'LogLevel debug\' to get a backtrace. [Thu Sep 23 09:48:21 2010][debug] core.c(3063): [client xxx.xxx.xxx.xxx] r->uri = /~xxxxxxx.xxxxxxx/htdocs/public/public/public/public/public/public/public/public/public/index.php

I was following your tutorial (and quite new to Zend), but could not figure out how to switch between the default and admin modules.
I always get the default module when viewed from \"localhost:8081\", but get a 404 when try to go \"localhost:8081\\admin\". Any help is much appreciated!
Thanks! Richard.

Thank you verry much, you saved me!

I used your code and it works great on godaddy greetings from romania ;)

not working if using modules. i use wamp.

omg works like a charm. thank you soo much.

Yup, it did exactly as the op said it was going to do.

This worked like a champ. Glad someone was nice enough to post this <3 google.

Hi Thanks for the tutorial. I have a little challenge with IIS 7.5 i need to convert your above .htaccess file to match with the web.config file. Do you know a way around this?
moving my web.config file into the public folder works but the URL isn\'t nice: http://www.sitename/public/

Your solution has been a great help in depolying the zf application. I have separate css folder for admin module and default module. I am using the .htacess file that you have provided as is. The layout does not load css and images form subdirectories. It gives a 404 page
the css/image folder is public/default/images/logo.gif public/admin/images/logo.gif public/default/css/main.css public/admin/css/admin.css
<img src=\"<?php echo $this->baseUrl(\'default/images/logo.jpg\') ?>\" alt=\"\" width=\"243\" height=\"74\" /> <?php echo $this->headLink()->appendStylesheet(\'default/css/main.css\') ;?>
I am not just being able to fix the problem

I\'m using your mod_rewrite and it works perfectly as-is. However, if I try to access a folder from within my public directory, I\'m not able to (I receive a controller error). Is there a possible workaround for this?

thanks it works

ok for everyone who are still unable to solve this mystery, follow these steps:
1) Create an index.php file one level above the \"public\" folder i.e outside the \"public\" folder.
2) Open that index.php file and add the following line:
<?php include \'public/index.php\'; ?>
3) On the same path where you have your new index.php file, create an .htaccess file and add the following in it:
SetEnv APPLICATION_ENV development
RewriteEngine On RewriteRule .* index.php
4) The final step is to modify the baseUrl() function. To do the same, open the BaseUrl.php file from
Go to the baseUrl() function and modify the line that reads:
return $baseUrl . $file;
return $baseUrl . \'/public\' . $file;
5) You should be all set. If you still have issues setting this up, you can mailme {at} shouvik {dot} net

Seems like this thread is relevant to hosting with a single public root and no access to server root. I am wrong?
I am new to ZF. Trying to setup a testing env to simulate a shared vhost env with multiple URLs. Given the typical shared host config with a server root containing infrastructure folders (ftp, includes, etc) and a single public (WWW docroot) folder, where do the zf site files go? Are you putting the zf files at server root and only the public folder in the the doc root? I think the host is already using rewrite to launch parked URLs. Seems like with multiple URLs things could get pretty messy.
Anyone got a map for this kind of environment?

Doenst work neither here, gives an 404 error :)

Thanks a lot.. You save the day!!!

Kind Help needed
Am having an issue after deploying my zend project on my host server. am having 404 error for my css files (not found)as my path for my stylesheet is relative <link href=\'/skin/blues/css/layout.css\' type=\"text/css\" rel=\"stylesheet\"> i have followed the tutorial http://akrabat.com/zend-framework/zend-framework-on-a-shared-host
if i refered an absolute path for css file it works , but i dont the path to my css files to be absolute, i want it to be relative.
eg with absolute path it works <link href=\'/myzendproject/public/skin/blues/css/layout.css\' type=\"text/css\" rel=\"stylesheet\"> however it it need to be <link href=\'/skin/blues/css/layout.css\' type=\"text/css\" rel=\"stylesheet\">
my ftp is in following structure
/ /myzendproject /application /public .htacess index.php /cgi .htaccess
thank u for helper

Thanks for this info - it was definitely helpful to me.
One question I would like to ask is what rule would you need to place in the .htaccess to handle the following case of URL typed by the visitor: http://website.com/index.php ?
When it\'s just http://website.com/, or http://website.com/public/, etc., the rewrite rules from the top of this page work out fine, but in the case of the user typing in the home page file name, it doesn\'t appear to redirect to http://website.com/public/index.php like it does in the other cases.

In regard to my previous post:
I\\\'ve just been learning about the mod_rewrite functionality, and today I happened upon a solution to my previoulsy mentioned problem that I thought I would share with everyone.
A Redirect statement can send a URL like http://example.com/index.php to one of the cases covered by the mod_rewrites, so you could say something like the following in the .htaccess:
Redirect /index.php http://example.com/
and then the mod_rewrite statements will handle it from there.

Cool post, any way to force \"www\" in the url every time for SEO purposes a la http://www.mattfarina.com/2007/07/24/www-or-no-www-seo-question?

Thank you! It worked for me! Make sure your hosting has AllowOverride directive of Apache set to All.

Great! Yoy saved my day

Thanks for this nice solution, it worked for me :) Example: http://www.keesschepers.nl/pikegrid/

hi there lorenzo, this article help me a lot, with a zend application godaddy hosted. also i have to add the APPLICATION_PATH when calling some code with require or include.

This script fails when zend is placed in a subdirectory in the server. You can replace all public with subdir/public, but it still fails due to zend mistaking the base url as subdir.
I\'m not a rewrite wizard and don\'t understand why this happens. But adding the following to [production] in application.ini can be a workaround:
resources.frontController.baseUrl = \"/subdir\"

Thank you for that. But on plesk (version 10 in my case), I change in vhost.conf the webroot to /.../httpdocs/public to make sure there is no way to access other zend directories like library etc. from outside.

I\'m rather new to zend and to hosting. I got the application working on a shared dreamhost account without a htaccess file and navigating to the public folder. The files are in the myDomain.com/project/app folder.
When I place the .htaccess file from above to the app-folder I get a 404 Not Found page.
Any idea on what I need to do to get this working?

Hi there
This worked for me...just have a question: Is is possible to have links like www.domain.com/contact-us, instead of www.domain.com/public/contact-us ??

Thank you so much for that! Works fine for me, after hours of false tryouts... Regards, Tilo

Thanx a lot! Really works!
>>Is is possible to >>have links like www.domain.com/contact-us, instead of >>www.domain.com/public/contact-us ?? Place this file in Controller Folder (sure you need to rewrite it by MVC ideology) then setup your Zend_Router at config or bootstrap. It takes for ten minutes and the most right way

It worked for all my controllers except for the one named Publications which has a uri of http://mysite.com/publications Can the regex be tightened up to avoid this problem?

Can i use this same procedure to set up zend in localhost local pc ?

Thanks a lot, it was more than helpful.

Hi! This work only for default module, but not work for other modules! ex: admin module! If i go to www.domain.com/admin where admin is module, i\'m redirected to www.domain.com/public/admin
how fix this please?

Thank you very much for great solution,, you save a lot of my time :)

This work for me:
My project is not allocated in root. i.e. \"localhost/myprojects/project\"
myprojects/ project/ .htaccess -->(a) application/ configs/ application.ini -->(b) public/ .htaccess -->(c)
#(a) RewriteEngine On RewriteRule ^\\.htaccess$ - [F] RewriteCond %{REQUEST_URI} =\"\" RewriteRule ^.*$ public/index.php [NC,L] RewriteCond %{REQUEST_URI} !^/public/.*$ RewriteRule ^(.*)$ public/$1 [L] RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^.*$ – [NC,L] RewriteRule ^public/.*$ public/index.php [NC,L]
;(b) application.ini resources.frontController.baseUrl = /myprojects/project/
#(c) RewriteEngine On RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ index.php [NC,L]

Hello Thank You 4 this helpfull tutorial. Have some questions, hope some one can help me: 1) Structure is html/zend_project and to use your snippet i created a subdomain. Now i need redirect http://subdomain.domain.com to http://domain.com How can i do it? 2) My hosting located to godaddy and have intermitent \"no input file specified\", i try different solution but nothing seems to solve my problem. Any idea? Thank You and here my htacess located in html/myproject

Matchless topic, it is very interesting to me )))) tHANKS www.alberton.info tEAM

Anche a me non funziona mi restituisce \"error 404\" il mio ambiente diTo me it does not work I would return \"error 404\" my test environment running under xampp, could this be the problem?
help me, please.
thank you in advance

Lorenzo Alberton

Lorenzo Alberton Lorenzo has been working with large enterprise UK companies for the past 10+ years and is currently CTO at DataSift. He's an international conference speaker and a long-time contributor to many open source projects. Lorenzo Alberton's profile on GitHub Lorenzo Alberton's profile on LinkedIN View Lorenzo Alberton's profile on PHP PEAR
View Lorenzo Alberton's Twitter stream Lorenzo Alberton - Sun Certified MySQL 5 Developer PHP5 ZCE - Zend Certified Engineer


AJAX, Apache, Book Review, Charset, Cheat Sheet, Data structures, Database, Firebird SQL, Hadoop, Imagick, INFORMATION_SCHEMA, JavaScript, Kafka, Linux, Message Queues, mod_rewrite, Monitoring, MySQL, NoSQL, Oracle, PDO, PEAR, Performance, PHP, PostgreSQL, Profiling, Scalability, Security, SPL, SQL Server, SQLite, Testing, Tutorial, TYPO3, Windows, Zend Framework
Buy me a book - Is It Just Me Or Is Everything Shit