在root directiry中创建文件夹并将文件上传到该文件夹​​google drive api

时间:2018-06-14 11:07:19

标签: php google-drive-api google-api-php-client

我想使用CURL在googledrive根目录中创建文件夹。文件上传到驱动器但我需要创建一个文件夹并将文件上传到该文件夹​​。

根据@hanshenrik代码创建文件夹工作移动文件不起作用

我更新的代码:

$REDIRECT_URI = 'http' . ($_SERVER['SERVER_PORT'] == 80 ? '' : 's') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'];
$SCOPES = array($GAPIS_AUTH . 'drive', $GAPIS_AUTH . 'drive.file', $GAPIS_AUTH . 'userinfo.email', $GAPIS_AUTH . 'userinfo.profile');
$STORE_PATH = 'credentials.json';

function uploadFile($credentials, $filename, $targetPath,$folderId)
{

    global $GAPIS;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $GAPIS . 'upload/drive/v2/files?uploadType=media');

   //$content =  { title  "mypdf.pdf", description = "mypdf.pdf", mimeType = "application/pdf" };

   $contentArry = array('name' =>'veridoc', 'parents' => array('17dVe2GYpaHYFdFn1by5-TYKU1LXSAwkp'));
   $contentArry = json_encode($contentArry);



    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
    //curl_setopt($ch, CURLOPT_POSTFIELDS,$contentArry);
    curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($filename));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER,
            array('Content-Type : application/pdf','Content-Length:' . filesize($filename),'Authorization: Bearer ' . getAccessToken($credentials))
    );

    $postResult = curl_exec($ch);
    curl_close($ch);

    return json_decode($postResult, true);
}
function RenameUploadedFile($id,$credentials,$filename)
{

 $ch = curl_init();
    curl_setopt_array ( $ch, array (
            CURLOPT_URL => 'https://www.googleapis.com/drive/v3/files/' . urlencode ( $id ),
            CURLOPT_POST => 1,
            CURLOPT_RETURNTRANSFER => true,     
            CURLOPT_POSTFIELDS => json_encode ( array (
                    'name' => $filename  
            ) ),
            CURLOPT_CUSTOMREQUEST => 'PATCH',
            CURLOPT_HTTPHEADER => array (
                    'Content-Type : application/json',
                    'Authorization: Bearer ' . getAccessToken ( $credentials ) 
            ) 

    ) );
    curl_exec($ch);
    curl_close($ch);
    return true;
}

  function CreateGDFolder($credentials,$foldername)
    {


            $curl = curl_init();
            curl_setopt_array ( $curl, array (
            CURLOPT_URL => 'https://www.googleapis.com/drive/v3/files',
            CURLOPT_POST => 1,
            CURLOPT_RETURNTRANSFER => true,             
            CURLOPT_POSTFIELDS => json_encode ( array (
                // Earlier it was title changed to name
                "name" => $foldername,
                "mimeType" => "application/vnd.google-apps.folder"

            ) ),
            // Earlier it was PATCH changed to post
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_HTTPHEADER => array (
                'Content-Type : application/json',
                'Authorization: Bearer ' . getAccessToken ( $credentials ) 
            ) 

            ) );

           $response = curl_exec($curl);

        return json_decode($response, true);
}



function getStoredCredentials($path)
{

    $credentials = json_decode(file_get_contents($path), true);

    if (isset($credentials['refresh_token']))
    {   
        return $credentials;
    }


    $expire_date = new DateTime();
    $expire_date->setTimestamp($credentials['created']);
    $expire_date->add(new DateInterval('PT' . $credentials['expires_in'] . 'S'));

    $current_time = new DateTime();

    if ($current_time->getTimestamp() >= $expire_date->getTimestamp())
    {
        $credentials = null;
        unlink($path);
    }

    return $credentials;
}

function storeCredentials($path, $credentials)
{

    $credentials['created'] = (new DateTime())->getTimestamp();
    file_put_contents($path, json_encode($credentials));
    return $credentials;
}

