在拉勒维尔创造一个链状的方法

我一直在尝试用拉拉威尔的雄辩创造我自己的链接式的方法 , 但我遗漏了一些东西 , 不确定是什么。 这听起来可能有点疯狂 , 但看看下面我的功能 , 以便更好地了解我想说什么。

class Post extends Eloquent{
    public static function custom_wh($data){
        return static::where_in('categories_id', $data, 'AND');
    }
}

//this works fine
$posts = Post::custom_wh(array(1, 2, 3))->get();

//but this says custom_wh is not defined in the query class
$posts = Post::where_in('tags', array(2, 3, 4), 'AND')->custom_wh(array(1, 2, 3))->get();

如果我正确地理解了, 那么我的方法就没有资格在其他方法之后串链了? 所以我想我的问题是如何在我的模型中创建一个链接法 ?

P. S. 我查看了 laravel 的查询生成器类 , 在该类中我看到了链接式方法返回该对象的实例 , 但除了我在上面代码中所做的方法之外 , 我无法找到返回该对象的方法。 任何建议或建议都是非常感谢的。 先谢谢你。


EN From: creating a chainable method in laravel

8 Comments

  1. 我不确定我是否准确 , 但这是我很快想到的...

    如果 _ in () 不返回一个注释模型 , 则返回类型查询的对象。

    对于您如何简单地编写自定义函数 , 我将避免使用该函数

    $posts = Post::where_in('tags', array(2, 3, 4))->where_in('categories_ids', array(1,2,3))->get();
    

    从我头顶

    你可以试试

    class Post extends Eloquent {
        public static function custom_wh($data=array()) {
            return static::where_in('categories_id', $data);
            // return type of query not eloquent
        }
    }
    
    $posts = Post::custom_wh(array(1,2,3))->where_in('tags', array(2, 3, 4))->get();
    

    除非你想更改查询类

    1. 嗯 , 我就是这么做的 , 但问题是定制的 wh 函数不能链接 , 所以假设我有一个大问题需要做几个连接 , 在那里 , 子句我想把它们用独立的函数包起来 , 在需要的时候用链子锁起来 , 然后问题就出现了。 我试图将它们放入函数的另一个原因是 ORM 不应该是我的模型 , 对吗 ? 我也想保留我的代码"dry"。
  2. 你试过用"自我"代替"静态"吗? 据我所知 , 如果您使用 self 和属性 / 方法 , 并且您所指的子类和方法是不重写主类属性 / 方法的 , 那么在这种情况下 , 它将返回查询类的"where_in"方法。 然后 , 您就可以将自定义方法链起来。

  3. 好吧... 这可能会让你的大脑有点扭曲 , 但要坚持住。 定义的实际方法是 _ where 。 那么 , 这两种邮政方式是什么呢 ? 答案是"魔法"。 d

    PHP 有这些被称为"神奇方法"的东西,它们可以使一些非常动态的行为。 在这种情况下 , Laravel 使用 _ callatic () 和 _ call () 处理对未定义方法的调用。 这使相同的方法被静态和非静态调用。

    public static function __callStatic($method, $parameters)
    {
        // Create a new instance of the called class, in this case it is Post
        $model = get_called_class();
    
        // Call the requested method on the newly created object
        return call_user_func_array(array(new $model, $method), $parameters);
    }
    

    所以基本上是邮政 : : ( 在什么地方 ) 只是一种简称 :"邮局=新邮局";"邮局->在哪里"

    从这里请求到 _ 调用 ( ) , 其中有一组下划线的方法名。 如果请求的方法在下划线名称列表中 , 则调用并返回 $the->_method()。

    但这还不是全部。 在返回查询对象的"where_in"中,德鲁是正确的。 您所熟悉的大多数 ORM 链接方法实际上是 ORM 查询对象的一部分。 这是整个过程。

    • 邮政 : 何处 (.)
    • 帖子 : _ 愈伤组织 ("哪里",.)
    • 美元后电话 ("哪里",.)
    • $查询 ->_电话('在哪里',.)
    • 美元查询 ->_地点(.)

    要扩展的类是模型使用的查询。 无法在 _ 调用 ( ) 中定义的下划线方法列表中添加其他方法名称。 您必须将 _ 调用完整地复制到查询定义中 , 以便使您的新方法具有这种行为。

    我已经在我的项目中完成了这一点 , 将 Evolent ( Laravel 模型的别名 ) 指向扩展版本 , 使我的所有模型都能使用扩展查询方法。

    // application/libraries/mylib/query.php
    namespace MyLib;
    
    class Model extends \Laravel\Model {
    
        // Tell \MyLib\Model to use \MyLib\Query instead of Laravels Query
        protected function query()
        { 
            return new \MyLib\Query($this);
        } 
    
    }
    
    // application/libraries/mylib/query.php
    namespace MyLib;
    
    class Query extends \Laravel\Database\Eloquent\Query {
    
        function _my_method() { ... }
    
        function __call() { ... }
    }
    
    // application/config/application.php
    'aliases' => array(
        ...
        'Eloquent' => 'MyLib\\Model',
        ...
    )
    

    http://php.net/manual/en/language.oop5.magic.phphttps://github.com/laravel/laravel/blob/master/laravel/database/eloquent/model.php#L734https://github.com/laravel/laravel/blob/master/laravel/database/eloquent/query.php#L274

    1. 这解释了很多。 老实说 , 我在 php上没有太多关于面向对象的研究 , 我开始使用框架 , 因为我认为我会随着学习面向对象 , 所以是的 , 这很容易掌握 , 但是 Lemme 可以利用你的技术来尝试。 如果有任何问题我会随时通知你。 多谢你帮忙。
  4. 既然你提出了这个问题 , Laravel 就提供了一种新的方法 , 称为"查询范围"。 你可以在这里找到医生。

    您只需用前缀 scope 编写一个函数 , 就可以像其他查询生成器的函数一样将该方法链上 :

    class Post extends Eloquent {
    
        public function scopeWhereCategories($query, $categories)
        {
            return $query->whereIn('categories_id', $categories, 'AND');
        }
    
    }
    
    $posts = Post::whereCategories(array(1, 2, 3))->get();
    $posts = Post::orderBy('date')->whereCategories(array(1, 2, 3))->take(5)->get();
    
    1. 我喜欢这个功能 , 并且已经在使用它了 : 我知道当我发布我的问题时 , 这个功能并不存在 , 但是我选择这个作为像我这样的谷歌人的正确答案。 谢谢。
  5. 实际上 , 你可以轻松地扩展雄辩的建设者 , 然后就跑 :

    $posts = Post::custom_wh(array(1, 2, 3))->get();
    

    在我的回答中你有说明 : Laravel 自定义模型方法

    另外 , 除了你现在正在做什么之外 , 不要使用范围。

