How to use Google Cloud Storage for PHP? - php

So ive followed the guide on how to use GCS on their site: https://developers.google.com/appengine/docs/php/googlestorage/
But the following code does not work. I cannot access my bucket, and the CloudStorageTools is not even found.
require_once 'google/appengine/api/cloud_storage/CloudStorageTools.php';
use google\appengine\api\cloud_storage\CloudStorageTools;
// check if GCS bucket if writable
$my_bucket = 'gs://my_bucket/';
$check1 = is_writable($my_bucket); //returns nothing
class_exists("CloudStorageTools"); //returns false
I also added google_app_engine.allow_include_gs_buckets into the php.ini file. Still no support for GCS.
Anyone have some running code they could share?

I think it may have something to do with permissions set to your bucket. Make sure you added your app account email Application Settings -> Service Account Name.
I ported my app with no issues and using Smarty to write into and include from the bucket. I did not have to declare:
require_once 'google/appengine/api/cloud_storage/CloudStorageTools.php';
use google\appengine\api\cloud_storage\CloudStorageTools;
and the app reads and writes to the bucket with no problems.
I have had however issues with some WordPress porting, when although the bucket existed and had properly setup access permission, for some reason app throws a Fatal Error and I can see it in the app logs, that application was trying to access the cloud storage via gs:// wrapper.
Hope that helps.

Hi dude make sure you bucket is Public Write enabled
use this gsutil command to do so (google how to configure gsutil utility)
$ gsutil acl ch -u AllUsers:W gs://example-bucket-name

Related

Loading an image from Google Cloud Bucket with PHP