function requestAuthCode()
{

    global $GOAUTH, $CLIENT_ID, $REDIRECT_URI, $SCOPES;
    $url = sprintf($GOAUTH . 'auth?scope=%s&redirect_uri=%s&response_type=code&client_id=%s&approval_prompt=force&access_type=offline',
            urlencode(implode(' ', $SCOPES)), urlencode($REDIRECT_URI), urlencode($CLIENT_ID)
    );
    header('Location:' . $url);
}

function requestAccessToken($access_code)
{

    global $GOAUTH, $CLIENT_ID, $CLIENT_SECRET, $REDIRECT_URI;
    $url = $GOAUTH . 'token';
    $post_fields = 'code=' . $access_code . '&client_id=' . urlencode($CLIENT_ID) . '&client_secret=' . urlencode($CLIENT_SECRET)
            . '&redirect_uri=' . urlencode($REDIRECT_URI) . '&grant_type=authorization_code';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
    curl_setopt($ch, CURLOPT_POST, true);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $url);

    $result = curl_exec($ch);

    curl_close($ch);

    return json_decode($result, true);
}

function getAccessToken($credentials)
{

    $expire_date = new DateTime();
    $expire_date->setTimestamp($credentials['created']);
    $expire_date->add(new DateInterval('PT' . $credentials['expires_in'] . 'S'));

    $current_time = new DateTime();

    if ($current_time->getTimestamp() >= $expire_date->getTimestamp())
        return $credentials['refresh_token'];
    else
        return $credentials['access_token'];

}

function authenticate()
{

    global $STORE_PATH;

    if (file_exists($STORE_PATH))
        $credentials = getStoredCredentials($STORE_PATH);
    else
        $credentials = null;

    if (!(isset($_GET['code']) || isset($credentials)))
        requestAuthCode();

    if (!isset($credentials))
        $credentials = requestAccessToken($_GET['code']);

    if (isset($credentials) && isset($credentials['access_token']) && !file_exists($STORE_PATH))
        $credentials = storeCredentials($STORE_PATH, $credentials);

    return $credentials;
}   

$credentials = authenticate();

$folderresponse=CreateGDFolder($credentials,"veridoc");
$folderID= $folderresponse['id'];
$folder_id=$folderID;
$filename="veridoc".date('_Y_m_d_H_i_s').".pdf";

$result = uploadFile($credentials, 'veridoc.pdf', '',$folderID);

// File rename to original

$id=$result['id'];
$file_id=$id;


if(isset($folderID)){

//Upload a file 
if(RenameUploadedFile($id,$credentials,$filename))
{
echo "We have uploaded ".$filename." to drive";
}
else{
echo "can't rename file";
}
}



try {
    $ch = curl_init ();
    curl_setopt_array ( $ch, array (
            CURLOPT_URL => 'https://www.googleapis.com/upload/drive/v3/files/' . urlencode ( $file_id ),
            CURLOPT_POST => 1,
            CURLOPT_RETURNTRANSFER => true,     
            CURLOPT_POSTFIELDS => json_encode (array(
            'addParents' => $folder_id,
            'removeParents' => 'root',
            'fields' => 'id, parents') ),
            CURLOPT_CUSTOMREQUEST => 'PATCH',
            CURLOPT_HTTPHEADER => array (
                    'Content-Type : application/pdf',
                    'Authorization: Bearer ' . getAccessToken ( $credentials ) 
            ) 

    ) );
    $resp = curl_exec ( $ch );
    $parsed = json_decode ( $resp, true );

} finally{
    curl_close ( $ch );
}

4 个答案:

答案 0 :(得分:2)

https://developers.google.com/drive/api/v2/folder文件夹上的文档中进行查找,似乎就像您通过上载内容类型设置为application/vnd.google-apps.folder的空“文件”来创建文件夹一样。

这是有关如何以简单方式上传文件的文档:https://developers.google.com/drive/api/v2/simple-upload

