File Browser in CodeIgniter

This is a quick post. I’m going to show the code necessary to build a file browser in PHP using CodeIgniter. It allows file browsing in the server and opening files without leaving your app. Text files are displayed directly while other files are send to download.


During a PHP project development cycle, we usually work locally, easily accessing our files. When we upload our work to an external server we need a way to verify our uploads, changes made by the app itself or check if an specific file has the correct version. Common ways of doing this are FTP or a file explorer like cPanels. But they need external tools. Other servers like PagodaBox, which is a Git server, have files updated through a ‘git push’.

To speed things up you can use the code presented in this post to check filed directly in the browser. There’s an obvious risk associated, so you need to guarantee the only the correct users access this functionality. This security layer is on your own. I’m not going to show any user control in this post.

There are other ways to integrate similar solutions in your application, but this is a simple working solution that can be improved according to your needs.

The Method

Considering that you have a controller only to administrative access, the following method is able to access your files.

    function file_browser()
        $segment_array = $this->uri->segment_array();

        // first and second segments are the controller and method
        $controller = array_shift( $segment_array );
        $method = array_shift( $segment_array );

        // absolute path using additional segments
        $path_in_url = '';
        foreach ( $segment_array as $segment ) $path_in_url.= $segment.'/';
        $absolute_path = getcwd().'/'.$path_in_url;
        $absolute_path = rtrim( $absolute_path ,'/' );

        // check if it is a path or file
        if ( is_dir( $absolute_path ))
            // link generation helper

            $dirs = array();
            $files = array();
            // fetching directory
            if ( $handle = @opendir( $absolute_path ))
                while ( false !== ($file = readdir( $handle )))
                    if (( $file != "." AND $file != ".." ))
                        if ( is_dir( $absolute_path.'/'.$file ))
                            $dirs[]['name'] = $file;
                            $files[]['name'] = $file;
                closedir( $handle );
                sort( $dirs );
                sort( $files );

            // parent folder
            // ensure it exists and is the first in array
            if ( $path_in_url != '' )
                array_unshift ( $dirs, array( 'name' => '..' ));

            // view data
            $data = array(
                'controller' => $controller,
                'method' => $method,
                'virtual_root' => getcwd(),
                'path_in_url' => $path_in_url,
                'dirs' => $dirs,
                'files' => $files,
            $this->load->view( 'file_browser', $data );
            // is it a file?
            if ( is_file($absolute_path) )
                // open it
                header ('Cache-Control: no-store, no-cache, must-revalidate');
                header ('Cache-Control: pre-check=0, post-check=0, max-age=0');
                header ('Pragma: no-cache');

                $text_types = array(
                    'php', 'css', 'js', 'html', 'txt', 'htaccess', 'xml'
                $path_parts = pathinfo($absolute_path);
                // download necessary ?
                if( isset($path_parts['extension']) && in_array( $path_parts['extension'], $text_types) ) {
                    header('Content-Type: text/plain');
                } else {
                    header('Content-Type: application/x-download');
                    header('Content-Length: ' . filesize( $absolute_path ));
                    header('Content-Disposition: attachment; filename=' . basename( $absolute_path ));

                @readfile( $absolute_path );

This code only work when the controller is inside /controllers. If you put it in a sub-folder you need to change the segments section. As it’s a simple logic, I think the comments are enough to explain it. Let’s got to the view.


The view is very simple as well..

    <h1>File Browser</h1>
    <h2><?php echo $virtual_root.'/'.$path_in_url ?></h2>
        $prefix = $controller.'/'.$method.'/'.$path_in_url;
        if (!empty($dirs)) foreach( $dirs as $dir )
            echo '/'.anchor($prefix.$dir['name'], $dir['name']).'<br>';

        if (!empty($files)) foreach( $files as $file )
            echo anchor($prefix.$file['name'], $file['name']).'<br>';

That’s all you need to finish your file browser. Now you can view your files without leaving your app.


A big part of the code was reused from here: