I understand folders are a pseudo- concept in AWS, however the AWS console's S3 UI allows you to create empty "folders" within a bucket or within other folders.
I looked briefly at the mkdir implementation in the StreamWrapper and noted it had support for creating buckets but it seems to fail for anything other than that (such as mkdir('s3://bucket/folder').
Apps transitioning from a traditional file system which rely on mkdir returning true before proceeding to put some files in will fail if the StreamWrapper doesn't support the same functionality that the UI exposes.
I imagine the change to be fairly simple but I'm not familiar enough with the S3 API (yet) to simply go ahead and do it myself.
We intentionally avoided creating empty pseudo-folders in the stream wrapper. Allowing empty pseudo-folders forces a lot of application layer code in the abstraction. The typical way this is achieved is by uploading a file with some special name (e.g., "$_bucketname_$"). Implementing this would add additional requests for various operations (does a file exist by this key?, do objects exist under this prefix?, does the place holder exist?), requires a large number of changes that would complicate the stream wrapper even further, and causes the problem of having an arbitrary place holder file that is relevant only to the abstraction that created it.
The Amazon S3 stream wrapper provides a different interface that PHP developers can use to interact with Amazon S3. We feel that the mkdir() functionality currently implemented is the most appropriate abstraction to offer and it works in the way Amazon S3 normally behaves.
Thanks. I was under the impression it was much simpler than this, judging by the HTTP requests that the S3 console generates. Such as:
-> /DeliverHttp
{
"method":"PUT",
"url":"https://s3-ap-southeast-2.amazonaws.com/bucket/bar/baz/",
"headers":{
"x-amz-s3-console-metadata-version":"2010-03-09",
"x-amz-s3-console-folder":"true",
"User-Agent":"S3Console/0.4",
"Date":"Thu, 15 Aug 2013 22:21:33 GMT",
"Authorization":"...",
"x-amz-security-token":"..."
},
"entitySpec":null
}
Perhaps the console is doing some magic in relation to the x-amz-s3-console-folder header, but the result is ideal because it is simply queried afterwards with a...
https://s3-ap-southeast-2.amazonaws.com/bucket?prefix=bar/&max-keys=100&marker=bar/&delimiter=/
I disagree with what @mtdowling said as on S3 Management Console you can create empty folder with the button provided by Amazon. I tested the API and we can actually create the same empty folder with a slash at the end of the key. So the code:
$s3Client->putObject(array(
'Bucket' => $bucket,
'Key' => $folder . '/',
'Body' => '',
));
works perfectly.
I would regard StreamWrapper as a simple wrapper and should not add too many custom logic. So it should either link to API CreateBucket to create bucket or PutObject with a slash at the end to create folder. The current implementation of StreamWrapper breaks some PHP libraries as they enforce folder existence by calling mkdir(), which you issue an error. Just let the API do the job.
Has this changed? i. e. #1779 seems to imply mkdir works for folders..
Most helpful comment
I disagree with what @mtdowling said as on S3 Management Console you can create empty folder with the button provided by Amazon. I tested the API and we can actually create the same empty folder with a slash at the end of the key. So the code:
works perfectly.
I would regard
StreamWrapperas a simple wrapper and should not add too many custom logic. So it should either link to APICreateBucketto create bucket orPutObjectwith a slash at the end to create folder. The current implementation ofStreamWrapperbreaks some PHP libraries as they enforce folder existence by callingmkdir(), which you issue an error. Just let the API do the job.