Is it possible to get an image from google cloud bucket in a similar fashion to file_get_contents? I need the image for mess around with without needing to have it on my local machine/server
i have tried using the google cloud storage library for php (https://github.com/googleapis/google-cloud-php-storage) but it keeps giving me "failed to open stream" error, which leads me to believe that I may provided the wrong url to the file_get_content function.
I should mention that all the files are set to public, with public storage.cloud.google.com links available
My current code is similar to this:
require 'vendor/autoload.php';
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient();
$storage->registerStreamWrapper();
$contents = file_get_contents('gs://{BUCKET}/{IMAGE NAME}.jpg');
While my current bucket structure is more like this
BUCKET - FOLDER - IMAGE
I have tried adding the folder in the URL and it still gave me the same "failed to open stream" error. Could anyone point me at what am i doing wrong? Do I need to authenticate? Do I even need the library for this? I tried using file_get_content($public_url) but since storage.cloud.google.com links redirect you that obviously didn't work hahaha
Any help would be appreciated
Cheers
I have installed the Cloud SDK, and used the default service account credentials to connect to Google Cloud services link.
In general, the Google Cloud PHP library uses Service Account
credentials to connect to Google Cloud services. When running on
Compute Engine the credentials will be discovered automatically. When
running on other environments, the Service Account credentials can be
specified by providing the path to the JSON keyfile for the account
(or the JSON itself) in environment variables.
Run composer require google/cloud
Create a test.php file:
<?php
# Includes the autoloader for libraries installed with composer
require __DIR__ . '/vendor/autoload.php';
# Imports the Google Cloud client library
use Google\Cloud\Storage\StorageClient;
# Your Google Cloud Platform project ID
$projectId = 'my_project';
# Instantiates a client
$storage = new StorageClient([
'projectId' => $projectId
]);
# The name for the new bucket
$storage->registerStreamWrapper();
$contents = file_get_contents('gs://my-buck-sample/image.JPG');
echo 'content' . $contents . ' created.';
?>
3.Run php test.php

How does google storage file upload work for app engine using php?

I am new to coding world.I want to upload a simple txt file to a bucket that is in my cloud storage. I didn't find any useful cloud documentations regarding it.
here is the not working code:
<?php
require_once 'vendor/autoload.php';
use Google\Cloud\Storage\StorageClient;
define("PROJECT_ID", 'projectID');
define("BUCKET_NAME", 'bucketname');
$client = new Google_Client();
$client->setApplicationName("API_Cloud_Storage");
$client->useApplicationDefaultCredentials();
$client->setScopes(["https://www.googleapis.com/auth/cloud-platform"]);
$service = new Google_Service_Storage($client);
$request = $service->objects->listObjects(BUCKET_NAME);
foreach ($request["items"] as $object)
printf("%s\n", $object->getName());
printf("%s\n", $object->get);
$storage = new StorageClient();
$bucket = $storage->bucket(BUCKET_NAME); // Put your bucket name here.
$filePath="C:\users\useraccount\Desktop\address_file\textfile.txt";
$objectName="textfile.txt";
$object = $bucket->upload(file_get_contents($filePath),
['name' => $objectName]);
?>
It seems that the issue is in your code and there is an answer provided in a related question that you can refer to (it also has a link to another useful documentation) that can help you correct your code [1]. You can also rely on this sample code in GitHub [2].
In terms of the concept of uploading a local file to later provide public access to write to it. I think you may need to read a bit more about serving files uploaded with your app from the filesystem [3]. I also advise that you read through this entire documentation as it talks about serving files from a script or directly from GCS [4].
[1] https://stackoverflow.com/a/48559967
[2] https://github.com/GoogleCloudPlatform/php-docs-samples/blob/master/appengine/php55/storage/app.php#L79
[3] https://cloud.google.com/appengine/docs/standard/php/googlestorage/#is_there_any_other_way_to_read_and_write_files
[4]
https://cloud.google.com/appengine/docs/standard/php/googlestorage/public_access#top_of_page
Fortunately Google App Engine (GAE) provides a built-in Google Cloud Storage (GCS) stream wrapper that allows you to use many of the standard PHP filesystem functions to read and write files in an App Engine PHP app. I am also improving my coding skills and have found tips that worked for me in the GCP Documentation.
Taking from the code snippet you provided, you have to ensure you have done at least 2 things:
that you have properly created a storage bucket in Google Cloud Storage (GCS) [1].
Make sure to replace "BUCKET_NAME" in your code with the name of the GCS bucket you created, and indicate the filepath to the text file you want to upload.
that you have configured your PHP app for writing files to your app [2], or to allow user uploads if you want other users to be able to upload files to your GCS bucket [3].
These are standard how-to guides (Tutorials are at the bottom of navigation bar) so make sure to view the examples provided on Github to take a look at the complete codes and adapt the style to yours.
Hope this helps!
[1] https://cloud.google.com/storage/docs/creating-buckets
[2] https://cloud.google.com/appengine/docs/standard/php/googlestorage/#top_of_page
[3] https://cloud.google.com/appengine/docs/standard/php/googlestorage/user_upload

How to handle secret files on Azure App Services with Git

We have an PHP app, where for encryption of the connection with database we need to provide 3 files that shouldn't be publicly accessible, but should be present on the server to make the DB connection (https://www.cleardb.com/developers/ssl_connections)
Obviously we don't want to store them in the SCM with the app code, so the only idea that comes to my mind is using post-deploy action hook and fetch those files from storage account (with keys and URIs provided in the app parameters).
Is there a nicer/cleaner way to achieve this? :)
Thank you,
You can try to use Custom Deployment Script to execute additional scripts or command during the deployment task. So you can create a php script whose functionality is to download the certificate files from Blob Storage to server file system location. And then in your PHP application, the DB connection can use these files.
Following are the general steps:
Enable composer extension in your portal:
Install azure-cli module via npm, refer to https://learn.microsoft.com/en-us/azure/xplat-cli-install for more info.
Create deployment script for php via command azure site deplotmentscript --php
Execute command composer require microsoft/windowsazure, make sure you have a composer.json with the storage sdk dependency.
Create php script in your root directory to download flies from Blob Storage(e.g. named run.php):
require_once 'vendor/autoload.php';
use WindowsAzure\Common\ServicesBuilder;
use MicrosoftAzure\Storage\Common\ServiceException;
$connectionString = "<connection_string>";
$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);
$container = 'certificate';
$blobs = ['client-key.pem','client-cert.pem','cleardb-ca.pem'];
foreach($blobs as $k => $b){
$blobresult = $blobRestProxy->getBlob($container, $b);
$source = stream_get_contents($blobresult->getContentStream());
$result = file_put_contents($b, $source);
}
Modify the deploy.cmd script, add santence php run.php under the step KuduSync.
Deploy your application to Azure Web App via Git.
Any further concern, please feel free to let me know.

Writing to GC Bucket using AppEngine

