Quickstart: Run a Drive App in PHP seems to be using an outdated version of [google-api-php-client][2], also it doesn't provide example on how to upload a file using Service Account.
In my project I'll need to add a file (spreadsheet) using Service Account, add a spreadsheet, share the spreadsheet with another user and add rows to the spreadsheet.
I'm able to get an empty list of spreadsheets, but I couldn't figure it out how to upload a file using Service Account.
The PHP Class google-api-php-client/examples/spreadsheet.php:
<?php
    use Google\Spreadsheet\DefaultServiceRequest;
    use Google\Spreadsheet\ServiceRequestFactory;
    use Google\Spreadsheet\SpreadsheetService;
    define('JPATH_PLATFORM',1);
    require_once realpath(dirname(__FILE__) . '/../autoload.php');
    class GoogleSpreadSheet
    {
        protected $data;
        protected $client_id            = null ; //Client ID
        protected $service_account_name = null; //Email Address
        protected $key_file_location    = null; //key.p12
        protected $client               = null;
        protected $aplication_name      = null;
        protected $_errors = array();
        protected $scopes = array(    'https://www.googleapis.com/auth/drive'
                                    , 'https://www.googleapis.com/auth/drive.appdata'
                                    , 'https://www.googleapis.com/auth/drive.apps.readonly'
                                    , 'https://spreadsheets.google.com/feeds'
                                );
        /**
         * Class constructor
         * @param   mixed  $properties  Either and associative array or another
         *                              object to set the initial properties of the object.
         */
        public function __construct($properties = null){
            if ($properties !== null)
            {
                $this->setProperties($properties);
            }
            $this->data = new stdClass();
            $this->getClient();
        }
        /**
         * Get Google_Client object
         * @return mixed Google_Client object if client ID and application_name are set OR null
         */
        public function getClient(){
            if(empty($this->client) AND $this->get('client_id') AND $this->get('aplication_name')){
                $this->client = new Google_Client();
                $this->client->setApplicationName($this->get('aplication_name'));
                $this->client->setClientId($this->get('client_id'));
            }
            return $this->client;
        }
        /**
         * Get Service AccessToken
         * @return AccessToken
         */
        public function getToken()
        {
            $key = file_get_contents($this->get('key_file_location'));
            $cred = new Google_Auth_AssertionCredentials(
                    $this->service_account_name,
                    $this->get('scopes', array()),
                    $key
            );
            $this->client->setAssertionCredentials($cred);
            if($this->client->getAuth()->isAccessTokenExpired()) {
                $this->client->getAuth()->refreshTokenWithAssertion($cred);
            }
            $service_token = json_decode($this->client->getAccessToken());
            return $service_token->access_token;
        }
        /**
         * Get Available Spreadsheets
         */
        public function getSpreadsheetsList()
        {
            $accessToken        = $this->getToken();
            $serviceRequest     = new DefaultServiceRequest($accessToken);
            ServiceRequestFactory::setInstance($serviceRequest);
            $spreadsheetService = new SpreadsheetService();
            $spreadsheetFeed    = $spreadsheetService->getSpreadsheets();
            echo '<pre>'; print_r($spreadsheetFeed);
            foreach($spreadsheetFeed as $item) {
                $spreadsheets[basename($item->getId())] = $item->getTitle();
            }
            $this->data->spreadsheets = isset($spreadsheets) ? $spreadsheets : false;
        }
        /**
         * Insert new file.
         *
         * @param string $title Title of the file to insert, including the extension.
         * @param string $description Description of the file to insert.
         * @param string $parentId Parent folder's ID.
         * @param string $mimeType MIME type of the file to insert.
         * @param string $filename Filename of the file to insert.
         * @return Google_DriveFile The file that was inserted. NULL is returned if an API error occurred.
         */
        public function insertFile($title, $description, $mimeType='application/vnd.google-apps.spreadsheet', $filename=null, $parentId=null) {
            //Google_DriveService $service Drive API service instance.
            $service = new Google_Service_Drive($this->getClient());
            $file = new Google_Service_Drive_DriveFile();
            $file->setTitle($title);
            $file->setDescription($description);
            $file->setMimeType($mimeType);
            // Set the parent folder.
            if ($parentId != null) {
                $parent = new Google_ParentReference();
                $parent->setId($parentId);
                $file->setParents(array($parent));
            }
            try {
                if(!empty($filename)){
                    $data = file_get_contents($filename);
                }else{
                    $data = '';
                }
                $createdFile = $service->files->insert($file, array(
                        'data' => $data,
                        'mimeType' => $mimeType,
                ));
                // Uncomment the following line to print the File ID
                // print 'File ID: %s' % $createdFile->getId();
                return $createdFile;
            } catch (Exception $e) {
                $this->setError($e->getMessage());
                print "An error occurred: " . $e->getMessage();
            }
        }
        /**
         * Sets a default value if not alreay assigned
         * @param   string  $property  The name of the property.
         * @param   mixed   $default   The default value.
         * @return  mixed
         */
        public function def($property, $default = null)
        {
            $value = $this->get($property, $default);
            return $this->set($property, $value);
        }
        /**
         * Returns a property of the object or the default value if the property is not set.
         * @param   string  $property  The name of the property.
         * @param   mixed   $default   The default value.
         * @return  mixed    The value of the property.
         */
        public function get($property, $default = null)
        {
            if (isset($this->$property))
            {
                return $this->$property;
            }
            return $default;
        }
        /**
         * Returns an associative array of object properties.
         * @param   boolean  $public  If true, returns only the public properties.
         * @return  array
         */
        public function getProperties($public = true)
        {
            $vars = get_object_vars($this);
            if ($public)
            {
                foreach ($vars as $key => $value)
                {
                    if ('_' == substr($key, 0, 1))
                    {
                        unset($vars[$key]);
                    }
                }
            }
            return $vars;
        }
        /**
         * Get the most recent error message.
         * @param   integer  $i         Option error index.
         * @param   boolean  $toString  Indicates if JError objects should return their error message.
         * @return  string   Error message
         */
        public function getError($i = null, $toString = true)
        {
            // Find the error
            if ($i === null)
            {
                // Default, return the last message
                $error = end($this->_errors);
            }
            elseif (!array_key_exists($i, $this->_errors))
            {
                // If $i has been specified but does not exist, return false
                return false;
            }
            else
            {
                $error = $this->_errors[$i];
            }
            // Check if only the string is requested
            if ($error instanceof Exception && $toString)
            {
                return (string) $error;
            }
            return $error;
        }
        /**
         * Return all errors, if any.
         * @return  array  Array of error messages or JErrors.
         */
        public function getErrors()
        {
            return $this->_errors;
        }
        /**
         * Modifies a property of the object, creating it if it does not already exist.
         * @param   string  $property  The name of the property.
         * @param   mixed   $value     The value of the property to set.
         * @return  mixed  Previous value of the property.
         */
        public function set($property, $value = null)
        {
            $previous = isset($this->$property) ? $this->$property : null;
            $this->$property = $value;
            return $previous;
        }
        /**
         * Set the object properties based on a named array/hash.
         * @param   mixed  $properties  Either an associative array or another object.
         * @return  boolean
         */
        public function setProperties($properties)
        {
            if (is_array($properties) || is_object($properties))
            {
                foreach ((array) $properties as $k => $v)
                {
                    // Use the set function which might be overridden.
                    $this->set($k, $v);
                }
                return true;
            }
            return false;
        }
        /**
         * Add an error message.
         * @param   string  $error  Error message.
         * @return  void
         */
        public function setError($error)
        {
            array_push($this->_errors, $error);
        }
    }
    $opt = array();
    $opt['key_file_location']   = realpath(dirname(__FILE__)).'/key_ss.p12';
    $opt['client_id']           = '*********.apps.googleusercontent.com';
    $opt['service_account_name']= '*********@developer.gserviceaccount.com';
    $opt['aplication_name']     = 'MY APPLICATION NAME';
    $GoogleSS = new GoogleSpreadSheet($opt);
    $GoogleSS->insertFile('test', 'description');
    $GoogleSS->getSpreadsheetsList();
