如何在 Laravel 中返​​回数据库表名

Posted

技术标签:

【中文标题】如何在 Laravel 中返​​回数据库表名【英文标题】:How to return database table name in Laravel 【发布时间】:2012-12-14 11:54:46 【问题描述】:

有没有一种方法可以让我所在的模型正在使用当前的数据库表?我看到 Laravel/Database/Eloquent/model.php 中有一个 table() 函数,但我一直没有成功调用它从我所在的模型中调用它。

【问题讨论】:

【参考方案1】:

Eloquent\Model 中定义了一个公共 getTable() 方法,因此您应该可以使用$model->getTable()

【讨论】:

好吧,这似乎只有在您拥有模型的实际实例时才有效。它在作为静态函数调用时不起作用。 @Robert 它调用的是实例方法,而不是静态方法,所以没有什么可以推断出静态方法会存在。 您不必拥有实例。你可以做app(Model::class)->getTable(); @sabertababaeyazdi Model::class 只是一个字符串。您可以在命令行中传递它并使用该变量。例如app($modelClass)->getTable()。但它必须包含命名空间。 getTable() 不包含任何表前缀,如果您正在使用它。【参考方案2】:

泰勒有一个answer 来回答你的问题:

在模型类中,您可以执行以下操作:

return with(new static)->getTable();

如果您希望所有模型都能够静态返回表名,那么可以这样:

class BaseModel extends Eloquent 

    public static function getTableName()
    
        return with(new static)->getTable();
    



class User extends BaseModel 




User::getTableName();

【讨论】:

对于 Laravel 5.3 你必须把它放在 Illuminate\Database\Eloquent\Model 工作正常,谢谢! 永远不要这样做@Santee。永远不要更改 vendor 文件夹中的文件。 你是正统的Tainmar。谢谢。 我看不到在这里使用with 的好处。 @poring91 为什么with(new static)(new static) 好? laravel.com/docs/5.7/helpers#method-with【参考方案3】:

2019 年 4 月编辑:此答案现已过时。查看 Flyn San 的新正确答案

是的 - Eloquent 有一个 $table 变量。您可以通过两种方式访问​​它:

class yourModel extends Eloquent 

        public static $table = "differentTable";

        function someFunction()
        
             return yourModel::$table;
        

class yourModel extends Eloquent 

    public function someFunction()
    
        return $this->table();

    

然后在你的代码中

Route::get('/', function () 
    $model = new yourModel();   
    dd($model->someFunction());
);

【讨论】:

感谢您的帮助。我已经尝试过手动设置表名而不是手动设置表名。我不断得到“不在对象上下文中使用 $this”。有任何想法吗?谢谢! Chris G: 你能在这里复制/粘贴你的代码吗,因为你得到的错误看起来像是在静态方法中调用 $this 我认为 eloquent 模型中已经有一个 getTable() 函数。除此之外,在子类中复制和粘贴相同的函数是没有意义的。如果受保护的属性缺少函数包装器(在这种情况下没有),请使用 trait。 @JedLynch - 这个答案是在 2012 年,早在 Laravel 中存在该功能之前。我将对其进行编辑以指出这是一个旧答案。【参考方案4】:

就我而言,我使用的是 laravel 5.4

return (new static)->getTable();

【讨论】:

也适用于 laravel 5.2 适用于 Laravel 5.5。谢谢。【参考方案5】:

由于 table 是 Model 类 (Laravel >= 5) 中的受保护属性,因此您需要一个 Model 实例。

这是一个案例:

        DB::table( (new YourModelClassname)->getTable() )
            ->update(['field' => false]);

【讨论】:

【参考方案6】:

您可以通过以下代码获取模型表的名称:

如果我们有一个 Model 作为 ModelName:

ModelName::query()->getQuery()->from

此方法在模型中由protected $table = 'custom_table_name' 定义的自定义表名的情况下也可以正常工作。

【讨论】:

【参考方案7】:

基于Lucky Soni answer,如果您想直接从VontrollerView 调用它,还有另一个简单的技巧。

在 Laravel 6 中测试,如果你是 “单行程序员” 讨厌额外的行实例声明,我会继续使用它。模型文件中也不需要额外的行。

$string_table_name = with(new \App\Model\TableModelName)->getTable();

或者更好,你也可以直接调用它

$string_table_name = (new \App\Model\TableModelName)->getTable();

即使您在模型类中重命名$table 变量,它也会返回表格名称的纯字符串。

编辑:

减去代表 ??也许你应该先在你的 controller 中尝试这个,而不是在模型类中创建新函数只是为了获取表名并且在调用时不需要声明对象。

with() 本身是 Laravel 辅助函数,它返回类的对象。在扩展模型的内部类中,已经有函数getTable()。因此,您不必在模型类中添加另一个新的冗余函数。 好像是最新版本,不用with()函数就可以直接调用(new Class)

这个答案和Lucky的答案的区别,我没有在模型类中创建任何新函数来获取表名,即使你可以在控制器和视图中调用函数而不声明模型类的对象。这是为了美化代码。

虽然 Lucky 的回答在 Model 类中创建了新函数,但您需要从对象中调用该函数。

