PHP Cron作业备份到Google云端硬盘 [英] PHP Cron job to backup to Google Drive

查看:56
本文介绍了PHP Cron作业备份到Google云端硬盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置一项cron作业,该作业会将服务器中的各种文件备份到Google云端硬盘.我看过很多解决方案,但似乎都没有用!我最接近(使用oAuth)的是:

I am trying to set up a cron job that will back up various files from my server to Google Drive. I have looked at many solutions and none seem to work! The closest I have got (using oAuth) is this:

<?php
/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

require_once __DIR__ . '/../vendor/autoload.php';
require_once "base.php";

echo pageHeader("File Upload - Uploading a large file");

/*************************************************
 * Ensure you've downloaded your oauth credentials
 ************************************************/
if (!$oauth_credentials = getOAuthCredentialsFile()) {
  echo missingOAuth2CredentialsWarning();
  return;
}

/************************************************
 * The redirect URI is to the current page, e.g:
 * http://localhost:8080/large-file-upload.php
 ************************************************/
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
echo "<br>$redirect_uri";
$client = new Google_Client();
echo "<br>got client";
$client->setAuthConfig($oauth_credentials);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/drive");
$service = new Google_Service_Drive($client);

// add "?logout" to the URL to remove a token from the session
if (isset($_REQUEST['logout'])) {
  unset($_SESSION['upload_token']);
}
echo "<br>got service";
/************************************************
 * If we have a code back from the OAuth 2.0 flow,
 * we need to exchange that with the
 * Google_Client::fetchAccessTokenWithAuthCode()
 * function. We store the resultant access token
 * bundle in the session, and redirect to ourself.
 ************************************************/
if (isset($_GET['code'])) {
echo "<br>getting token";
  $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
echo "<br>Got token";
  $client->setAccessToken($token);

  // store in the session also
  $_SESSION['upload_token'] = $token;

  // redirect back to the example
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

// set the access token as part of the client
if (!empty($_SESSION['upload_token'])) {
echo "<br>getting access token";
  $client->setAccessToken($_SESSION['upload_token']);
  if ($client->isAccessTokenExpired()) {
    unset($_SESSION['upload_token']);
  }
} else {
  $authUrl = $client->createAuthUrl();
}
echo "<br>Ready to go";

/************************************************
 * If we're signed in then lets try to upload our
 * file.
 ************************************************/
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $client->getAccessToken()) {
  /************************************************
   * We'll setup an empty 20MB file to upload.
   ************************************************/
  DEFINE("TESTFILE", 'testfile.txt');
  if (!file_exists(TESTFILE)) {
    $fh = fopen(TESTFILE, 'w');
    fseek($fh, 1024*1024*20);
    fwrite($fh, "!", 1);
    fclose($fh);
  }

  $file = new Google_Service_Drive_DriveFile();
  $file->name = "Big File";
  $chunkSizeBytes = 1 * 1024 * 1024;
echo "<br>created file";

  // Call the API with the media upload, defer so it doesn't immediately return.
  $client->setDefer(true);
  $request = $service->files->create($file);

  // Create a media file upload to represent our upload process.
  $media = new Google_Http_MediaFileUpload(
      $client,
      $request,
      'text/plain',
      null,
      true,
      $chunkSizeBytes
  );
  $media->setFileSize(filesize(TESTFILE));
echo "<br>created media";

  // Upload the various chunks. $status will be false until the process is
  // complete.
  $status = false;
  $handle = fopen(TESTFILE, "rb");
  while (!$status && !feof($handle)) {
    // read until you get $chunkSizeBytes from TESTFILE
    // fread will never return more than 8192 bytes if the stream is read buffered and it does not represent a plain file
    // An example of a read buffered file is when reading from a URL
    $chunk = readVideoChunk($handle, $chunkSizeBytes);
    $status = $media->nextChunk($chunk);
  }

  // The final value of $status will be the data from the API for the object
  // that has been uploaded.
  $result = false;
  if ($status != false) {
    $result = $status;
  }

  fclose($handle);
}

function readVideoChunk ($handle, $chunkSize)
{
    $byteCount = 0;
    $giantChunk = "";
    while (!feof($handle)) {
        // fread will never return more than 8192 bytes if the stream is read buffered and it does not represent a plain file
        $chunk = fread($handle, 8192);
        $byteCount += strlen($chunk);
        $giantChunk .= $chunk;
        if ($byteCount >= $chunkSize)
        {
            return $giantChunk;
        }
    }
    return $giantChunk;
}
?>

<div class="box">
<?php if (isset($authUrl)): ?>
  <div class="request">
    <a class='login' href='<?= $authUrl ?>'>Connect Me!</a>
  </div>
<?php elseif($_SERVER['REQUEST_METHOD'] == 'POST'): ?>
  <div class="shortened">
    <p>Your call was successful! Check your drive for this file:</p>
    <p><a href="https://drive.google.com/open?id=<?= $result->id ?>" target="_blank"><?= $result->name ?></a></p>
    <p>Now try <a href="/large-file-download.php">downloading a large file from Drive</a>.
  </div>
<?php else: ?>
  <form method="POST">
    <input type="submit" value="Click here to upload a large (20MB) test file" />
  </form>
<?php endif ?>
</div>

<?= pageFooter(__FILE__) ?>

但是它似乎达到了获取令牌"的目的.注释和停止-在Google API代码中进行了更多跟踪,但是我肯定不需要这样做吗?是的,我为此设置了oauth凭据-通过它们

But it seems to get as far as the "Getting token" comment and stops - have poked around in the Google API code with more tracing but surely I should not need to do this? Yes I have oauth credentials set up for this - gets past them

推荐答案

如果您正在使用cron作业,则需要在无需用户干预的情况下运行该服务帐户.

You should consider using a service account if you are working with a cron job which will need to be run without user intervention.

请注意,服务帐户是由该服务帐户上传的虚拟用户文件,该文件将归该服务帐户所有,您需要将其设置为授予您的个人帐户对其上传文件的权限.

Just note that a service account is a dummy user files uploaded by the service account will be owned by the service account you will need to set the service account up to grant your personal account permissions on the files it uploads.

除非您授予文件写入个人驱动器帐户上的目录的权限,否则文件将被上传到服务帐户驱动器帐户.

Also files will be uploaded to the service accounts drive account unless you give it permissions to write to a directory on your personal drive account and upload to that instead.

// Load the Google API PHP Client Library.
require_once __DIR__ . '/vendor/autoload.php';

// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');

/**
 * Gets the Google client refreshing auth if needed.
 * Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
 * Initializes a client object.
 * @return A google client object.
 */
function getGoogleClient() {
    return getServiceAccountClient();
}

/**
 * Builds the Google client object.
 * Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
 * Scopes will need to be changed depending upon the API's being accessed. 
 * array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
 * List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
 * @return A google client object.
 */
function getServiceAccountClient() {
    try {   
        // Create and configure a new client object.        
        $client = new Google_Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope([YOUR SCOPES HERE]);
        return $client;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

这篇关于PHP Cron作业备份到Google云端硬盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