Я не думаю, что ошибка, с которой вы сталкиваетесь, связана с вызовом функции вне класса или внутри класса, а также с синтаксическим анализом строк PHP и магическими методами Laravel.
Разбор PHP-строки позволяет вставлять имена переменных, но не функции. Другими словами, если вы сделаете следующее: "$this->toString()"
PHP будет думать, что имя вашей переменной - $this->toString
, а не $this->toString()
.
Итак, когда вы используете его таким образом, он пытается получить доступ к свойству класса с именем toString
вместо выполнения метода с именем toString()
.
В Laravel у моделей есть магический метод (__get()
), который позволяет динамически разрешать как атрибуты модели, так и отношения, что позволяет вам использовать, например, $mymodel->myattribute
без необходимости явно определять это свойство в классе. Итак, когда вы пытаетесь вызвать $this->toString
(без завершающих скобок), Laravel сначала проверяет, есть ли у этой модели атрибут с именем toString
и, если да, возвращает его значение. Если нет, он ищет функцию с именем toString()
и ожидает, что она определит отношение. Это последнее, что происходит с вами.
Я бы не стал использовать toString
для имени метода, потому что он слишком близок к магическому методу, называемому __toString()
, который позволяет вам определять неявное преобразование класса в строку (Laravel уже имеет это также определяется в его классе Model).
Для вашей конкретной проблемы, если вы хотите использовать значение внутри строки, вы можете обойти ограничение разбора строки, заключив его в фигурные скобки (что является хорошей привычкой устанавливать в любом случае, чтобы избежать путаницы):
Log::debug("{$this->toString()} wants to...");
В качестве альтернативы, отличная функция в Laravel - виртуальный аксессор , который можно определить так:
public function getDisplayNameAttribute() {
if ($this->telegram_first_name != null) {
return $this->telegram_first_name;
} else if ($this->telegram_username != null) {
return $this->telegram_username;
}
}
Вы в основном определяете функцию, которая начинается с get
и заканчивается Attribute
, и Laravel магически отображает это на любое слово (слова), которое вы вставляете между ними, чтобы вы могли получить к нему доступ как к нативному свойству.
Затем вы можете сделать:
Log::debug("$this->displayName wants to...");
и должно работать.