У меня есть массив клиентов (объектов) и еще один массив счетов (также объектов):
class Client {
public $id;
public $name;
}
class Invoice {
public $id;
public $clientId;
public $amount;
}
Я хочу создать вложенный массив счетов для каждого клиента, без свойства $clientId.
Я попробовал следующее:
foreach ($clientesArr as &$client) {
$client->invoices = array_filter($invoicesArr, function ($invoice) use ($client){
return $invoice->clientId === $client->id;
});
foreach ($client->invoices as &$invoice) {
unset($tec->clientId);
}
Этот код вызывает следующую ошибку:Undefined property: stdClass::$id_clientes
Почему это происходит?
Ответ 1
Массивы присваиваются по копии, а объекты - по ссылке. Когда вы используете array_filter, вы создаете новый массив, но поскольку элементы массива являются объектами, они копируются по ссылке.
Для вашей проблемы есть несколько решений:
Используйте array_map вместо цикла foreach:
Вместо того чтобы перебирать элементы массива и изменять их, вы можете создавать новые элементы.
$client->invoices = array_map(function ($el) {
$newEl = clone($el);
unset($newEl->clientId);
return $newEl;
}, $client->invoices);
Добавьте условие внутри обратного вызова array_filter:
$client->invoices = array_filter($invoicesArr, function ($invoice) use ($client) {
return isset($invoice->clientId) && $invoice->clientId === $client->id;
});
Обратите внимание, что вы присваиваете свойство invoices, которое не объявлено в вашем классе Client. Хотя это и работает, лучше иметь его в определении класса.
Web