Google Sheets API v4를 PHP에서 연동하는 완벽 가이드

 

Google Sheets를 외부 애플리케이션에서 직접 제어하고 싶은 개발자들이 많지만, 대부분 Google API Console의 복잡한 설정과 OAuth 2.0 인증 방식 때문에 난감해한다. 특히 PHP에서 Google Sheets API를 연동할 때 어디서 키를 받아야 하고, 어떻게 인증을 처리해야 하는지 정확히 아는 개발자는 생각보다 많지 않다.

이번 글에서는 Google Sheets API v4의 기본 개념부터 시작해서, 서비스 어카운트 키 생성, PHP 라이브러리 설치, 실제 데이터 읽기와 쓰기까지 한 번에 정리해주겠다. 이 글을 따라가면 엑셀 같은 스프레드시트를 백엔드에서 데이터베이스처럼 활용할 수 있게 될 것이다.

1단계: Google Sheets API란 무엇인가?

 

Google Sheets API는 Google이 제공하는 REST 기반의 API로, 스프레드시트의 데이터를 프로그래밍으로 읽고 수정할 수 있게 해준다. 보통 다음 같은 상황에서 쓰인다:

  • 관리자가 Google Sheets에서 관리하는 설정값을 웹서비스에서 실시간으로 가져오기
  • 사용자가 입력한 데이터를 자동으로 Google Sheets에 기록하기
  • 데이터 수집, 보고서 자동 생성, 재고 관리 등 간단한 데이터 작업

흔히 "REST API"라고 부르지만, Google은 gRPC, Batch 요청 등 여러 방식을 지원한다. 하지만 PHP에서는 공식 클라이언트 라이브러리(google-api-php-client)를 사용하는 게 가장 간단하다.

2단계: Google API Console에서 프로젝트 생성 및 키 발급

 

Google Sheets API를 사용하려면 먼저 Google Cloud Console에서 서비스 어카운트를 만들고 JSON 키 파일을 받아야 한다. 절차는 다음과 같다:

2-1) Google Cloud Console 접속

https://console.cloud.google.com 에 들어가서 새 프로젝트를 만든다(또는 기존 프로젝트 선택).

2-2) Google Sheets API 활성화

왼쪽 메뉴에서 "API 및 서비스" → "라이브러리"를 클릭하고, "Google Sheets API"를 검색해서 활성화한다.

2-3) 서비스 어카운트 생성

"API 및 서비스" → "사용자 인증 정보"로 간다. "+ 사용자 인증 정보 만들기"를 클릭하고 "서비스 어카운트"를 선택한다. 어카운트 이름을 입력(예: sheets-api-user)하고 생성한다.

2-4) JSON 키 다운로드

생성된 서비스 어카운트를 클릭 → "키" 탭 → "새 키 추가"를 클릭한다. 형식은 "JSON"으로 선택하고 생성하면 JSON 파일이 다운로드된다. 이 파일을 프로젝트의 안전한 디렉토리(예: config/)에 저장한다.

다운로드한 JSON 파일은 다음과 같은 구조다:

{
  "type": "service_account",
  "project_id": "your-project-id",
  "private_key_id": "key-id",
  "private_key": "-----BEGIN PRIVATE KEY-----n...",
  "client_email": "your-sa@your-project.iam.gserviceaccount.com",
  "client_id": "123456789",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token"
}
3단계: PHP 프로젝트에 Google API 클라이언트 설치

 

Composer를 사용해서 google-api-php-client를 설치한다:

composer require google/apiclient

또는 이미 composer.json이 있다면 다음을 추가하고 composer update를 실행한다:

"require": {
  "google/apiclient": "^2.15"
}
4단계: 실전 예제 - 스프레드시트에서 데이터 읽기

 

✗ 잘못된 코드 - 인증 정보를 코드에 하드코딩

<?php
// 절대 하지 말 것: 키를 소스코드에 직접 쓰기
$client = new Google_Client();
$client->setAuthConfig([
  'type' => 'service_account',
  'client_email' => 'user@project.iam.gserviceaccount.com',
  'private_key' => '-----BEGIN PRIVATE KEY-----...'
]);
?>

