Getting Started with Solar

To get Solar up and running for the first time, follow these steps:

  1. Download and install Solar

  2. Determine your document root, URI base, and include-path

  3. Place a config file outside your document-root

  4. Place an index.php bootstrap file in your document-root

  5. Create a symlink or alias to Solar public files in your document-root

  6. Browse to your installation

  7. Optionally, for "nice" URIs, place a .htaccess mod_rewrite file in your document-root.

Download and Install Solar

You can read full instructions for downloading and installing here. In short, you can use PEAR to install like this:

$ pear channel-discover solarphp.com
$ pear install Solar/Solar-@package_stability@
...

Document Root, URI Base, and Include Path

The document root (hereinafter referred to as $DOCROOT) is the root of your web directory in the file system, where the index.php bootstrap file will be located. This may be the top-level web root, or a subdirectory or user-directory.

The URI base (aka $URIBASE) is the initial portion of all URIs that point to $DOCROOT.

Some examples include:

http://example.com/index.php
$DOCROOT = '/var/www/htdocs'
$URIBASE = '/'
http://example.com/~username/index.php
$DOCROOT = '/home/username/public_html'
$URIBASE = '/~username'
http://example.com/~username/foo/bar/index.php
$DOCROOT = '/home/username/public_html/foo/bar'
$URIBASE = '/~username/foo/bar'

The include-path (hereinafter referred to as $INCPATH) is where the Solar.php and Solar/ directory are located. Typically this is the same as the PEAR PHP directory (e.g., /usr/local/share/pear/php). While $INCPATH may be in the web root, for security reasons, it should not be in the web root.

Special Note: If the URIBASE is not set properly, the front-controller won't know where the "prefix" base portion ends, and where the controller-name part of the URI begins. This will cause it to not-find the controller class.

Config File

Solar uses a single config file to set itself up. Although this file may be in the document root, for security reasons it should not be in the document root.

You can create a very simple config file using TextMate (or the text editor of your choice.)

$ cd /path/to/config
$ mate Solar.config.php

At a minimum, the config file should tell Solar the base path for URIs so it can build links properly.

<?php
$config = array();

// Base action href
$config['Solar_Uri_Action']['path'] = '$URIBASE/index.php';

// Base public directory href
$config['Solar_Uri_Public']['path'] = '$URIBASE/public';

// Done!
return $config;
?>

Note that the config file builds a normal PHP array, then returns that array at the end of the file. This is because Solar reads the file in a limited scope so that variables are not exposed to the global name space.

Bootstrap Script

Now that you have Solar installed in your include-path, and you know where the web root is, place a "bootstrap" index.php script in the document root to connect the document root to your Solar installation.

$ cd $DOCROOT/
$ mate index.php

The index.php bootstrap script will start Solar and pass control over to a front-controller object. It should look something like this:

<?php
// $INCPATH is the the path to where Solar is installed,
// typically the PEAR PHP directory.
set_include_path($INCPATH);

// Load and start Solar.  Be sure to point to the proper
// location of your Solar.config.php file.
require_once 'Solar.php';
Solar::start('/path/to/config/Solar.config.php');

// Instantiate and run the front controller.
$front = Solar::factory('Solar_Controller_Front');
$front->display();

// Done!
Solar::stop();
?>

Symlink to Public Files

For security reasons, it is best to install Solar outside the document root. However, browsers still need access to "public" resources that are part of Solar; these include CSS stylesheets, images, JavaScript files, and so on.

The easiest way to make sure these files are available through the document root is to place a symlink or alias to the Solar public resources.

$ cd $DOCROOT
$ mkdir public
$ cd public
$ ln -s $INCPATH/Solar/App/Public/ Solar

At this point, your document root should look something like this:

$DOCROOT/           # document root
    index.php       # bootstrap file
    public/         # public directory
        Solar/      # symlink or alias to Solar/App/Public/

If you cannot symlink or alias, you may copy the public files to the $DOCROOT/public/Solar directory, but then you will need to re-copy all the public files each time you upgrade your Solar installation.

We use the public/Solar/ subdirectory so that other vendors with Solar-style organization can use the same directory for their own public resources.

Browse To Your Installation

You should now be able to browse to http://example.com/$URIBASE/index.php/hello and see the text "Hello World!".

Mod_Rewrite

Having 'index.php' in your URIs is kind of inelegant. To get prettier URIs, you can optionally add a .htaccess file in your document root to turn on mod_rewrite. This will automatically take requests for files that don't exist and pass them through the index.php bootstrap script.

First, edit your config file ...

$ cd /path/to/config
$ mate Solar.config.php

... and remove 'index.php' from the base action URI:

<?php
// Base action href without mod_rewrite:
// $config['Solar_Uri_Action']['path'] = '$URIBASE/index.php';

// Base action href *with* mod_rewrite:
$config['Solar_Uri_Action']['path'] = '$URIBASE/';
?>

Then, edit a new or existing .htaccess file in your $DOCROOT ...

$ cd $DOCROOT
$ mate .htaccess

... and add these commands:

# turn on rewriting
RewriteEngine On

# turn empty reqests into requests for "index.html",
# keeping the query string intact
RewriteRule ^$ index.html [QSA]

# for all files not found in the file system,
# reroute to "index.php" bootstrap script,
# keeping the query string intact.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

You should now be able to browse to http://example.com/$URIBASE/hello and see the text "Hello World!".

Nginx

You can set up pretty URIs on nginx with the following code inside your server declaration:

location / {
    root   /path/to/your/docroot/;
    index  index.php;

    # This matches the requested file to a .css extension so it 
    # won't be processed as php even if the file is missing.
    if ($request_filename ~ ^.*\.css$) {
        break;
    }

    # Matches any file/directory/link that doesn't exist (-e), 
    # prepends index.php to the query string (assuming your 
    # index.php is at the root) so that the location below
    # matches and is handed off to the fast CGI handler.
    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php/$1 last;
        break;
    }
}

# Matches a query string where index.php is at the root
# (change if your solar system has a non empty $URIBASE)
# and hands off those requests to the php fast CGI handler.
location ~ ^/index\.php.*$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_param  SCRIPT_FILENAME  /path/to/your/docroot$fastcgi_script_name;
    include /etc/nginx/fastcgi_params;
}

Fatal error: Maximum function nesting level of '100' reached, aborting! in C:\AppServ\www\solar\Solar.php on line 325? what?