该上传方法存在的问题是所创建的文件(在本例中为文件夹)将没有名称,其名称仅为untitled<whatever>,因此,最后,这是有关如何重命名文件的文档: https://developers.google.com/drive/api/v3/reference/files/update(或本例中的文件夹)

将它们放在一起,您可能最终会得到类似的东西:

<?php
$ch = curl_init ();
curl_setopt_array ( $ch, array (
        CURLOPT_URL => 'https://www.googleapis.com/upload/drive/v3/files?uploadType=media',
        CURLOPT_HTTPHEADER => array (
                'Content-Type: application/vnd.google-apps.folder',
                'Authorization: Bearer '.getAccessToken ( $credentials )  
        ),
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => '', // "empty file"
        CURLOPT_RETURNTRANSFER => 1 
) );
try {
    // this will create the folder, with no name
    if (false === ($resp = curl_exec ( $ch ))) {
        throw new \RuntimeException ( 'curl error ' . curl_errno ( $ch ) . ": " . curl_error ( $ch ) );
    }
    $parsed = json_decode ( $resp, true );
    if (! $parsed || $parsed ['code'] !== 200) {
        throw new \RuntimeException ( 'google api error: ' . $resp );
    }
    $id = $parsed ['id'];
    // now to give the folder a name:
    curl_setopt_array ( $ch, array (
            CURLOPT_URL => 'https://www.googleapis.com/drive/v3/files/' . urlencode ( $id ),
            CURLOPT_POST => 1,
            CURLOPT_POSTFIELDS => json_encode ( array (
                    'name' => 'the_folders_name' 
            ) ),
            CURLOPT_CUSTOMREQUEST => 'PATCH',
            CURLOPT_HTTPHEADER => array (
                    'Content-Type : application/json',
                    'Authorization: Bearer ' . getAccessToken ( $credentials ) 
            ) 

    ) );

    if (false === ($resp = curl_exec ( $ch ))) {
        throw new \RuntimeException ( 'curl error ' . curl_errno ( $ch ) . ": " . curl_error ( $ch ) );
    }
    $parsed = json_decode ( $resp, true );
    if (! $parsed || $parsed ['code'] !== 200) {
        throw new \RuntimeException ( 'google api error: ' . $resp );
    }
} finally{
    curl_close ( $ch );
}
var_dump ( $resp );

最后,要在此文件夹中移动文件,请将PATCH请求发送到https://www.googleapis.com/upload/drive/v3/files/<file_you_want_to_move_id>,并将文件夹的ID作为请求正文的addParents参数,例如:

<?php
try {
    $ch = curl_init ();
    curl_setopt_array ( $ch, array (
            CURLOPT_URL => 'https://www.googleapis.com/upload/drive/v3/files/' . urlencode ( $file_id ),
            CURLOPT_POST => 1,
            CURLOPT_POSTFIELDS => json_encode ( array (
                    'addParents' => $folder_id,
                    'removeParents'=> 'root',


            ) ),
            CURLOPT_CUSTOMREQUEST => 'PATCH',
            CURLOPT_HTTPHEADER => array (
                    'Content-Type : application/json',
                    'Authorization: Bearer ' . getAccessToken ( $credentials ) 
            ) 

    ) );
    if (false === ($resp = curl_exec ( $ch ))) {
        throw new \RuntimeException ( 'curl error ' . curl_errno ( $ch ) . ": " . curl_error ( $ch ) );
    }
    $parsed = json_decode ( $resp, true );
    if (! $parsed || $parsed ['code'] !== 200) {
        throw new \RuntimeException ( 'google api error: ' . $resp );
    }
} finally{
    curl_close ( $ch );
}

答案 1 :(得分:1)

这将对您有所帮助:

https://developers.google.com/drive/api/v3/folder

创建文件夹:

在Drive API中,文件夹本质上是一个文件 - 由特殊文件夹MIME类型application / vnd.google-apps.folder标识的文件。您可以通过插入具有此MIME类型和文件夹标题的文件来创建新文件夹。设置文件夹标题时不要包含扩展名。

$fileMetadata = new Google_Service_Drive_DriveFile(array(
    'name' => 'Invoices',
    'mimeType' => 'application/vnd.google-apps.folder'));
$file = $driveService->files->create($fileMetadata, array(
    'fields' => 'id'));
printf("Folder ID: %s\n", $file->id);

在文件夹中插入文件:

要在特定文件夹中插入文件,请在文件的parents属性中指定正确的ID,如下所示:

$folderId = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E';
$fileMetadata = new Google_Service_Drive_DriveFile(array(
    'name' => 'photo.jpg',
    'parents' => array($folderId)
));
$content = file_get_contents('files/photo.jpg');
$file = $driveService->files->create($fileMetadata, array(
    'data' => $content,
    'mimeType' => 'image/jpeg',
    'uploadType' => 'multipart',
    'fields' => 'id'));
printf("File ID: %s\n", $file->id);

创建文件夹时也可以使用parents属性来创建子文件夹。

在文件夹之间移动文件: 要为现有文件添加或删除父项,请对文件使用addParents和removeParents查询参数。update方法。

这两个参数可用于将文件从一个文件夹移动到另一个文件夹,如下所示:

$fileId = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ';
$folderId = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E';
$emptyFileMetadata = new Google_Service_Drive_DriveFile();
// Retrieve the existing parents to remove
$file = $driveService->files->get($fileId, array('fields' => 'parents'));
$previousParents = join(',', $file->parents);
// Move the file to the new folder
$file = $driveService->files->update($fileId, $emptyFileMetadata, array(
    'addParents' => $folderId,
    'removeParents' => $previousParents,
    'fields' => 'id, parents'));

答案 2 :(得分:0)

查看是否正常。我进行了"name" => ""CURLOPT_CUSTOMREQUEST => 'POST',

之类的更改
function CreateGDFolder($credentials)
    {
        $ch = curl_init();
        curl_setopt_array ( $ch, array (
        CURLOPT_URL => 'https://www.googleapis.com/drive/v3/files',
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => json_encode ( array (
            // Earlier it was title changed to name
            "name" => "pets",
            "mimeType" => "application/vnd.google-apps.folder"

        ) ),
        // Earlier it was PATCH changed to post
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_HTTPHEADER => array (
            'Content-Type : application/json',
            'Authorization: Bearer ' . getAccessToken ( $credentials ) 
        ) 

        ) );

        $response=curl_exec($ch);
        $response = json_decode($response, true);
        print_r($response); 
        curl_close($ch);
    }

See its working fine for me

答案 3 :(得分:0)

这是我的工作示例:

要连接Google驱动程序:

public function connect(Request $request)
    {
        $user = Auth::user();

        $client = new \Google_Client();
        $client->setHttpClient(new \GuzzleHttp\Client(['verify' => false]));
        $client->setClientId('xxxx');
        $client->setClientSecret('xxxxxx');
        $client->setRedirectUri(url('copywriter/connect'));
        $client->setAccessType('offline');
        $client->setApprovalPrompt('force');
        $client->setScopes(array('https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.appfolder'));
        if (isset($request->code)) {
            $authCode = trim($request->code);
            $accessToken = $client->authenticate($authCode);
            $copywriter->gd_access_token=json_encode($accessToken, JSON_PRETTY_PRINT);
            $copywriter->save();
        } else {
            $authUrl = $client->createAuthUrl();
            return redirect($authUrl);
        }

        $found=$this->search_gd("files");
        if (!isset($found['file_id'])) {
            $found=$this->create_folder_gd("copify_files");
            $copywriter->gd_folder_id=$found["file_id"];
            $copywriter->save();
        }
        return redirect(route("copywriter.index"));
    }

