別のホストにある受信側のPHPスクリプトにCURLを介してフォームデータを送信するのに問題があります。
_Array to string conversion
_エラーが表示されます
これは、私が投稿している配列の_print_r
_です。
_Array
(
[name] => Array
(
[0] => Jason
[1] => Mary
[2] => Lucy
)
[id] => 12
[status] => local
[file] => @/test.txt
)
_
これは、エラーが発生する行です。
_curl_setopt($this->ch, CURLOPT_POSTFIELDS, $post);
_
3番目の引数mustは配列である必要があるため、この同じ配列を介してファイルを送信するときに_Content-Type
_ヘッダーを_multipart/form-data
_に設定する必要があるため、配列を変換できませんクエリ文字列に使用するか、http_build_query()
を使用します。
また、受信ホストのコードにアクセスできないため、アレイをシリアル化および非シリアル化できません。
配列であるnameキーの値がこのエラーの原因であると想定しています。また、_CURLOPT_POSTFIELDS
_多次元配列をサポートしていません。これを回避する他の方法はありますか、それとも運命ですか?
前もって感謝します!
配列全体を渡すのではなく、POST文字列を手動で構築する必要があります。その後、curlの自動選択コンテンツヘッダーを次のようにオーバーライドできます。
curl_setopt($c, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
シリアル化/ json化は簡単ですが、あなたが言うように、受信側を制御することはできないので、やることが少し余分にあります。
function http_build_query_for_curl( $arrays, &$new = array(), $prefix = null ) {
if ( is_object( $arrays ) ) {
$arrays = get_object_vars( $arrays );
}
foreach ( $arrays AS $key => $value ) {
$k = isset( $prefix ) ? $prefix . '[' . $key . ']' : $key;
if ( is_array( $value ) OR is_object( $value ) ) {
http_build_query_for_curl( $value, $new, $k );
} else {
$new[$k] = $value;
}
}
}
$arrays = array(
'name' => array(
'first' => array(
'Natali', 'Yura'
)
)
);
http_build_query_for_curl( $arrays, $post );
print_r($post);
HTTPリクエストに関しては、配列の概念は実際には存在しません。 PHP(および他のサーバー側言語の可能性が高い)には、looksのような要求データを取得できるロジックが組み込まれています(それに)配列し、$_GET
、$_POST
などにデータを入力しながら配列としてまとめます.
たとえば、POSTフォームの配列の場合、フォーム要素は次のようになります。
<form ...>
<input name="my_array[0]">
<input name="my_array[1]">
<input name="my_array[2]">
</form>
あるいは:
<form ...>
<input name="my_array[]">
<input name="my_array[]">
<input name="my_array[]">
</form>
PHPは受信時にこのデータをどのように処理するか(つまり、配列を構築する)をHTMLとHTTPに認識していますが、同様の(または同じ、これは技術的に有効なHTMLではありません)の名前です。
CURLリクエストの逆を行うには、配列をキーの文字列表現に分解する必要があります。 name
配列を使用すると、次のようなことができます。
foreach ($post['name'] as $id => $name)
{
$post['name[' . $id . ']'] = $name;
}
unset($post['name']);
その結果、$post
配列は次のようになります。
Array
(
[name[0]] => Jason
[name[1]] => Mary
[name[2]] => Lucy
[id] => 12
[status] => local
[file] => @/test.txt
)
そして、投稿する配列内の各キーは、scalar値になります。これはcURLが予期しているもので、配列は必要に応じて表されますHTTP。
最も簡単な解決策は以下を実行することです:
$array = urldecode(http_build_query($array));
以下は、これが実際に使用されるサンプルコードです。
https://Gist.github.com/gayanhewa/142c48162f72e68a4a2
上記のGistに$ paramsセクションをネストすると、それに応じて解析され、curlを介した投稿の準備が行われます。
最初に、彼の 洞察に満ちた返信 に感謝しますDaniel Vandersluis。彼の入力に基づいて、元の質問の問題を解決するためにこれを思いつきました。
<?php
function curl_postfields_flatten($data, $prefix = '') {
if (!is_array($data)) {
return $data; // in case someone sends an url-encoded string by mistake
}
$output = array();
foreach($data as $key => $value) {
$final_key = $prefix ? "{$prefix}[{$key}]" : $key;
if (is_array($value)) {
// @todo: handle name collision here if needed
$output += curl_postfields_flatten($value, $final_key);
}
else {
$output[$final_key] = $value;
}
}
return $output;
}
使用法は次のようになります。
curl_setopt($this->ch, CURLOPT_POSTFIELDS, curl_postfields_flatten($post));
この関数は、配列を次のように変換します。
array(
'a' => 'a',
'b' => array(
'c' => array(
'd' => 'd',
'e' => array(
'f' => 'f',
),
),
),
);
これに:
array(
'a' => 'a',
'b[c][d]' => 'd',
'b[c][e][f]' => 'f',
)
次のようなキーの衝突がある場合、混合フォーマットの場合は処理しません。
array(
'b[c]' => '1',
'b' => array(
'c' => '2',
),
);
出力には、そのキーの最初の値のみが含まれます
array(
'b[c]' => '1'
)
オプションを文字列として渡す必要があると思います。
curl_setopt($this->ch, CURLOPT_POSTFIELDS, 'name[]=Jason&name[]=Mary&name[]=Lucy...');
その後、CURLOPT_HTTPHEADERを使用してヘッダーを手動で設定できるはずです。
CURLオプション_CURLOPT_POSTFIELDS
_は、文字列または単純な配列のいずれかを受け入れますが、ネストされた配列は受け入れません。そうしようとすると、_Array to string conversion
_エラーが生成されます。
ただし、http_build_query()
はネストされた配列を処理できるので、それを使用して_$_POST
_配列を文字列に変換し、代わりにその文字列を送信します。だからあなたが持っているところ;
_curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
_
代わりにこれを使用してください。
_curl_setopt($ch, CURLOPT_POSTFIELDS, urldecode(http_build_query($_POST)));
_