The google docs states
The GCS stream wrapper is built in to the run time, and is used when you supply a file name starting with gs://.
When I look into the app.yaml, I see where the runtime is selected. I have selected php runtime. However when I try to write to my bucket I get an error saying the wrapper is not found for gs://. But when I try to write to my bucket using the helloworld.php script that is provided by google here https://cloud.google.com/appengine/docs/php/gettingstarted/helloworld and modifying it so that it says
<?php
file_put_contents('gs://<app_id>.appspot.com/hello.txt', 'Hello');
I have to deploy the app in order for the write to be successful. I am not understanding why I have to deploy the app everytime to get the wrapper I need to write to my bucket. How come I can not write to my bucket from a random php script?
Google says
"In the Development Server, when a Google Cloud Storage URI is specified we emulate this functionality by reading and writing to temporary files on the user's local filesystem"
So, "gs://" is simulated locally - to actually write to GCS buckets using the stream wrapper, it has to run from App Engine itself.
Try something like this:
use google\appengine\api\cloud_storage\CloudStorageTools;
$object_url = "gs://bucket/file.png";
$options = stream_context_create(['gs'=>['acl'=>'private', 'Content-Type' => 'image/png']]);
$my_file = fopen($object_url, 'w', false, $options);
fwrite($my_file, $file_data));
fclose($my_file);

Access network share with PHP5.2 + IIS7.5

I'm using php 5.2 with IIS7.5.
I have a network share on a NAS that is username and password protected. I cannot disable or change authentication info on the NAS. I need to be able to access that network share via php.
I've done the following:
Created new user in windows whose username and password matches those on the NAS.
Created IIS application pool that uses this same auth info.
Created a web.config file inside of the php app directory with an impersonation turned on, using the same auth info.
identity impersonate="true" password="ThePass" userName="TheUser" />
Turned on ASP.NET impersonation in the application authentication in IIS.
None of this seemed to work with this simple line of code in php:
$dir = opendir("\\someservername\somesharename");
Warning: opendir(\someservername\somesharename) [function.opendir]: failed to open dir: No error in C:\websites\site\forum\testing.php on line 7
So, I decided to test the configuration with ASP.NET.
string[] diretories = System.IO.Directory.GetDirectories("\\someservername\somesharename");
The asp.net test worked perfectly.
Going further down the rabbit hole, I ran phpinfo() and checked the username info in it. Down in the "Environment" section of phpinfo, I found the "USERNAME" item. Its value was "TheUser," as was what I expected.
Everything points to the system being configured correctly until I tried:
echo get_current_user();
Which returned, "IUSR." That surely isn't what I expected.
So, how in the world do I get php + IIS7.5 to read from a foreign network share?
Update:
Thanks to a few of the answers, I've added
$result = shell_exec("net use o: \\\\pathToServer\\27301 /persistent:yes 2>&1");
Which returns a success. I'm still getting the error on opendir. I tried another test and used is_dir. This returned false on my newly created mapped drive.
var_dump(is_dir("o:\\"));
// Prints: bool(false)
UPDATE
I ran the script from the command line when logged in as the user that created. The scripts executes correctly. Could this take us back to get_current_user() which returns IUSR? I tryied getmypid() which returned a process ID. I cross referred that process id with the task manager and found that it was for php-cgi.exe, running under the custom user account that I made.
The recommended way to access a network share in PHP is to "mount" it. Try to connect your share as a network drive.
Btw. your command is wrong
$dir = opendir("\\someservername\somesharename");
You have to use 4 "\" because it's the escape character
$dir = opendir("\\\\someservername\somesharename");
NOTE: get_current_user() returns the owner of the process on IIS
You can try a test by mapping it like
$command = "net use $drive \"\\\\$ip\\$share\" $smb_password /user:$domain\\$smb_username";
$result = shell_exec($command);
on opendir you need to have \\\\$server_name\\$share try with 4 '\' and if mapping like that works and 4 '\' is failing on opendir. You may have credentials not matching.
If you map it this way new user you created in windows whose username and password matches those on the NAS will have rights on mapped drive that way you do not need to worry about the scope.
Had the same problem on a similar system. Solved this by going to web site > Authentication > Anonymous Authentication > Change IUSR to whatever your username is or use Application Pool user if correctly configured.

Categories