Development

SymfonyPHPsuexec

You must first sign up to be able to contribute.

Version 2 (modified by markchicobaby, 10 years ago)
--

Running Symfony on a shared server, with PHPsuexec

For those running on a shared host with PHPsuexec, I have found the following information essential. (Note that for performance reasons, it is recommended to run Symfony on a virtual private server, and not on a shared server).

Note these permissions are only relevant to servers with PHPsuexec

This is because under PHPsuexec, the Apache service runs as the same user as the owner of the files. Thus it has full access to them, as it is the same user. If file permissions are set to to 600 on a different server, "permission denied" errors may result.

NOTE This guide requires access to the shared server command line

With PHPsuexec, we have several special requirements, which this document addresses:

  • If a server's default php.ini settings need to be overridden, then each folder that contains any PHP scripts must contain a custom php.ini file
  • Directories can't have more than 755 permissions
  • Files can't have more than 644 permissions

In this example, the public web directory is called public_html. This is the root web directory. This is where pages like CSS (cascading style sheets) and favicon are served from. We will set up our public_html directory with these permissions:

  • public_html directories 755
  • public_html files 644

Our Symfony directories contain all our Symfony libraries. The permissions should quite restrictive:

  • Symfony directories 700
  • Symfony files 600

Other special permission settings:

  • php.ini 600
  • .htaccess 644

If Symfony skeletons are created on the shared server (via telnet or SSH) (eg php symfony init-module), the file permissions for the created files may be incorrect for PHPsuexec. This is due to a combination of the default umask and Symfony's handling of permissions on newly created files and directories.

This discussion ignores what permissions Symfony sets for files it creates (e.g. via symfony init-project) and simply states how to set appropriate permissions. Instead, we assume that the project is "frozen" via the "symfony freeze" command, then ftped to the server. Permissions are then applied after the ftp to the server.

1. First, a quick note on shared server directory arrangements.

On a shared server its not a bad idea to move the Symfony libraries to the same level as the public_html folder. One possible configuration (described in the book in Chapter 19, "Modifying the Project Web Root" is as follows:

symfony/
  apps/
  batch/
...
public_html/
  images/
  css/
  index.php

This arrangement also simplifies our tasks, as the public_html and symfony directories will have different permissions applied.

2. If necessary, copy a custom php.ini file to each directory that requires it

Shared servers don't always have ideal settings for running Symfony. Here is a custom php.ini that was required to override some unsafe settings.

Check existing php.ini settings

To check the existing php settings on the server, place a function call to phpinfo() in a single php file called phpinfo.php, and point the browser to http://yoursite/phpinfo.php. This can also be called after the custom php.ini is installed to test it is working as desired. Once finished, remove phpinfo.php for better security.

File phpinfo.php contains one line:

<?php phpinfo() ?>

For a production server, we divert PHP error reporting to a file and turn off magic quotes (required on this example server) To override default settings, file php.ini contains:

; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc = Off

; Do not print out errors as a part of the output
display_errors = Off

; Log errors to specified file
error_log = /home/myuserid/php_error_log.txt

; error_reporting reporting level
error_reporting  =  E_ERROR|E_WARNING

IMPORTANT: REMEMBER TO REMOVE phpinfo.php ONCE php.ini IS WORKING AS DESIRED

Create list of directories that require a custom php.ini

This relies on some cool bash shell magic.

  1. Change directory into the directory above public_html/ and symfony/ (e.g. If the full path to public_html is /home/userid/public_html, then execute cd /home/userid
  2. Place the custom php.ini into this directory.
  3. Run the following commands:
find public_html -name '*.php'  -printf '%h \n' | sort -u > dirlist.txt
find symfony     -name '*.php'  -printf '%h \n' | sort -u >> dirlist.txt

Explanation

The first command searches everywhere in directory public_html for files that match wildcard "*.php". It prints out the directory in which that file is found. The output of this is piped to sort, duplicate entries are removed by the -u flag, and the result is stored in new file dirlist.txt. The second command does almost the same thing, except it starts in directory symfony and appends to dirlist.txt.

  1. dirlist.txt will now contain a list of all directories that contain a PHP script. Lets copy our custom php.ini into these directories with the following command:
for x in `cat dirlist.txt` ; do cp php.ini $x ; echo "Copied php.ini to $x" ; done; echo "Finished"; 

Explanation

Loop through the directories listed on each line of dirlist.txt, for each one copy php.ini into it.

  1. Now point a browser to http://yoursite/phpinfo.php and confirm the required settings are as desired.
  2. If all is OK, delete public_html/phpinfo.php

Set required file and directory permissions

From the same directory (parent directory of public_html/ and symfony/) run the following:

This will set all files and directories in symfony/ to be accessible only to the owner:

find symfony/ -type f -exec chmod 600 '{}' \;
find symfony/ -type d -exec chmod 700 '{}' \;

We're going to treat public_html a little differently. The reason for this is that it is set up very carefully by your shared host administrators. We will not touch the permissions on the actual public_html directory itself. Instead, lets cd into it first, and then run find on all files and directories inside it.

This will set all files and directories in public_html/ to be read accessible to everyone (except for php.ini):

cd public_html
find . -type f -exec chmod 644 '{}' \;
find . -type d -exec chmod 755 '{}' \;
find . -name php.ini -exec chmod 600 '{}' \;

The last line just tightens up security a bit; its actually pretty dangerous to blindly make all files 644, so please ensure there is nothing in public_html that should be visible to the general public. For example, if chmod 600 php.ini isn't run, then browsing http://yoursite/php.ini will reveal the contents of the custom php.ini file!

Please log any problems in the Symfony installation forum.