Closed aradhell closed 4 years ago
Hi @aradhell, thanks for reaching out to us. Can you provide a code sample showing how you're attempting to retrieve your object's URL / presigned URL? Unfortunately I haven't been able to reproduce this from my end on docker containers running the php:7.4.0RC3-fpm and php:7.4.0RC4-fpm-alpine images with the following code.
<?php
require_once("vendor/autoload.php");
use Aws\S3\S3Client;
$bucket = 'my-bucket';
$key = 'php/1889/test';
$body = fopen('test', 'r');
echo "Using AWS SDK for PHP version " . Aws\Sdk::VERSION.PHP_EOL;
$client = new S3Client([
'region' => 'us-west-2',
'version' => 'latest',
]);
$resp = $client->putObject([
'Bucket' => $bucket,
'Key' => $key,
'Body' => $body,
]);
$url = $client->getObjectUrl($bucket, $key);
print_r($url.PHP_EOL);
$cmd = $client->getCommand('GetObject', [
'Bucket' => $bucket,
'Key' => $key
]);
try {
$request = $client->createPresignedRequest($cmd, '+20 minutes');
$url = (string)$request->getUri();
echo "Presigned request created:\n{$url}\n";
} catch (AwsException $e) {
echo "Error creating presigned request:\n{$e}\n";
}
PHP 7.4.0RC3
root@8dfb17c25c18:/app# php -v
PHP 7.4.0RC3 (cli) (built: Oct 17 2019 14:40:29) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0-dev, Copyright (c) Zend Technologies
root@8dfb17c25c18:/app# php putObjGetURL.php
Using AWS SDK for PHP version 3.112.25
https://my-bucket.s3.us-west-2.amazonaws.com/php/1889/test
Presigned request created:
https://my-bucket.s3.us-west-2.amazonaws.com/php/1889/test?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLEABCDEFGHJ%2F20191021%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20191021T182533Z&X-Amz-SignedHeaders=host&X-Amz-Expires=1200&X-Amz-Signature=[redacted]
PHP 7.4.0RC4
/app # php -v
PHP 7.4.0RC4 (cli) (built: Oct 19 2019 03:51:14) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0-dev, Copyright (c) Zend Technologies
/app # php putObjGetURL.php
Using AWS SDK for PHP version 3.112.25
https://my-bucket.s3.us-west-2.amazonaws.com/php/1889/test
Presigned request created:
https://my-bucket.s3.us-west-2.amazonaws.com/php/1889/test?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAEXAMPLEABCDEFGHJ%2F20191021%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20191021T182608Z&X-Amz-SignedHeaders=host&X-Amz-Expires=1200&X-Amz-Signature=[redacted]
Hi @diehlaws, thanks for your help. Have you enabled error displaying on notice level?
edit: I used your code to test again.
My output with php-7.4.0RC4 / RC3 / RC2
PHP Notice: Trying to access array offset on value of type null in /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php on line 146
PHP Stack trace:
PHP 1. {main}() /Users/username/Documents/GitHub/my-repo/test.php:0
PHP 2. Aws\S3\S3Client->createPresignedRequest() /Users/username/Documents/GitHub/my-repo/test.php:24
PHP 3. Aws\serialize() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/S3/S3Client.php:354
PHP 4. GuzzleHttp\Promise\Promise->wait() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/functions.php:329
PHP 5. GuzzleHttp\Promise\Promise->waitIfPending() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:62
PHP 6. GuzzleHttp\Promise\Promise->invokeWaitList() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:225
PHP 7. GuzzleHttp\Promise\Promise->waitIfPending() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:267
PHP 8. GuzzleHttp\Promise\Promise->invokeWaitFn() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:223
PHP 9. GuzzleHttp\Promise\TaskQueue->run() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:246
PHP 10. GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure:/Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:154-158}() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/TaskQueue.php:47
PHP 11. GuzzleHttp\Promise\Promise::callHandler() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:156
PHP 12. Aws\RetryMiddleware->Aws\{closure:/Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:221-264}() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:203
PHP 13. Aws\S3\S3Client::Aws\S3\{closure:/Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/S3/S3Client.php:530-560}() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:248
PHP 14. Aws\RetryMiddleware::Aws\{closure:/Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:80-110}() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/S3/S3Client.php:535
PHP 15. Aws\RetryMiddleware::isRetryable() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:93
Notice: Trying to access array offset on value of type null in /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php on line 146
Call Stack:
0.0008 401504 1. {main}() /Users/username/Documents/GitHub/my-repo/test.php:0
0.1480 7931032 2. Aws\S3\S3Client->createPresignedRequest() /Users/username/Documents/GitHub/my-repo/test.php:24
0.1494 8009520 3. Aws\serialize() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/S3/S3Client.php:354
0.1640 8432232 4. GuzzleHttp\Promise\Promise->wait() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/functions.php:329
0.1640 8432232 5. GuzzleHttp\Promise\Promise->waitIfPending() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:62
0.1640 8432232 6. GuzzleHttp\Promise\Promise->invokeWaitList() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:225
0.1640 8432232 7. GuzzleHttp\Promise\Promise->waitIfPending() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:267
0.1640 8432232 8. GuzzleHttp\Promise\Promise->invokeWaitFn() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:223
0.1640 8432232 9. GuzzleHttp\Promise\TaskQueue->run() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:246
0.1641 8427136 10. GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure:/Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:154-158}() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/TaskQueue.php:47
0.1641 8427136 11. GuzzleHttp\Promise\Promise::callHandler() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:156
0.1641 8427136 12. Aws\RetryMiddleware->Aws\{closure:/Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:221-264}() /Users/username/Documents/GitHub/my-repo/vendor/guzzlehttp/promises/src/Promise.php:203
0.1641 8427944 13. Aws\S3\S3Client::Aws\S3\{closure:/Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/S3/S3Client.php:530-560}() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:248
0.1641 8427944 14. Aws\RetryMiddleware::Aws\{closure:/Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:80-110}() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/S3/S3Client.php:535
0.1641 8427944 15. Aws\RetryMiddleware::isRetryable() /Users/username/Documents/GitHub/my-repo/vendor/aws/aws-sdk-php/src/RetryMiddleware.php:93
Presigned request created:
https://my-bucket.s3.eu-west-1.amazonaws.com/creditsafe/reports/file.txt?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAZY3D2OYTCSAPCUTI%2F20191021%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20191021T214925Z&X-Amz-SignedHeaders=host&X-Amz-Expires=12000&X-Amz-Signature=bfb4f466cf76b62bc38c5043bf17df867f069a33950dd2a3c8397df7b09f410b
@aradhell did you solve this problem? I have same one...
"retries" attribute sets to 0 solve the problem for me. Also works in Laravel filesystems configuration.
$client = new S3Client([ 'retries' => 0 ]);
@aradhell did you solve this problem? I have same one...
I ignored warnings as a temporary solution, couldn't find time to dig it deeper. @haxmedia suggests another workaround.
I experienced the same issue. It appears that in some cases, RetryMiddleware::isRetryable is called with an empty result object passed to it where $result['@metadata'] is not set. This quick patch resolves that issue by returning false in those cases.
diff --git a/src/RetryMiddleware.php b/src/RetryMiddleware.php
index 4ad945a9c..d5e65a30d 100644
--- a/src/RetryMiddleware.php
+++ b/src/RetryMiddleware.php
@@ -143,6 +143,10 @@ class RetryMiddleware
}
if (!$error) {
+ if (!isset($result['@metadata'])) {
+ return false;
+ }
+
return isset($statusCodes[$result['@metadata']['statusCode']]);
}
The final release of PHP7.4 triggers a notice (during RC versions it was a warning), when you try to use array access (like $foo['bar']
) on a variable that is not an array (like when $foo value is null).
@Demoboy solution works (because there are flows where $result['@metadata']
can be null. I did the same on my env (before seen his message):
<?php
return is_array($result['@metadata']) ? isset($statusCodes[$result['@metadata']['statusCode']]) : false;
In my Laravel project, this issue happened somewhere else in the code base: https://github.com/aws/aws-sdk-php/blob/8fa68de81738f851e0aa62fbc0a657f2905aa860/src/S3/PutObjectUrlMiddleware.php#L46-L48
Both provided solutions don't work for me, as the error happens before RetryMiddleware
.
This also means that the proposed fix in #1912 isn't sufficient.
I'm using php 7.4.0
and sdk verson 3.124.0
.
Full error:
{
"message": "Trying to access array offset on value of type null",
"exception": "ErrorException",
"file": "/path/to/project/vendor/aws/aws-sdk-php/src/S3/PutObjectUrlMiddleware.php",
"line": 48,
"trace": [
{
"file": "/path/to/project/vendor/aws/aws-sdk-php/src/S3/PutObjectUrlMiddleware.php",
"line": 48,
"function": "handleError",
"class": "Illuminate\\Foundation\\Bootstrap\\HandleExceptions",
"type": "->"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/Promise.php",
"line": 203,
"function": "Aws\\S3\\{closure}",
"class": "Aws\\S3\\PutObjectUrlMiddleware",
"type": "->"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/Promise.php",
"line": 156,
"function": "callHandler",
"class": "GuzzleHttp\\Promise\\Promise",
"type": "::"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/TaskQueue.php",
"line": 47,
"function": "GuzzleHttp\\Promise\\{closure}",
"class": "GuzzleHttp\\Promise\\Promise",
"type": "::"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/Promise.php",
"line": 246,
"function": "run",
"class": "GuzzleHttp\\Promise\\TaskQueue",
"type": "->"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/Promise.php",
"line": 223,
"function": "invokeWaitFn",
"class": "GuzzleHttp\\Promise\\Promise",
"type": "->"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/Promise.php",
"line": 267,
"function": "waitIfPending",
"class": "GuzzleHttp\\Promise\\Promise",
"type": "->"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/Promise.php",
"line": 225,
"function": "invokeWaitList",
"class": "GuzzleHttp\\Promise\\Promise",
"type": "->"
},
{
"file": "/path/to/project/vendor/guzzlehttp/promises/src/Promise.php",
"line": 62,
"function": "waitIfPending",
"class": "GuzzleHttp\\Promise\\Promise",
"type": "->"
},
{
"file": "/path/to/project/vendor/aws/aws-sdk-php/src/functions.php",
"line": 328,
"function": "wait",
"class": "GuzzleHttp\\Promise\\Promise",
"type": "->"
},
{
"file": "/path/to/project/vendor/aws/aws-sdk-php/src/S3/S3Client.php",
"line": 370,
"function": "Aws\\serialize"
},
{
"file": "/path/to/project/vendor/laravel/vapor-core/src/Http/Controllers/SignedStorageUrlController.php",
"line": 36,
"function": "createPresignedRequest",
"class": "Aws\\S3\\S3Client",
"type": "->"
},
{
"function": "store",
"class": "Laravel\\Vapor\\Http\\Controllers\\SignedStorageUrlController",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
"line": 54,
"function": "call_user_func_array"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
"line": 45,
"function": "callAction",
"class": "Illuminate\\Routing\\Controller",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
"line": 219,
"function": "dispatch",
"class": "Illuminate\\Routing\\ControllerDispatcher",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
"line": 176,
"function": "runController",
"class": "Illuminate\\Routing\\Route",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 692,
"function": "run",
"class": "Illuminate\\Routing\\Route",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 130,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
"line": 41,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 105,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 694,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 669,
"function": "runRouteWithinStack",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 635,
"function": "runRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 624,
"function": "dispatchToRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 176,
"function": "dispatch",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 130,
"function": "Illuminate\\Foundation\\Http\\{closure}",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/path/to/project/vendor/spatie/laravel-cors/src/Cors.php",
"line": 28,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Spatie\\Cors\\Cors",
"type": "->"
},
{
"file": "/path/to/project/vendor/fideloper/proxy/src/TrustProxies.php",
"line": 57,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 171,
"function": "handle",
"class": "Fideloper\\Proxy\\TrustProxies",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 105,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 151,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/path/to/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 116,
"function": "sendRequestThroughRouter",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/path/to/project/public/index.php",
"line": 55,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/Users/xxxxx/.composer/vendor/laravel/valet/server.php",
"line": 158,
"function": "require"
}
]
}
I updated the PR on https://github.com/aws/aws-sdk-php/pull/1912, to to cover @georgeboot issue.
This was fixed in #1916
As noted by georgeboot, this was resolved in #1916.
Hello, I am having an issue while trying to get urls for the objects.
Version of AWS SDK for PHP?
aws/aws-sdk-php 3.112.25
Version of PHP (
php -v
)?php-7.4.0RC2 / RC3 / RC4
What issue did you see?
Error on S3Client get URL / temporary URL ErrorException: Trying to access array offset on value of type null
Steps to reproduce
Upload an object and try to get url / a presigned url
Additional context
Using Laravel 6 but I also tried it directly from the SDK