Web

PHP - сбросить свойства объектов в массиве после вызова array_filter

У меня есть массив клиентов (объектов) и еще один массив счетов (также объектов): 

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. Хотя это и работает, лучше иметь его в определении класса.

 

Схожие статьи

Оптимизация HTML, CSS и JavaScript: как настроить и ускорить
Web

Оптимизация HTML, CSS и JavaScript: как настроить и ускорить

Web

Как использовать str_replace, чтобы она действовала только при первом совпадении

Web

Для laravel требуется расширение Mcrypt PHP

Web

Как выполнить загрузку файла с помощью сериализации jquery