이렇게 하면 깃허브에 올렸을 때 누구든 당신의 인증정보를 볼 수 있고, 구글 클라우드 과금이 폭주할 수 있다.

✓ 올바른 코드 - JSON 파일을 별도로 관리

<?php
require_once __DIR__ . '/vendor/autoload.php';

// 1. Google 클라이언트 초기화
$client = new Google_Client();

// 2. JSON 키 파일 경로 설정 (서버 파일시스템에 저장된 파일)
$client->setAuthConfig(__DIR__ . '/config/service-account-key.json');

// 3. Sheets API 스코프 지정
$client->addScope(Google_Service_Sheets::SPREADSHEETS);

// 4. Sheets 서비스 객체 생성
$service = new Google_Service_Sheets($client);

// 5. 스프레드시트 ID와 범위 지정
$spreadsheetId = '1ABC-xyz123_your-spreadsheet-id';
$range = 'Sheet1!A1:C10';  // Sheet1의 A1부터 C10까지

// 6. 데이터 읽기
try {
    $response = $service->spreadsheets_values->get($spreadsheetId, $range);
    $values = $response->getValues();
    
    if (count($values) > 0) {
        foreach ($values as $row) {
            echo "Row: " . implode(', ', $row) . "<br>";
        }
    } else {
        echo "해당 범위에 데이터가 없습니다.";
    }
} catch (Exception $e) {
    echo "에러 발생: " . $e->getMessage();
}
?>

이 코드의 핵심:

  • setAuthConfig(): JSON 파일의 경로를 지정해서 인증한다.
  • addScope(): 이 서비스 어카운트가 무엇을 할 수 있는지 권한을 지정한다.
  • spreadsheets_values->get(): 특정 범위의 데이터를 조회한다.

스프레드시트 ID는 어디서 찾나?

Google Sheets를 브라우저에서 열었을 때 URL이 다음과 같다면:

https://docs.google.com/spreadsheets/d/1ABC-xyz123_your-spreadsheet-id/edit

"/d/" 다음부터 "/edit" 전까지의 부분이 스프레드시트 ID다.

5단계: 스프레드시트에 데이터 쓰기

 

✗ 잘못된 코드 - 범위를 명시하지 않고 쓰기

<?php
$data = [
    ['이름', '이메일', '나이'],
    ['홍길동', 'hong@example.com', '28']
];

// 범위를 안 쓰면 어디에 저장될지 알 수 없다
$body = new Google_Service_Sheets_ValueRange();
$body->setValues($data);
$service->spreadsheets_values->update($spreadsheetId, $body);
?>

이렇게 하면 어느 셀부터 데이터가 저장될지 불명확하고 기존 데이터를 덮어쓸 수도 있다.

✓ 올바른 코드 - 범위를 명시해서 쓰기

<?php
require_once __DIR__ . '/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig(__DIR__ . '/config/service-account-key.json');
$client->addScope(Google_Service_Sheets::SPREADSHEETS);
$service = new Google_Service_Sheets($client);

$spreadsheetId = '1ABC-xyz123_your-spreadsheet-id';

// 1. 쓸 데이터 준비
$data = [
    ['이름', '이메일', '나이'],
    ['홍길동', 'hong@example.com', '28'],
    ['김영희', 'kim@example.com', '25']
];

// 2. ValueRange 객체 생성
$body = new Google_Service_Sheets_ValueRange();
$body->setValues($data);

// 3. 범위를 명시해서 업데이트
$range = 'Sheet1!A1';
$options = ['valueInputOption' => 'RAW'];  // RAW = 데이터 그대로 저장, USER_ENTERED = 수식으로 계산

try {
    $response = $service->spreadsheets_values->update(
        $spreadsheetId,
        $range,
        $body,
        $options
    );
    echo "업데이트 완료! 수정된 셀: " . $response->getUpdatedCells();
} catch (Exception $e) {
    echo "에러: " . $e->getMessage();
}
?>

