I’ve made a GCP cloud function in PHP8.1, that connects to GCP cloud storage. I receive a filename to be processed, and the cloud function should open the file, decode it, and send the result to a pub sub.
The problem I’m having is that I can’t get fopen
to work on the file hosted in cloud storage.
I need fopen
to work, because another package that I’m using to decode AVRO files uses fopen
to access the file.
Thanks in advance for any help.
I’ve tested file_get_contents
and that works fine.
I’ve also tested downloading the file contents as a stream using the cloud storage package, and that works fine as well.
I’ve also modified the allow_url_fopen
php setting, but that didn’t change anything.
I’m using the google/cloud-storage
package, version v1.30.2
I’m using the google/cloud
package, version v0.201.0
$bucketName = 'bucket-name';
$filePath = 'file/path/in/bucket';
$this->storageClient->registerStreamWrapper();
$bucket = $this->storageClient->bucket($bucketName);
$object = $bucket->object($filePath);
$newGsFilePath = "gs://$bucketName/$filePath";
error_log(file_exists($newGsFilePath)); // logs "1", signifying that the file exists
error_log(file_get_contents($newGsFilePath)); // logs the contents of the file
$fp = fopen($newGsFilePath, "rb");
error_log(var_export($fp, true)); // logs "NULL". It should be false according to docs when it fails?
error_log(fseek($fp, 0, SEEK_SET)); // logs "-1", presumably because $fp is NULL
fclose($fp);
$stream = $object->downloadAsStream();
$contents = '';
while (!$stream->eof()) {
$contents .= $stream->read(1024);
}
error_log("$contents: $contents"); // logs the contents of the file
Could it be a permissions issue? I’m not the admin of this account, and am fairly new to GCP
2
Answers
The files opened from a Google Cloud Storage are not seekable, that's why
seek($fp, 0)
returns -1.The file can be transformed into a seekable file by copying its contents into a local file, using
I would recommend deleting the file after you are done with it.
Thanks to @KoalaYoung for helping me come to this answer.
If you don’t want to manage an extra file (or if you want to work within memory), you may try this:
The "php://temp" read-write stream would be created in-memory until it is larger than 2MB (or override the maxmemory like this:
php://temp/maxmemory:16MB
). If it is bigger, PHP will create and manage it as a temp file.