Laravel получить имя класса соответствующей модели

В моем приложении Laravel у меня есть модель Faq. Модель Faq может содержать много моделей Product, поэтому класс Faq содержит следующую функцию:

class Faq extends Eloquent{ 
    public function products(){
        return $this->belongsToMany('Product');
    }
}

В контроллере я хотел бы получить имя класса, которое определяет отношение. Например, если у меня есть объект Faq, например:

$faq = new Faq();

Как определить имя класса отношения, которое в этом случае будет Product. В настоящее время я могу сделать это следующим образом:

$className = get_class($faq->products()->get()->first());

Однако мне интересно, есть ли способ выполнить эту же задачу без фактического выполнения запроса.

Ответы

Ответ 1

Да, есть способ получить связанную модель без запроса:

$className = get_class($faq->products()->getRelated());

Он будет работать для всех отношений.

Это вернет полное имя с пространством имен. Если вы хотите использовать только базовое имя:

// laravel helper:
$baseClass = class_basename($className);

// generic solution
$reflection = new ReflectionClass($className);
$reflection->getShortName();

Ответ 2

Я думаю, вы не можете этого сделать. Я не знаю, для чего вам это нужно, но вы можете просто добавить дополнительный метод, в котором вы поместите все свои имена класса отношений и где вы вернете тот, который вы хотите:

public function getRelationsClassName($relation) {
    $relations = [
        'products' => 'Product',
        'users' => 'User',
    ]  
    return isset($relations[$relation]) ? $relations[$relation] : null;
}

Ответ 3

Используя PHP API отражения, вы можете попробовать следующее:

$class = new ReflectionClass('Faq');
$method = $class->getMethod('products');
$startLine = $method->getStartLine();
$endLine = $method->getEndLine();
$length = $endLine - $startLine;

$fileName = $class->getFileName();
if(!empty($fileName)) {
    $fileContents = file($fileName);
    $methodSource = trim(implode('',array_slice(file($fileName),$startLine,$length)));
    preg_match('/\((.*)\)/', $methodSource, $m);
    $className = $m[1]; // <-- This is the result
}

Ваш метод должен быть написан в этом формате в вашем классе:

public function products(){
    return $this->belongsToMany('Product');
}

Кстати, нужно ли это делать? возможно, вы можете пойти с Marcin Nabiałek простым и легким ответом, я просто играл вокруг него.