Почему последовательные вызовы работают, а попытка вызвать их в одной строке приводит к ошибке?

Я переписал несколько отдельных функций в одном классе с его методами. Однако у меня возникла проблема: когда я вызываю методы последовательно, всё работает. Пример кода выглядит так:

```php
class ProductAmount
{
    function __construct($array=array()){ ... }
    function getOfers($items=[]){ ... }
    function getProfuctStore($inListStore='N'){ ... }
    ...
}
```

При вызове методов по отдельности всё работает корректно:

```php
$obj = new \ProductAmount();
$obj->getOfers([229411]); // возвращает true
$obj->getProfuctStore('Y'); // возвращает true
$res = $obj->setListStore('Y'); // возвращает array
```

Но когда я пытаюсь выполнить все вызовы в одной строке, возникает ошибка:

```php
$obj = new ProductAmount();
$res = $obj->getOfers([229411])->getProfuctStore('Y')->setListStore('Y');
```

Получаю сообщение об ошибке: "Call to a member function getProfuctStore() on bool". В чем может быть проблема?
  • 24 сентября 2024 г. 11:33
Ответы на вопрос 5
Ваш код выдаёт ошибку, потому что метод `getOfers` возвращает значение типа `bool`, а вы пытаетесь вызвать следующий метод `getProfuctStore` на этом булевом значении.

В PHP, если метод возвращает `true` или `false`, это означает, что вы не можете вызывать другие методы на этом значении, так как это не является объектом (в данном случае - это булевое значение).

Давайте проанализируем вашу цепочку вызовов.

1. `getOfers([229411])` - если этот метод возвращает `true`, то вы пытаетесь вызвать следующий метод: `getProfuctStore('Y')` на `true`, что и вызывает ошибку "Call to a member function getProfuctStore() on bool".

2. Если вам нужно вызвать методы последовательно, вы можете изменить методы таким образом, чтобы они возвращали `$this` (текущий объект), если вы хотите использовать цепочку вызовов. Либо вам нужно будет разбивать вызовы методов на отдельные строки, как вы уже делали.

Вот пример, как можно изменить методы, чтобы они возвращали `$this`:

```php
class ProductAmount
{
    function __construct($array=array()){ /* ваш код */ }
    
    function getOfers($items=[])
    {
        // Ваш код ...
        return $this; // Возвращаем текущий объект
    }
    
    function getProfuctStore($inListStore='N')
    {
        // Ваш код ...
        return $this; // Возвращаем текущий объект
    }
    
    function setListStore($inListStore='Y')
    {
        // Ваш код ...
        return []; // Возвращаем массив
    }
}
```

Теперь вызов будет работать правильно:

```php
$obj = new ProductAmount();
$res = $obj->getOfers([229411])->getProfuctStore('Y')->setListStore('Y');
```

Имейте в виду, что если `setListStore()` возвращает массив, то вы не сможете продолжить цепочку вызовов после этого, если только вы не измените и его так, чтобы он тоже возвращал `$this`, либо сам объект. Это будет зависеть от вашей логики и того, что вам нужно сделать.
Метод getOfers() должен возвращать объект класса, а не true. 

class ProductAmount
{
    function __construct($array = array()) { 
        ...
    }

    function getOfers($items = []) {
        ...
        return $this;
    }

    function getProfuctStore($inListStore = 'N') {
        ...
        return $this;
    }

    function setListStore($inListStore = 'Y') {
        ...
        return $this;
    }
}


$obj = new ProductAmount();
$res = $obj->getOfers([229411])->getProfuctStore('Y')->setListStore('Y');
Для такой цепочки каждая функция должна возвращать $this. 
По неймингу - префиксы set и get, как правило используются для сеттеров и геттеров, то есть функций, устанавливающих и возвращающих значения свойств экземпляра. Использовать их для других целей, конечно, можно, но крайне не рекомендуется.
Тебе необходимо что бы функция " getProfuctStore " возвращала тот же объект в котором оно находится. 

function getProfuctStore($inListStore='N') { return $this; }
Похожие вопросы