valueInputOption의 차이:

옵션 설명 예시
RAW 데이터를 그대로 저장한다 =SUM(A1:A10) → 문자열로 저장
USER_ENTERED 수식이면 계산하고, 숫자로 보이면 숫자로 저장 =SUM(A1:A10) → 계산 결과 저장
6단계: 마지막 행 뒤에 데이터 추가하기 (append)

 

기존 데이터를 덮어쓰지 않고 마지막 행 뒤에 추가하려면 append 메소드를 쓴다:

<?php
$newRow = ['박민수', 'park@example.com', '30'];

$body = new Google_Service_Sheets_ValueRange();
$body->setValues([$newRow]);

$range = 'Sheet1!A:A';  // A열 전체 (마지막 행 다음에 자동 추가)
$options = ['valueInputOption' => 'USER_ENTERED'];

try {
    $response = $service->spreadsheets_values->append(
        $spreadsheetId,
        $range,
        $body,
        $options
    );
    echo "행 추가 완료! 추가된 범위: " . $response->getUpdates()->getUpdatedRange();
} catch (Exception $e) {
    echo "에러: " . $e->getMessage();
}
?>
7단계: 주의사항 및 흔한 실수

 

① 서비스 어카운트에 스프레드시트 공유 권한 부여 안 함

✗ 잘못된 것: API를 설정했는데 "Permission denied" 에러가 난다

✓ 올바른 것: Google Sheets를 열고, 공유 버튼을 클릭해서 서비스 어카운트 이메일(JSON 파일의 client_email)을 "편집자"로 초대한다.

② 스프레드시트 ID를 잘못 복사했을 때

✗ 잘못된 것: 1ABC-xyz (URL에서 일부만 복사)

✓ 올바른 것: 1ABC-xyz123_your-spreadsheet-id (전체 ID)

③ 범위 표기법 오류

✗ 잘못된 것: 'Sheet1 A1:C10' (공백이 있으면 안됨), 'A1:C10' (시트명 필수)

✓ 올바른 것: 'Sheet1!A1:C10' 또는 '시트명'!범위

④ JSON 파일을 깃허브에 커밋했을 때
즉시 Google Cloud Console에서 그 키를 비활성화하고 새로운 키를 발급받아야 한다. 이미 노출된 키로는 누구나 당신의 스프레드시트를 수정할 수 있다.

8단계: 실무 팁 - 성능 최적화

 

여러 행을 한 번에 읽거나 쓸 때는 배치 요청(batchUpdate)을 사용하면 API 호출 횟수를 줄일 수 있다:

<?php
// 한 번의 API 호출로 여러 범위를 동시에 읽기
$ranges = ['Sheet1!A1:C5', 'Sheet2!A1:B10'];

try {
    $response = $service->spreadsheets_values->batchGet(
        $spreadsheetId,
        ['ranges' => $ranges]
    );
    
    foreach ($response->getValueRanges() as $valueRange) {
        $range = $valueRange->getRange();
        $values = $valueRange->getValues();
        echo "범위 {$range}: " . count($values) . "개 행<br>";
    }
} catch (Exception $e) {
    echo "에러: " . $e->getMessage();
}
?>
마무리

 

Google Sheets API는 간단한 데이터 관리부터 복잡한 자동화까지 다양한 상황에서 유용한 도구다. 인증 부분이 조금 복잡해 보이지만, 한 번 설정하면 나머지는 간단한 CRUD 작업일 뿐이다. JSON 키 파일을 안전하게 관리하고, 필요한 스코프만 지정하는 작은 습관이 모여서 보안 사고를 예방한다는 점을 잊지 말자.

이 글의 "4단계 데이터 읽기" 예제로 시작해서 실제 프로젝트에 적용해보면, Google Sheets를 더 이상 수동으로만 관리하는 도구가 아닌 자동화된 데이터 소스로 활용할 수 있을 것이다.