More articles:

  • 有没有更好的方法可以将一个象形文字预先添加到 Laravel 的 BootForm 插件按钮中 ?
  • 在更新到 Laravel 5.3 后播种时 , 调用未定义的方法 Illuminate\ Database\ Query / Builder::: 列表
  • 通过它获取另一个表的字符串
  • 拉勒维尔 : 如何显示可用时间段列表
  • 如何分割一个用户模型查询
  • 拉勒维尔的 ID 命名惯例
  • 拉勒维尔访问归属者模型有很多关系
  • 如何每隔一个星期三在拉勒维尔举办一个活动
  • 不存在日期的方法
  • 如何将变量传递给拉勒维尔的工厂?
  • 拉勒维尔将变量从一个种子文件传递到另一个种子文件?
  • 拉勒维尔 - 多重关系
  • 调用未定义的方法 Illumenate\ Database\ Query / Builder : FireCustomModelEvent ()
  • 创造一个"追随者"? 两个用户类型之间的方法 , rails
  • 拉勒维尔 , 用一个旧的代替整个会议
  • 相同的前两次关键时间指一个模型
  • Laravel 从另一个表获取数据
  • 使用多个表组合成一个的 Laravel Evient 模型 ( 无单独模型 )
  • Laravel 5 另一个控制器的访问控制器方法
  • 查询只返回一个用户
  • 试图获取拉勒维尔关系中的非对象属性
  • 方法. 调用是否在 java 中创建了一个新的线程 ?
  • 我如何在 C# 中写一个方法, 一旦条件是真实的就返回?
  • 返回一个没有信息或方法的对象
  • 当服务器准备好时 , 如何在 Spring 中执行一个方法 ?
  • 惯用的记录程序的方法 , 包括一个主程序。
  • Django: 有任何方法执行连续模型. 保存 () 操作作为一个 DB 请求?
  • 用熊猫从一个数据文件复制到另一个数据文件的最快方法 ?
  • Laravel 5.1 大容量插入语句的处理
  • Laravel 查询不起作用