发送到Google云端硬盘

    public function send_to_gd($name)
        {
            $user = Auth::user();
            $copywriter=Copywriter::where('user_id', $user->id)->first();
            $folderId = $copywriter->gd_folder_id;
            $client=$this->getClient();
            $service = new \Google_Service_Drive($client);
            $fileMetadata = new \Google_Service_Drive_DriveFile(array(
            'name' => $name,'mimeType' => 'application/vnd.google-apps.document','parents' => array($folderId)));
            $file = $service->files->create($fileMetadata, array(
            'mimeType' => 'application/vnd.google-apps.document',
            'uploadType' => 'multipart',
            'fields' => 'id'));
            return $file->id;
        }

请求的客户

public function getClient($user=null)
    {
        if ($user==null) {
            $user = Auth::user();
        }
        $copywriter=Copywriter::where('user_id', $user->id)->first();
        $client = new \Google_Client();
        $client->setHttpClient(new \GuzzleHttp\Client(['verify' => false]));
        $client->setClientId('xxxx');
        $client->setClientSecret('xxxxx');
        $client->setRedirectUri(url('copywriter/connect'));
        $client->setAccessType('offline');
        $client->setApprovalPrompt('force');
        $client->setScopes(array('https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.appfolder'));


        $data=json_decode($copywriter->gd_access_token, true);

        $client->setAccessToken($data);

        // Refresh the token if it's expired.
        if ($client->isAccessTokenExpired()) {
            $oldAccessToken=$client->getAccessToken();
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
            $accessToken=$client->getAccessToken();
            $accessToken['refresh_token']=$oldAccessToken['refresh_token'];

            $copywriter->gd_access_token=json_encode($accessToken, JSON_PRETTY_PRINT);
            $copywriter->save();
        }
        return $client;
    }

在Google云端硬盘中搜索

public function search_gd($name)
    {
        $client=$this->getClient();
        $service = new \Google_Service_Drive($client);
        $pageToken = null;
        do {
            $response = $service->files->listFiles(array(
        'q' => "mimeType='application/vnd.google-apps.folder' and name='".$name."'",
        'spaces' => 'drive',
        'pageToken' => $pageToken,
        'fields' => 'nextPageToken, files(id, name)',
    ));
            foreach ($response->files as $file) {
                return ['file_name'=>$file->name,'file_id'=>$file->id];
                printf("Found file: %s (%s)\n", $file->name, $file->id);
            }
            if (isset($repsonse)) {
                $pageToken = $repsonse->pageToken;
            }
        } while ($pageToken != null);
    }

在Google云端硬盘上创建文件夹

public function create_folder_gd($name)
    {
        $client=$this->getClient();
        $service = new \Google_Service_Drive($client);
        $fileMetadata = new \Google_Service_Drive_DriveFile(array(
    'name' => $name,
    'mimeType' => 'application/vnd.google-apps.folder'));
        $file = $service->files->create($fileMetadata, array(
    'fields' => 'id'));
        return ['file_name'=>$name,'file_id'=>$file->id];
    }

在Google云端硬盘上创建文档

public function create_document($name, $content_id=null)
    {
        $user = Auth::user();
        $copywriter=Copywriter::where('user_id', $user->id)->first();
        $folderId = $copywriter->gd_folder_id;
        $client=$this->getClient();
        $service = new \Google_Service_Drive($client);
        $fileMetadata = new \Google_Service_Drive_DriveFile(array(
      'name' => $name,'mimeType' => 'application/vnd.google-apps.document','parents' => array($folderId)));
        $file = $service->files->create($fileMetadata, array(
      'mimeType' => 'application/vnd.google-apps.document',
      'uploadType' => 'multipart',
      'fields' => 'id'));
        if ($content_id!=null) {
            $content=Content::findOrFail($content_id);
            $content->file_id=$file->id;
            $content->save();
        }
        return ['file_name'=>$name,'file_id'=>$file->id];
    }

我的模型是撰稿人,并且内容用您的模型替换。