Как сформировать массив payments в PHP
Узнайте, как собрать массив payments с ключами new1, new2 и т.д. в PHP, избегая вложенных массивов, и исправьте ошибку array_push.
Как правильно сформировать ассоциативный массив payments в PHP, чтобы он имел следующую структуру:
array(3) {
"seller" => object(SimpleXMLElement)#539 (1) {
[0] => object(SimpleXMLElement)#546 (0) {}
}
"product_id" => int(2320617)
"payments" => array(2) {
"new1" => array(3) {
"type" => string(7) "payment"
"title" => string(9) "Тест1"
"fields" => array(3) {
"price" => string(5) "19999"
"currency" => string(3) "RUB"
"code" => string(4) "CODE"
}
}
"new2" => array(3) {
"type" => string(7) "payment"
"title" => string(9) "Тест2"
"fields" => array(3) {
"price" => string(4) "9999"
"currency" => string(3) "RUB"
"code" => string(4) "CODE"
}
}
}
}
А вот массив, который я получаю сейчас:
array(3) {
"seller" => object(SimpleXMLElement)#539 (1) {
[0] => object(SimpleXMLElement)#546 (0) {}
}
"product_id" => int(2320617)
"payments" => array(16) {
[0] => array(1) {
"new1" => array(3) { ... }
}
[1] => array(1) {
"new2" => array(3) { ... }
}
...
}
}
Т.е. у меня получается массив из 16 вложенных массивов, где каждый вложенный массив содержит один элемент с ключом newX. Это не соответствует требуемой структуре и приводит к ошибкам.
Мой текущий код:
$methods = /* массив со всеми методами */;
$ready = array();
for ($i = 0; $i < count($methods); $i++) {
$arr = array('new'.$i+1 => [
'type' => 'payment',
'title' => strval($methods[$i]->name),
'fields' => [
"price" => strval($methods[$i]->currencies->currency->price),
"currency" => strval($methods[$i]->currencies->currency->currency),
"code" => strval($methods[$i]->code)
],
]);
array_push($ready, $arr);
}
$payments = array(
"seller" => $seller_name,
"product_id" => $product_id,
'payments' => $ready,
);
var_dump($payments);
Как исправить этот код, чтобы массив payments имел нужную структуру с ключами new1, new2 и т.д., а не массив из 16 вложенных массивов?
Краткий ответ
Чтобы получить массив вида
$payments = [
'seller' => $seller_name,
'product_id' => $product_id,
'payments' => [
'new1' => [/* … */],
'new2' => [/* … */],
],
];
не обязательно использовать array_push.
Нужно просто пополнять ассоциативный массив $ready (или сразу $payments['payments']) ключами new1, new2 и т.д.
$ready = []; // ← ассоциативный массив
foreach ($methods as $idx => $method) {
$ready['new' . ($idx + 1)] = [
'type' => 'payment',
'title' => (string)$method->name,
'fields' => [
'price' => (string)$method->currencies->currency->price,
'currency' => (string)$method->currencies->currency->currency,
'code' => (string)$method->code,
],
];
}
$payments = [
'seller' => $seller_name,
'product_id' => $product_id,
'payments' => $ready,
];
Почему array_push ломает структуру
array_push($ready, $arr) добавляет значение $arr в конец массива $ready с числовым ключом (0, 1, 2 …).
В результате вы получаете
$ready = [
0 => ['new1' => [...]],
1 => ['new2' => [...]],
// …
];
а не
$ready = [
'new1' => [...],
'new2' => [...],
];
К тому же в выражении 'new'.$i+1 оператор + имеет более высокую приоритетность, чем .
Таким образом 'new'.$i+1 сначала вычисляется как ('new' . $i) + 1, а не как 'new' . ($i + 1).
В итоге ключи могут получаться неверными (new0 → 1, new1 → 2 и т.д.).
Полный рабочий пример
<?php
$methods = /* массив со всеми методами */;
$seller_name = /* объект SimpleXMLElement */;
$product_id = 2320617;
$ready = [];
foreach ($methods as $idx => $method) {
// ключи new1, new2, …
$key = 'new' . ($idx + 1);
$ready[$key] = [
'type' => 'payment',
'title' => (string)$method->name,
'fields' => [
'price' => (string)$method->currencies->currency->price,
'currency' => (string)$method->currencies->currency->currency,
'code' => (string)$method->code,
],
];
}
$payments = [
'seller' => $seller_name,
'product_id' => $product_id,
'payments' => $ready,
];
var_dump($payments);
Вывод будет точно таким, как показано в задаче:
array(3) {
["seller"]=>
object(SimpleXMLElement)#... (1) {
[0]=>
object(SimpleXMLElement)#... (0) {}
}
["product_id"]=>
int(2320617)
["payments"]=>
array(2) {
["new1"]=>
array(3) { ... }
["new2"]=>
array(3) { ... }
}
}
Что можно улучшить
| Что | Как сделать |
|---|---|
| Чтение | Использовать foreach вместо for ($i = 0; $i < count($methods); $i++). |
| Приведение типов | В PHP 8 можно написать (string)$method->name вместо strval(). |
| Переиспользуемость | Выделить создание одного платежа в отдельную функцию: makePayment($method, $idx) и вызывать её в цикле. |
| Проверка данных | Добавить проверки, что $method->currencies->currency существует, чтобы избежать ошибок. |
Итого
Уберите array_push, замените его прямым присваиванием в ассоциативный массив, и убедитесь, что ключи формируются как 'new' . ($i + 1). Это создаст нужную структуру и избавит от лишних вложенных массивов.