Category Archives: php

Use Composer with Kohana 3.3

Kohana 3.3 has a file named “composer.json” in the root of the project, however it is not configured for Kohana and Composer is not installed.

This example is tested on a Mac. Windows users will need to install Composer from the instructions on the Composer project site, at

Install Composer

First, modify composer.json to tell composer where to install libraries.


	"config": {
		"vendor-dir": "application/vendor"
	"require": {
		"phpunit/phpunit": "3.7.24",
		"phing/phing": "dev-master"

Open a terminal and navigate to the root of your Kohana project.

curl -sS | php
php composer.phar install

Modify Kohana’s bootstrap.php File

Add this to bootstrap. Right above the router configuration is a good spot.

 * Autoload composer libraries
require APPPATH . 'vendor/autoload.php';

Adding a Library

You can either edit composer.json with your required library (and then re-run the install command above), or use the composer require verb from the command line to add the library, which also modifies composer.json.

php composer.phar require "monolog/monolog" "1.6.0"

The monolog package page is Note that you need the package name for the first parameter and the version for the second parameter.

View/download a file not in the public directory with PHP

When you need to give users access to files that are not in the public directory, where you cannot simply use an anchor tag with an “href”, you need to do a bit of work. For example, if you’ve created an authentication system where only authenticated users can download or view a file, this can be necessary.

$filename = 'something';
$file_path = '/somepath/to/the/file/';
$file_fullpath = $file_path . $filename;
if (!file_exists($file_fullpath)) {
    header("HTTP/1.0 404 Not Found");
// get the mime type
$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$mimeType = finfo_file($finfo, $file_fullpath);
// calc values for header
$size = filesize($file_fullpath);
$time = date('r', filemtime($file_fullpath));
$fm = @fopen($file_fullpath, 'rb');
if (!$fm) {
    header('HTTP/1.0 505 Internal server error');
$begin = 0;
$end = $size;
if (isset($_SERVER['HTTP_RANGE'])) {
    if (preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) {
        $begin = intval($matches[0]);
        if (!empty($matches[1])) $end = intval($matches[1]);
// create http header
if ($begin > 0 || $end < $size) {
    header('HTTP/1.0 206 Partial Content');
}else {
    header('HTTP/1.0 200 OK');
header('HTTP/1.0 200 OK');
header("Content-Type: $mimeType");
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Accept-Ranges: bytes');
header('Content-Length:' . ($end - $begin));
header("Content-Range: bytes $begin-$end/$size");
header("Content-Disposition: inline; filename=$filename");
header("Content-Transfer-Encoding: binary\n");
header("Last-Modified: $time");
header('Connection: close');
// output the file
$cur = $begin;
fseek($fm, $begin, 0);
while (!feof($fm) && $cur < $end && (connection_status() == 0)) {
    print fread($fm, min(1024 * 16, $end - $cur));
    $cur+= 1024 * 16;

There you have it. Your user can click the link for the file, which then runs this code. In my case, this is in a Kohana controller.

The files are not stored in a public directory, so unauthenticated users cannot access them.

If a file is created on the fly, like a PDF of an invoice, this will also work.

XAMPP on Mac OSX with Virtual Hosts

XAMPP is an all-in-one LAMP development solution for multiple platforms. I use Linux on my main computer and OSX for my laptop.

I’ve selected XAMPP to provide the LAMP environment on my Mac. It is free, in on-going development and works well.

Because I have several projects in development at once, I need to be able to quickly update my Mac with the current state of a project and then develop and test. Subversion is part of that equation and Komodo IDE is too. Setting up LAMP on Linux is a snap, but installing everything on the Mac, even with MacPorts would be tedious. There are a few pre-packaged solutions, including XAMPP, MAMP and Zend Server. I chose XAMPP after a little research and it has worked well for me.

The Apache virtual server does not come enabled by default, so a little setup is needed.

Folder for virtual websites

Create the folder “www” in your home directory, this example is in Terminal:

cd ~
mkdir www

This is the folder where you will place each of the virtual site directories. You could just as well put this somewhere else, but a “www” directory here makes sense to me.


Add the following to /Applications/XAMPP/etc/httpd.conf

	Options Indexes FollowSymLinks ExecCGI Includes
	AllowOverride All
	Order allow,deny
	Allow from all

In the above you will need to substitute your username for “yourusername”. This simply sets some Apache settings for the folder where your virtual sites will be.

In this same file find:

# Virtual hosts
#Include /Applications/XAMPP/etc/extra/httpd-vhosts.conf

…and un-rem out the Include line. This enables virtual hosting. Yay!


For each website, add a code block to /Applications/XAMPP/etc/extra/http-vhosts.conf

    DocumentRoot "/Users/yourusername/www/"
    ErrorLog "/Users/yourusername/www/"
    CustomLog "/Users/yourusername/www/" common

In the above, just follow the same pattern I’ve shown for this example site. Don’t vary from this unless you want to do some research and testing. You can see I place a “public” folder insite the top directory for a particular virtual site – put your web documents to serve here.

hosts file

Edit your /etc/hosts file to add “” (your version of this) to a line starting with “” like this:

Restart Apache

Using the XAMPP control stop and re-start Apache.