【问题标题】:Google API - update spreadsheet using PUT with PHP and CurlGoogle API - 使用 PUT 和 PHP 和 Curl 更新电子表格
【发布时间】:2014-05-13 14:31:45
【问题描述】:

我正在使用来自 https://developers.google.com/google-apps/spreadsheets/ 的 Google 自己的示例

他们说:

要更新现有行的内容,首先检索要更新的行,根据需要对其进行修改,然后将消息正文中包含更新行的 PUT 请求发送到行的编辑 URL。

确保您 PUT 条目中的 id 值与现有条目的 id 完全匹配。编辑 URL 在以下行条目中突出显示:

<entry gd:etag='"S0wCTlpIIip7ImA0X0QI"'>
  <id>https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId</id>
  <updated>2006-11-17T18:23:45.173Z</updated>
  <category scheme="http://schemas.google.com/spreadsheets/2006"
    term="http://schemas.google.com/spreadsheets/2006#list"/>
  <title type="text">Bingley</title>
  <content type="text">Hours: 10, Items: 2, IPM: 0.0033</content>
  <link rel="self" type="application/atom+xml"
    href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId"/>
  <link rel="edit" type="application/atom+xml"
    href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId/version"/>
  <gsx:name>Bingley</gsx:name>
  <gsx:hours>20</gsx:hours>
  <gsx:items>4</gsx:items>
  <gsx:ipm>0.0033</gsx:ipm>
</entry>

我一直在尝试使用以下 CURL 发送此信息(使用我自己的数据,但结构完全相同):

$headers = array(
            "Authorization: GoogleLogin auth=" . $google_auth,
            "GData-Version: 3.0",
            "Content-Type: application/atom+xml",
            "If-Match: *",
            );
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, "https://spreadsheets.google.com/feeds/list/$feed/0/private/full/$row_id");
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_VERBOSE, true);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $response = curl_exec($curl);
            echo $response;

似乎 XML 格式不正确,这很奇怪,因为它来自 Google 的示例,当我从自己的电子表格中检索列表提要时,我得到了相同的响应。我该如何更正,还有其他问题吗?

当我将此 xml 粘贴到 http://www.freeformatter.com/xml-formatter.html 时,我收到一个错误,

Unable to parse any XML input. org.jdom2.input.JDOMParseException: Error on line 1: The prefix "gd" for attribute "gd:etag" associated with an element type "entry" is not bound.

谢谢。

【问题讨论】:

    标签: php curl google-api google-spreadsheet-api


    【解决方案1】:

    嗯,没有真正的回应....但我终于让它工作了。希望这对其他人有帮助。这个想法是您需要使用通过提要检索的名称空间。

    所以 XML 应该是这样的:

    <?xml version="1.0" encoding="UTF-8"?>
    <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" gd:etag="&quot;S0wCTlpIIip7ImA0X0QI&quot;">
       <id>https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId</id>
       <updated>2006-11-17T18:23:45.173Z</updated>
       <category scheme="http://schemas.google.com/spreadsheets/2006" term="http://schemas.google.com/spreadsheets/2006#list" />
       <title type="text">Bingley</title>
       <content type="text">Hours: 10, Items: 2, IPM: 0.0033</content>
       <link rel="self" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId" />
       <link rel="edit" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/list/key/worksheetId/private/full/rowId/version" />
       <gsx:name>Bingley</gsx:name>
       <gsx:hours>20</gsx:hours>
       <gsx:items>4</gsx:items>
       <gsx:ipm>0.0033</gsx:ipm>
    </entry>
    

    CURL 应该是这样的:

    $headers = array(
                "Authorization: GoogleLogin auth=" . $google_auth, //google_auth retrieved earlier
                "GData-Version: 3.0",
                "Content-Type: application/atom+xml",
                "If-Match: *",
                );
    
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, "https://spreadsheets.google.com/feeds/list/$feed/0/private/full/$id"); //feed is obtained from spreadsheet url and id can be obtained by retrieving list feed
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
            curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
            curl_setopt($curl, CURLOPT_HEADER, false);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_VERBOSE, true);
            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            $response = curl_exec($curl);
            echo $response;
    

    【讨论】:

    • 但是为什么要在 标签中插入时间戳呢?这不应该是谷歌服务器响应的东西吗?
    • 您对需要在请求中的 xmlns 属性是正确的。
    【解决方案2】:

    如果您想检索和更新适当的自定义 XML 而不是通用 Atom XML 文档,那么您可以尝试 APISpark PaaS,它具有 GSpreadsheets 包装器,可以创建和托管自定义 Web API。

    见教程:https://apispark.com/docs/tutorials/google-spreadsheet

    【讨论】:

    • 这看起来确实很有趣,尽管快速浏览只提到了检索或添加新数据。我确定其中有一些关于更新和删除的内容。
    • 是的,如果您查看教程末尾创建的 Web API,它有 HTTP PUT(用于更新)和 DELETE 方法。
    【解决方案3】:

    这应该对你有帮助

    $accessToken = $ACCESS_TOKEN;
    
    $key = $SPREADSHEET_ID;
    $sheetId = $SHEET_ID;
    
    $editUrl = "https://spreadsheets.google.com/feeds/cells/$key/$sheetId/private/full/R2C4?access_token=$accessToken";
    
    $entry = '<?xml version="1.0" encoding="UTF-8" ?><entry xmlns="http://www.w3.org/2005/Atom" xmlns:gs="http://schemas.google.com/spreadsheets/2006"><id>https://spreadsheets.google.com/feeds/cells/'.$key.'/'.$sheetId.'/private/full/R2C4</id><link rel="edit" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/cells/'.$key.'/'.$sheetId.'/private/full/R2C4"/><gs:cell row="2" col="4" inputValue="Enter_Value_Here">Enter_Value_Here</gs:cell></entry>';
    
    $ch = curl_init();  
    curl_setopt( $ch, CURLOPT_URL, $editUrl );
    curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "PUT");
    curl_setopt( $ch, CURLOPT_POST, true );
    curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: application/atom+xml','If-Match: *','Content-length: ' . strlen($entry)));
    curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $entry );
    
    $content = curl_exec($ch);
    
    if($content === false)
    {
        echo 'Curl error: ' . curl_error($ch)."<br>";
    }
    else
    {
        echo 'Operation completed without any errors <br>';
        $information = curl_getinfo($ch);
    }
    
    curl_close($ch);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      相关资源
      最近更新 更多