Step 1: Login to Google Cloud Console and Create a Project
Step 2: Go to App Engine and Create Application using below command in Cloud Shell or you can also follow steps by clicking on create application see screenshots below for your reference
1 |
gcloud app create --region=asia-south1 |
OR
Step 1 | Step 2 | Step 3 | Step 4 |
Step 3: After receiving success open Cloud Shell if not already opened and click on pencil icon to Launch Editor
Step 4: Download Google Cloud Storage Library using below command
1 |
composer require google/cloud-storage |
Step 5: Now It’s Time to Code
app.yaml
1 2 3 4 5 |
# Use the PHP 7.3 runtime (BETA) by replacing "php72" below with "php73" runtime: php73 env_variables: BUCKET_NAME: "mydemoproject-278919.appspot.com" |
We configure our App Engine app’s settings in the app.yaml
file. The app.yaml
file also contains information about your app’s code, PHP runtime, and entrypoint.
Here we are defining an environment variable named as BUCKET_NAME which we will use in our code, this bucket name you can get from Navigation Menu => Storage Option in GCP Console. Actually, when we create App Engine project a bucket is automatically created by App Engine for the use in your app with named as “yourprojectid.appspot.com”.
config.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
<?php // load GCS library require __DIR__ . '/vendor/autoload.php'; use Google\Cloud\Storage\StorageClient; function uploadFile($bucketName, $fileContent, $cloudPath, $makePublic = false) { $storage = new StorageClient(); // set which bucket to work in $bucket = $storage->bucket($bucketName); // upload/replace file $object = $bucket->upload( $fileContent, ['name' => $cloudPath] // if $cloudPath is existed then will be overwrite without confirmation // NOTE: // a. do not put prefix '/', '/' is a separate folder name !! ); // is it succeed ? if($object != null) { if($makePublic) { $object->update(['acl' => []], ['predefinedAcl' => 'PUBLICREAD']); } return true; } return false; } function getFileInfo($bucketName, $cloudPath) { $storage = new StorageClient(); // set which bucket to work in $bucket = $storage->bucket($bucketName); $object = $bucket->object($cloudPath); return $object->info(); } function getFiles($bucketName, $directory = null) { $storage = new StorageClient(); // set which bucket to work in $bucket = $storage->bucket($bucketName); if ($directory == null) { // list all files $objects = $bucket->objects(); } else { // list all files within a directory (sub-directory) $options = array('prefix' => $directory); $objects = $bucket->objects($options); } return $objects; } function deleteFile($bucketName, $objectName, $options = []) { $storage = new StorageClient(); // set which bucket to work in $bucket = $storage->bucket($bucketName); try { $object = $bucket->object($objectName); $object->delete(); } catch (Exception $exc) { //exception handling } } |
All necessary functions for uploading, listing and deleting files are defined here in this file
index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php # [START gae_simple_front_controller] switch (@parse_url($_SERVER['REQUEST_URI'])['path']) { case '/': require 'home.php'; break; case '/requests.php': require 'requests.php'; break; default: http_response_code(404); exit('Not Found'); } ?> |
User requests routing code which responds according to path i.e opening home page sending ajax request to requests.php showing 404 on invalid path
home.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<?php require_once 'config.php'; if (!getenv('BUCKET_NAME')) { die('Set BUCKET_NAME environment variables'); } $bucketName = getenv('BUCKET_NAME'); if (isset($_REQUEST['delete']) && isset($_REQUEST['name'])) { $fileName = urldecode($_REQUEST['name']); deleteFile($bucketName, $fileName); //header("Location: /"); echo '<script>window.location.href = "/"</script>'; exit(); } $objects = getFiles($bucketName); ?> <html> <head> <title>Objects in Bucket</title> </head> <body> <h1>Objects in Bucket</h1> <form id="fileUploadForm" method="post" enctype="multipart/form-data"> <input type="file" name="file"/> <input type="submit" name="upload" value="Upload"/> <span id="uploadingmsg"></span> <hr/> </form> <table border="1" style="width: 100%;"> <thead> <tr> <td>Object</td> <td>Action</td> </tr> </thead> <tbody id="objects"> <?php foreach ($objects as $o) { $oinfo = $o->info(); ?> <tr> <td><a href="https://storage.googleapis.com/<?= $oinfo['bucket'] ?>/<?= $oinfo['name'] ?>"><?= $o->name() ?></a></td> <td><a href="/?delete=1&name=<?= urlencode($o->name()) ?>">Delete</a></td> </tr> <?php } ?> </tbody> </table> <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> <script> $("#fileUploadForm").submit(function (e) { e.preventDefault(); var action = "requests.php?action=upload"; $("#uploadingmsg").html("Uploading..."); var data = new FormData(e.target); $.ajax({ type: 'POST', url: action, data: data, /*THIS MUST BE DONE FOR FILE UPLOADING*/ contentType: false, processData: false, }).done(function (response) { $("#uploadingmsg").html(response.msg); //https://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME] if (response.code == '200') { window.location.reload(); } }).fail(function (data) { //any message }); });         </script> </body> </html> |
Code to list objects of given bucket, uploading and deleting objects (files)
requests.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php include_once 'config.php'; $action = filter_var(trim($_REQUEST['action']), FILTER_SANITIZE_STRING); if ($action == 'upload') { $response['code'] = "200"; if ($_FILES['file']['error'] != 4) { //set which bucket to work in $bucketName = getenv('BUCKET_NAME'); // get local file for upload testing $fileContent = file_get_contents($_FILES["file"]["tmp_name"]); // NOTE: if 'folder' or 'tree' is not exist then it will be automatically created ! $cloudPath = $_FILES["file"]["name"]; $isSucceed = uploadFile($bucketName, $fileContent, $cloudPath, true); if ($isSucceed == true) { $response['msg'] = 'SUCCESS: to upload ' . $cloudPath . PHP_EOL; // TEST: get object detail (filesize, contentType, updated [date], etc.) $response['data'] = getFileInfo($bucketName, $cloudPath); } else { $response['code'] = "201"; $response['msg'] = 'FAILED: to upload ' . $cloudPath . PHP_EOL; } } header("Content-Type:application/json"); echo json_encode($response); exit(); } |
This file is called through ajax to upload file on google cloud storage and here you can see $cloudPath variable which is used to store file path and if we need to store it in database we can do so and later we can fetch it from our database instead of cloud storage api. We can also use Cloud SQL in our application to make our application fully cloud based if you are not aware how to use Cloud SQL with App Engine then checkout this post Connect Google App Engine with Google Cloud SQL.
Step 6: Go to Editor which we had launched in step 3 and upload all the files created in step 5.
Step 7: Deploy App using below command
1 2 3 |
gcloud app deploy OR gcloud app deploy --version v1 |
Step 8: Access App
Note: –
Video
NetBeans Project Download
App Engine with Cloud Storage
References:-
https://cloud.google.com/appengine/docs/standard/php7/using-cloud-storage
Thank you Friends
Please don’t forget share if you it useful
Comments