AWS"缺少所需的客户端配置选项" Yii :: createObject()默认配置的异常

时间:2017-07-04 16:20:10

标签: php amazon-web-services yii2 amazon-dynamodb aws-sdk

我试图让一个简单的Web应用程序使用Yii 2框架,一个托管在AWS上的DynamoDB数据库和一个适用于PHP的AWS开发工具包。我只是在电影数据库中保存/检索电影细节。

(出于在此处复制代码的目的,我不打算复制我的真实AWS密钥/秘密。)

当我创建像这样的Aws \ Sdk对象时,一切都按照我想要的方式运行:

$sdk = new Aws\Sdk([
    'region'   => 'us-west-2',
    'version'  => 'latest',
    'credentials' => [
        'key'     => 'KEYKEYKEYKEYKEYKEYKE',
        'secret'  => 'SECRETSECRETSECRETSECRETSECRETSECRETSECR'
    ]
]);
$dynamodb = $sdk->createDynamoDb();

但是我希望利用Yii的默认配置和Yii :: createObject()方法,这样我就不必指定区域,版本和我创建一个Aws \ Sdk对象的每个地方的凭据。因此,根据Yii documentation,我已保存到我的应用程序配置中:

\Yii::$container->set('Aws\Sdk', [
    'region'      => 'us-west-2',
    'version'     => 'latest',
    'credentials' => [
        'key'     => 'KEYKEYKEYKEYKEYKEYKE',
        'secret'  => 'SECRETSECRETSECRETSECRETSECRETSECRETSECR'
    ]
]);

现在无论我在哪里创建Aws \ Sdk对象,我的代码都是这样的:

$sdk = Yii::createObject('Aws\Sdk');
$dynamodb = $sdk->createDynamoDb();

但是,当我这样做的时候,我从AWS得到一个InvalidArgumentException,关于"缺少所需的客户端配置选项"。如果我var_dump()变量后面的$sdk变量,我可以看到该对象具有所需的区域,版本和凭证属性,但是我指定$dynamodb变量的下一行抛出异常。

我希望有人能告诉我出错的地方。

1 个答案:

答案 0 :(得分:3)

首先,您不应该在代码中放置凭据。我推荐以下内容:

  • 如果您在EC2实例上运行此代码,请将IAM角色应用于该实例。使用角色,您可以准确声明将在实例中运行的CLI / SDK调用的权限。 SDK开始拨打电话时it will contact the instance metadata server and get a set of temporary credentials。当然,这一切都是透明的,无需你做任何事情。由于凭证在一段时间后过期(当您透明地发生这种情况时,您的SDK当然会获取新凭据)。这是最好的选择,因为您不再需要担心凭据,其他SDK或CLI可以使用它,而且这都是暂时的。
  • Use a credentials file。如果您的代码不在AWS领域且无法使用IAM角色,那么您应该真的这样做。虽然您的凭据变得更加集中,但它们至少不属于您可能泄露的代码库。此外,它还可以让您轻松使用其他语言,并且还可以自动提取凭据。

现在转到另一部分:

\Yii::$container->set('Aws\Sdk', [
    'region'      => 'us-west-2',
    'version'     => 'latest',
    'credentials' => [
        'key'     => 'KEYKEYKEYKEYKEYKEYKE',
        'secret'  => 'SECRETSECRETSECRETSECRETSECRETSECRETSECR'
    ]
]);

如果你看the source code

,这不是你的想法
 * If a class definition with the same name already exists, it will be overwritten with the new one.
 * You may use [[has()]] to check if a class definition already exists.
 *
 * @param string $class class name, interface name or alias name
 * @param mixed $definition the definition associated with `$class`. It can be one of the following:
 *
 * - a PHP callable: The callable will be executed when [[get()]] is invoked. The signature of the callable
 *   should be `function ($container, $params, $config)`, where `$params` stands for the list of constructor
 *   parameters, `$config` the object configuration, and `$container` the container object. The return value
 *   of the callable will be returned by [[get()]] as the object instance requested.
 * - a configuration array: the array contains name-value pairs that will be **used to initialize the property**
 *   **values of the newly created object** when [[get()]] is called. The `class` element stands for the
 *   the class of the object to be created. If `class` is not specified, `$class` will be used as the class name.
 * - a string: a class name, an interface name or an alias name.
 * @param array $params the list of constructor parameters. The parameters will be passed to the class
 * constructor when [[get()]] is called.
 * @return $this the container itself
 */

注意“**”标记区域。换句话说,第二个参数不是一组构造函数参数,它们可能是您想要的,而是一个在调用构造函数后将设置的参数数组。相反,您希望第二个参数为空,第三个参数为数组:

\Yii::$container->set('Aws\Sdk', [], [[
    'region'      => 'us-west-2',
    'version'     => 'latest'
]]);

数组中的数组看起来很奇怪,但这是因为参数数组基本上是索引索引并将每个参数设置为位置参数。希望这会有所帮助。