Я добавил файл вспомогательной функции в composer.json сразу после записи psr-4
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
"files": [
"app/Http/Helpers/helpers.php"
]
},
но выдает синтаксическую ошибку:
<?php
namespace App\Http\Helpers;
if (!function_exists('entity_url')) {
function entity_show($entityType, $id, $locale = null) {
if (is_null($locale) && function_exists('app')) {
$locale = app()->getLocale();
}
$entity = \App\Models\{ $entityType }::find($id); // syntax error
}
}
Ошибка синтаксического анализа: синтаксическая ошибка, неожиданный токен "\"
Если я использую любую существующую актуальную модель, она работает: $entity = \App\Models\Foobar
. В моем коде есть несколько случаев, когда сложный фигурный синтаксис ({ $entityType }
) не вызывает проблем, почему он здесь?
Редактировать
$class = '\\App\\Models\\' . $entityType;
и $entity = "\\App\\Models\\$entityType"::find($id);
работают, но я до сих пор не понимаю, почему. Во многих контроллерах я могу легко использовать \App\Models\{$entityType}::
.
🤔 А знаете ли вы, что...
PHP обладает большим сообществом разработчиков и обширной документацией.
Синтаксическая ошибка возникает независимо от того, где находится ваш код.
Разница в том, что вспомогательный файл загружается и компилируется напрямую (автозагружается), в то время как класс контроллера загружается/компилируется только при вызове.
Это означает, что если вы возьмете класс (например, User::class) и добавите в него эту функцию.
class User
{
public static function foo()
{
return 'bar';
}
public function entity_show($entityType, $id, $locale = null) {
$entity = \App\Models\{ $entityType }::find($id); // syntax error
}
}
Если вы запустите команду php artisan tinker
, она не вызовет синтаксическую ошибку. Но если в laravel tinker запустить User::foo()
, появится ошибка.
Чтобы динамически загружать класс, избегая синтаксической ошибки, сгенерируйте строку класса заранее.
if (!function_exists('entity_url')) {
function entity_show($entityType, $id, $locale = null) {
if (is_null($locale) && function_exists('app')) {
$locale = app()->getLocale();
}
$entity = ('\App\Models\\' . $entityType)::find($id);
}
}
Хотя я настоятельно рекомендую вам отказаться от использования вызовов динамических классов, поскольку это будет мешать поиску использования классов, когда вы захотите их изменить. Простой способ для вашей функции - передать объект для поиска в вашей функции (что также позволит избежать проверки существования объекта в БД внутри этой функции)
use Illuminate\Database\Eloquent\Model;
if (!function_exists('entity_url')) {
function entity_show(Model $entity, $locale = null) {
if (is_null($locale) && function_exists('app')) {
$locale = app()->getLocale();
}
//...
}
}