I also have a modified version of /google-api-php-client/autoload.php:
<?php
    function google_api_php_client_autoload($className) {
      $classPath = explode('_', $className);
      if ($classPath[0] != 'Google') {
        return;
      }
      if (count($classPath) > 3) {
        // Maximum class file path depth in this project is 3.
        $classPath = array_slice($classPath, 0, 3);
      }
      $filePath = dirname(__FILE__) . '/src/' . implode('/', $classPath) . '.php';
      if (file_exists($filePath)) {
        require_once($filePath);
      }
    }
    function google_spreadsheet_api_php_client_autoload($className) {
        $classPath = explode('\\', $className);
        if (count($classPath) == 1) {
            $filePath = dirname(__FILE__) . '/src/Google/Spreadsheet/' .  $className . '.php';
        }else{
            $filePath = dirname(__FILE__) . '/src/' .  implode('/', $classPath) . '.php';
        } 
        if (file_exists($filePath)) {
            require_once($filePath);
        }
    }
    spl_autoload_register('google_api_php_client_autoload');
    spl_autoload_register('google_spreadsheet_api_php_client_autoload');
When I execute the code I get:
Notice: Undefined index: uploadType in /var/www/google-api-php-client/src/Google/Service/Resource.php on line 175
Notice: Undefined index: uploadType in /var/www/google-api-php-client/src/Google/Service/Resource.php on line 175
An error occurred: Error calling POST https://www.googleapis.com/drive/v2/files: (401) Login Required
Google\Spreadsheet\SpreadsheetFeed Object
( .... )
In order to reproduce the problem you will also need to download php-google-spreadsheet-client and upload the the Spreadsheet directory to /google-api-php-client/src/Google/
I've tried to provide as much details as possible, but please let me know if something is unclear.