My Symfony 2 installation is on a shared hosting site. Directory structure:
public
|-- api // subdomain api.mydomain.com
|-- app
|-- bin
|-- m // subdomain m.mydomain.com
|-- src
|-- vendor
|-- www // symfony "web" folder
| |
| +-- app.php // front controller!
Folder www
is the main folder and it's the folder where the front controller resides. It's bounded to mydmain.com
or www.mydomain.com
. Subdmains like m.mydomain.com
or api.mydomain.com
are folders inside the public
one (i.e. m
or api
).
I've no SSH access but only FTP (no SFTP). The problem is not repeating the content of www
inside m
and api
folder. If I copy all the content from www
to api
(say) the front controller is working and I'm able to work with subdomains in Symfony 2.
What I've tried so far:
Creating a symlink api
poiting to www
folder. I've used the folling script placed inside www
folder:
<?php
var_dump(__DIR__); // /htdocs/public/www where script is executed
$target = '/htdocs/public/www';
$link = '/htdocs/public/api';
if(file_exists($link)) {
if(is_link($link)) {
echo "unlinking $link...";
var_dump(unlink($link));
echo "symlinking $link to $target...";
var_dump(symlink($target, $link));
} else {
exit("$link exists but not symbolic link\n");
}
}
echo readlink($link); // /htdocs/public/www correct!
echo exec('cd .. && ls -l');
Output:
/htdocs/public/www
unlinking /htdocs/public/api... bool(true)
symlinking /htdocs/public/api to /htdocs/public/www... bool(true)
/htdocs/public/www
drwxr-xr-x 7 nobody nobody 4096 Nov 25 18:57 www
Symlink is created but (this is strange) I'm not able to see it connection through FTP or with the file manager interface (web). Front controller doesn't work. Symlink it's there, I'm getting an error if I try to create a folder with the same name as the symlink.
How can I route all requests for api
folder to www
folder (or from api subdomain to www subdomain)? This solution seems not quite correct to me (why a 301 redirect for GET /users api.mydomain.com
)?
The is_link() function in PHP used to check whether the specified file is a symbolic link or not. The path to the file is sent as a parameter to the is_link() function and it returns TRUE if the filename exists and is a symbolic link, otherwise it returns FALSE.
Overview. Symlinks, or symbolic links, are “virtual” files or folders which reference a physical file or folder located elsewhere, and are an important feature built in to many operating systems, including Linux and Windows.
Yes, a symbolic link is a pointer to another location. This means that any changes you make are in fact updating at the target location.
I have exactly the same configuration, and got it work! The only difference is that I map api.domain.com to www.domain.com/api instead of your www.domain.com, so my api symlink points to www/api, not www.
You can use a modification of one of my scenarios described below that doesn't need a symlink:
First include the code to preserve HTTP/HTTPS protocol in redirections (I will assume this code for all of my examples):
RewriteEngine on
RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ - [env=proto:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ - [env=proto:http]
The redirection code:
RewriteCond %{HTTP_HOST} ^api\.domain\.com$ [NC]
RewriteRule ^(.*)$ %{ENV:proto}://domain.com/api/$1 [L]
This will redirect all requests api.domain.com/$1
to domain.com/api/$1
. Or you can just use http://domain.com/$1
if you wish.
EDIT: if you don't want to hardcode the domain, you can use %N backreferences:
# don't forget to use the HTTP/HTTPS handling code above
RewriteCond %{HTTP_HOST} ^api\.([a-zA-Z0-9-]+\.[a-zA-Z0-9-]+)$ [NC]
RewriteRule ^(.*)$ %{ENV:proto}://%1/api/$1 [L]
I) Regarding the symlink, it is strange that you don't see the symlink over the FTP. I see it in FileZilla as a directory (as if it was a hardlink). Try to install FileZilla (and use explicit FTP over TLS for safe authentication).
II) The Options +FollowSymLinks
must be enabled, but in most hosting environments you cannot set it yourself. Depends whether the hosting company allowed you this setting by AllowOverride Options
. You can easily find out:
Options +FollowSymLinks
to /htdocs/public/.htaccessIf this fails, you have to ask your hosting provider to either set Options +FollowSymLinks
globally, or allow AllowOverride Options
globally.
I have actually 4 scenarios (you can test them online on my domain) using different methods (suppose that the master directory is named /public as in your case):
1) avif.birds.cz redirects to birds.cz/avif/ (canonical) - solution with a symlink
/public/avif - symlink to /public/www/avif
/public/www/avif/.htaccess:
RewriteCond %{HTTP_HOST} ^avif\.birds\.cz$ [NC]
RewriteRule ^(.*)$ %{ENV:proto}://birds.cz/avif/$1 [L]
2) cap.birds.cz redirects to birds.cz/avif/some_url (doesn't need a symlink at all)
/public/.htaccess:
RewriteCond %{HTTP_HOST} ^(www\.)?cap\.birds\.cz$ [NC]
RewriteRule ^(.*)$ %{ENV:proto}://birds.cz/avif/cap_intro.php [L]
3) (www.)birds.cz/jpsp redirects to jpsp.birds.cz (canonical)
/public/jpsp - symlink to /public/www/jpsp
/public/www/jpsp/.htaccess:
RewriteCond %{HTTP_HOST} !^jpsp\.birds\.cz$ [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^(.*)$ %{ENV:proto}://jpsp.birds.cz/$1 [L]
4) www.rorysi.cz - alias domain served by the same tree (rorysi.cz must stay as canonical domain)
the PHP source for this domain is different, placed under /public/www/rorysi.
/public/www/.htaccess:
RewriteCond %{HTTP_HOST} ^(www\.)?rorysi\.cz$ [NC]
RewriteCond %{REQUEST_URI} !^/rorysi/ [NC]
RewriteCond %{REQUEST_URI} !=/rorysi [NC]
RewriteCond %{REQUEST_URI} !^/lib/ [NC]
RewriteRule ^(.*)$ %{ENV:proto}://www.rorysi.cz/rorysi/$1 [L]
Note: the lib dir contains PHP libraries and inline stuff, so I don't want this to be redirected.
Maybe some of those scenarios can be helpful or inspirative to you.
1) Make sure that you have
Options +FollowSymLinks
in your .htaccess file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With