Don't know if anyone has experience with the Google Spreadsheets API or the Zend_GData classes but it's worth a go:
When I try to insert a value in a 750 row spreadsheet, it takes ages and then throws an error that my memory limit (which is 128 MB!) was exceeded. I also got this when querying all records of this spreadsheet but this I can imaging because it's quite a lot of data. But why does this happen when inserting a row? That's not too complex, is it? Here's the code I used:
public function insertIntoSpreadsheet($username, $password, $spreadSheetId, $data = array()) {
$service = Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($username, $password, $service);
$client->setConfig(array( 'timeout' => 240 ));
$service = new Zend_Gdata_Spreadsheets($client);
if (count($data) == 0) {
die("No valid data");
}
try {
$newEntry = $service->insertRow($data, $spreadSheetId);
return true;
} catch (Exception $e) {
return false;
}
}
I just ran into this today. When calling the insertRow()
method, my script used upwards of 130MB of memory inserting into a worksheet of ~600 records. I tested this on framework version 1.11.
As a work-around, I use the existing Zend HTTP client object to send a POST with the Atom entry containing the data for the row to be inserted. I followed Google's protocol for adding a list row.
Below is the code I came up with. The $values
parameter is an associative array that has keys matching the column names for the row. Of course, you already know your $spreadsheetKey
and $worksheetId
(if the worksheet you are inserting into is the first worksheet in the spreadsheet, I'm not sure its ID is necessary).
$authService = Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME;
$httpClient = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $authService);
function insertRow($httpClient, $spreadsheetKey, $worksheetId, $values) {
$entry = createEntry($values);
$httpClient->setUri("https://spreadsheets.google.com/feeds/list/".$spreadsheetKey."/".$worksheetId."/private/full");
$response = $httpClient->setRawData($entry, 'application/atom+xml')->request('POST');
return $response->getStatus() == 201;
}
function createEntry($values) {
$entry = "<entry xmlns=\"http://www.w3.org/2005/Atom\"";
$entry .= " xmlns:gsx=\"http://schemas.google.com/spreadsheets/2006/extended\">";
foreach($values as $key => $value) {
$entry .= "<gsx:".$key.">".$value."</gsx:".$key.">";
}
$entry .= "</entry>";
return $entry;
}
Hope this helps.
Sorry but I can't comment Jonathan Freeland's post, so I post it like this.
I added this inside of insertRow() to get it to work.
$token = $httpClient->getClientLoginToken();
$httpClient->setHeaders('Authorization','GoogleLogin auth='.$token);
$httpClient->setHeaders('Content-Type', 'application/atom+xml');
This is a serious Zend_Gdata bug. It is downloading the entire spreadsheet (by doing an empty query) and loading it into memory just to build a request url for the insert. I reported the issue as well as a fix but the issue has been ignored by the Zend maintainers and may never get fixed.