【讨论】:

这似乎更像是“幸运索尼的回答”,而不是“基于幸运索尼的回答”。正如他的回答所指出的,with() 在这里被用来做什么? 哇... -1 ?幸运的索尼将代码放入模型中。但是我的方式可以只放在控制器中,而不需要在模型类中添加代码。这就是更高效线路的区别。 with() 是返回对象的 Laravel 函数。 getTable 是 Model 类中的预定义函数。 with() 允许在不可能的情况下进行链接,但如果方法已经返回自己的类实例,则不需要。我会说 -1 是因为这更像是评论而不是答案?我也发生过同样的事情,令人沮丧,但这就是 *** 的工作原理。【参考方案8】:

通过以下方式从 Laravel 模型中获取表名的简单方法:

$tableName = app(\App\User::class)->getTable();

别忘了替换:

\应用\用户

带有模型路径。

【讨论】:

【参考方案9】:

另一种解决方案是像这样使用resolve 助手:

resolve('\\App\\Models\\User')->getTable()

【讨论】:

【参考方案10】:

它将从模型中返回表名。在 laravel 8 上完美运行

app(Modelname::class)->getTable()

你必须用你的模型类替换 Modelname

【讨论】:

【参考方案11】:

根据裁缝 Otwell 的 answer,您可以使用如下内容:

with(new Model)->getTable();

注意:在 5.x、6.x、7.x、8.x 版本上测试,效果很好。

【讨论】:

【参考方案12】:

这是另一种方法,您可以静态获取模型的表名。

    定义特征:app/Traits/CanGetTableNameStatically.php
<?php namespace App\Traits;

trait CanGetTableNameStatically

    public static function tableName()
    
        return (new static)->getTable();
    

    使用use 语句扩展您所需的ModelBaseModel

app/Models/BaseModel.php

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Traits\CanGetTableNameStatically;

class BaseModel extends Model

    use CanGetTableNameStatically;

    // ...

在您的模型上,如果您在 Laravel 的保留属性上设置自定义表名:protected $table,那么它仍然可以工作并返回正确的表名。

app/Models/Customer.php

<?php namespace App\Models\Master;

use App\Models\BaseModel;

class Customer extends BaseModel

    protected $table = 'my_customers';

    // ...

用法:在任何地方拨打YourModel::tableName()即可。

在视图中:

 \App\Models\Customer::tableName() 

在进行连接时:

DB::table( Product::tableName() . ' AS p' )
->leftJoin( ProductCategory::tableName() . ' AS pc', 'pc.id', '=', 'p.category_id')
// ... etc

注意: 我在需要但完全公开的地方使用了这种方法,我找到了另一个答案 here 具有完全相同的方法,所以我复制粘贴在这里作为参考当然感谢@topher

【讨论】:

【参考方案13】:

如果您使用的是表名前缀,那么到目前为止,没有一个答案会为您提供带有前缀的表名。这时候想数据库表的真名好像需要自己把前缀和表名串联起来。

以下是获取包含表前缀的表名的方法:

echo \App\MyModel::query()->getQuery()->getGrammar()->getTablePrefix() . app(\App\MyModel::class)->getTable();

【讨论】:

【参考方案14】:

我只是想为来自搜索引擎的人添加以下内容:

如果您根本不想实例化模型(更快?):

$model = 'App\User';
$modelTable = str_replace('\\', '', Str::snake(Str::plural(class_basename($model))));
dd($modelTable); // will return "users"

这可能看起来很难看,但这正是 getTable() 方法在后台解决它的方式,所以...

您需要在文件顶部添加use Illuminate\Support\Str;

附录:暗示您遵循框架的标准(即:Post 模型具有 posts 表,用户模型具有 users 表等)

【讨论】:

只要您不覆盖表变量以在模型中使用不同的表,此方法就可以工作。 我会说这绝对不是正确的方法。假设太多基于模型的类名很可能会遇到问题。正如路德维希所指出的,如果您覆盖表变量,将无法正常工作。 你们似乎都忽略了附录。【参考方案15】:

Laravel 4 中使用 静态 方法

$table_name = Model::getTable();

或 Eloquent 模型中的“self

$table_name = self::getTable();

【讨论】:

看来 getTable() 函数不是静态的——你需要一个模型实例来获取表格:$model = new Model(); $table_name = $model-&gt;getTable();(我使用的是 Laravel 4.1.30)。 截至 2017 年 1 月 16 日,我实际上能够通过 self::getTable() 在模型中获取表的名称。 Laravel 5.5.

以上是关于如何在 Laravel 中返​​回数据库表名的主要内容,如果未能解决你的问题,请参考以下文章

如何在模型 Laravel 中返​​回多个自定义值

使用邮递员的 PUT/PATCH 请求在 Laravel 中返​​回状态码 0

通过 Ajax 调用将数组发送到控制器,然后控制器在 Laravel 中返​​回具有该数组的另一个视图

在 QAbstractItemModel 中返​​回正数行和零列是不是可以?

在 Excel 中返​​回具有不同行长的最大值

在 Laravel 中返​​回多对多关系的统一 JSON