Метод толчка коллекции Laravel неизвестное поведение - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть коллекция, основанная на свойстве этой коллекции. Я хотел бы создать две дополнительные коллекции и передать их в коллекцию ответов.

Например,

$user = collect([
            "ID" => 4944,
            "reason" => "Friend Referral",
            "created_at" => "2016-08-29 18:23:53",
            "updated_at" => "2016-08-29 18:23:53",
            "type" => "credit",
            "amount" => "100",
            "usageCount" => 1
        ]);

    $credits = collect([]);
    $credits->push($user);

    if ($user->get('usageCount')) {
        $user->put('type','debit');
        $credits->push($user);
    }

Я получаюколлекция кредитов выглядит следующим образом:

[
{
"ID": 4944,
"reason": "Friend Referral",
"created_at": "2016-08-29 18:23:53",
"updated_at": "2016-08-29 18:23:53",
"type": "debit",
"amount": "100",
"usageCount": 1
},
{
"ID": 4944,
"reason": "Friend Referral",
"created_at": "2016-08-29 18:23:53",
"updated_at": "2016-08-29 18:23:53",
"type": "debit",
"amount": "100",
"usageCount": 1
}
]

Тип должен быть кредитом и дебетом, но я как-то толкаю тип дебета, чтобы сделать первый массив также типом дебета.

Я не понимаю.

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Цитируя документацию PHP

Один из ключевых моментов ООП PHP 5, который часто упоминается, это то, что "объекты передаются по ссылкам по умолчанию".Это не совсем верно.Этот раздел исправляет эту общую мысль, используя некоторые примеры.

Ссылка на PHP - это псевдоним, который позволяет двум разным переменным записывать одно и то же значение.Начиная с PHP 5, переменная объекта больше не содержит сам объект в качестве значения.Он содержит только идентификатор объекта, который позволяет методам доступа к объекту найти фактический объект.Когда объект отправляется с помощью аргумента, возвращается или присваивается другой переменной, различные переменные не являются псевдонимами: они содержат копию идентификатора, который указывает на тот же объект.

В вашем примерепеременная $user - это ссылка (или идентификатор), которая указывает на созданный вами объект.Поэтому, когда вы добавили объект $user в свою коллекцию, он также будет содержать эту ссылку.Поэтому, когда вы изменяете переменную $user, она обновляет тот же объект, на который ссылаются оба места, поэтому вы видите то, что видите.

Вы можете сделать это и увидеть похожее поведение:

$user = collect([
    "ID" => 4944,
    "reason" => "Friend Referral",
    "created_at" => "2016-08-29 18:23:53",
    "updated_at" => "2016-08-29 18:23:53",
    "type" => "credit",
    "amount" => "100",
    "usageCount" => 1
]);

// $second and $user now contain the same "reference" to your object
$second = $user;

// $second->type = 'debit' changes the object both $user and $second point to
$second->type = 'debit';

echo $user->type; // Outputs 'debit'

Чтобы обойти вашу проблему, вы можете просто сделать копию своего пользовательского объекта, который создает новый объект и новую ссылку, и изменить его перед передачей в свою коллекцию:

$second = clone $user;
if ($second->get('usageCount')) {
    $second->put('type','debit');
    $credits->push($second);
}
0 голосов
/ 13 сентября 2018

Это потому, что объекты передаются по ссылке.Поэтому, когда вы изменяете исходный объект, который был помещен в коллекцию, он изменяет элемент в коллекции.Вы можете решить эту проблему с помощью функции clone в PHP.Вот пример.

$user = collect([
        "ID" => 4944,
        "reason" => "Friend Referral",
        "created_at" => "2016-08-29 18:23:53",
        "updated_at" => "2016-08-29 18:23:53",
        "type" => "credit",
        "amount" => "100",
        "usageCount" => 1
    ]);

$credits = collect([]);
$credits->push($user);

$user = clone $user;

if ($user->get('usageCount')) {
    $user->put('type','debit');
    $credits->push($user);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...