Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用计算值的拉威尔范围_Php_Laravel_Laravel 5_Eloquent_Laravel 5.4 - Fatal编程技术网

Php 使用计算值的拉威尔范围

Php 使用计算值的拉威尔范围,php,laravel,laravel-5,eloquent,laravel-5.4,Php,Laravel,Laravel 5,Eloquent,Laravel 5.4,我在Laravel 5.4中有以下问题: 有一个用户表和一个成员表,其中一个用户可以有多个成员资格,并且成员资格属于一个用户。会员资格每年持续一次,但会员推荐的每个朋友在我的网站上注册,都会获得额外的免费日,因此免费日数不断变化;这反过来又改变了会员的截止日期。 所以问题是:如果过期日期是一个变量,如何确定给定用户的活动成员身份的范围? 我需要这样做: public function scopeActive($query, \Carbon\Carbon $dateToCheck = Null)

我在Laravel 5.4中有以下问题: 有一个用户表和一个成员表,其中一个用户可以有多个成员资格,并且成员资格属于一个用户。会员资格每年持续一次,但会员推荐的每个朋友在我的网站上注册,都会获得额外的免费日,因此免费日数不断变化;这反过来又改变了会员的截止日期。 所以问题是:如果过期日期是一个变量,如何确定给定用户的活动成员身份的范围? 我需要这样做:

public function scopeActive($query, \Carbon\Carbon $dateToCheck = Null) 
{
   $query->where('some_date_field',  '>=' ($expirationDate ?? now())->toDateTimeString());
}
public function scopeActive($query, $user, $dateToCheck = Null) {
    // If no date is passed, use today()
    $dateToCheck = is_null($dateToCheck) ? Carbon::today() : Carbon::parse($dateToCheck);

    //Substract the friendsDaysRemaining from the dateToCheck
    $AdjustedEndDate = $DateToCheck->copy()->subDays($user->friendsDaysRemaining);

    //Build the query 
    $query  ->where('paid', 1) //its been paid for
            ->where('startDay', '<=', $DateToCheck) //It has started
            ->where('renewalDueDate', '>=', $AdjustedEndDate); //It has not expired

    return $query;
}
首先是Membership.php中的到期日期:

这将计算每个成员的总天数: 请注意,friendsDays是在user.php中按用户计算的

public function getTotalDaysAttribute() {
        $days = $this->paidDays + $this->user->friendsDaysRemaining;
        return $days;
    }
这将计算每个成员的到期日期:

public function getExpirationDateAttribute() {
    $date = $this->startDay->addDays($this->TotalDays);
    return $date;
}
到目前为止还不错。。。现在,这就是我被卡住的地方(伪代码):

如何正确编码以获得:

dump($user->membership()->active()->get());
提前感谢。

您有两个问题:

  • 您正在尝试在范围中使用模型值。作用域发生在设置模型值之前。这是因为为了获得要设置的模型中的值,必须首先执行获取数据的查询

  • 不幸的是,由于您的数据库设计,您将无法创建一个范围来获得您想要的答案。这是因为您使用不同表中的值来计算
    TotalDays

  • 我建议您更改数据库中的
    expirationDate
    值,并在邀请朋友时调用它

    比如:

    function addDaysToExpiration(User $user) {
        $user->expirationDate = date('Y-m-d h:m:s', strtotime('2008-10-05' . '+1 day'));
        $user->save();
    }
    

    您可以将变量传递给作用域,例如,您可以这样定义作用域:

    public function scopeActive($query, \Carbon\Carbon $dateToCheck = Null) 
    {
       $query->where('some_date_field',  '>=' ($expirationDate ?? now())->toDateTimeString());
    }
    
    public function scopeActive($query, $user, $dateToCheck = Null) {
        // If no date is passed, use today()
        $dateToCheck = is_null($dateToCheck) ? Carbon::today() : Carbon::parse($dateToCheck);
    
        //Substract the friendsDaysRemaining from the dateToCheck
        $AdjustedEndDate = $DateToCheck->copy()->subDays($user->friendsDaysRemaining);
    
        //Build the query 
        $query  ->where('paid', 1) //its been paid for
                ->where('startDay', '<=', $DateToCheck) //It has started
                ->where('renewalDueDate', '>=', $AdjustedEndDate); //It has not expired
    
        return $query;
    }
    
    然后你可以做:

    $dateToCheck = now()->addDays(30);
    
    dump($user->membership()->active($dateToCheck)->get());
    

    如果在您的案例中使用更方便,您也可以只花几天的时间来确定范围而不是碳实例。

    使用您为自己定义的API:

    $user->membership()->active()->get();
    
    public function scopeActive($query) {
       var_dump($this->id); // null
       var_dump($this->user); // null, this part will try to do the query: select * from users where id = null
    }
    
    您的方法
    scopeActive
    将无法查看计算过期日期所需的相关
    User
    friendsDaysRemaining
    变量。您可以自己尝试:

    $user->membership()->active()->get();
    
    public function scopeActive($query) {
       var_dump($this->id); // null
       var_dump($this->user); // null, this part will try to do the query: select * from users where id = null
    }
    
    在您的位置上,我可能会在
    成员资格
    表中保留一个
    过期日期
    列,并在需要时进行更新。这将允许您执行smth,如:

    public function scopeActive($query) {
        return $query->where('expiration_date', '>', Carbon::now());
    }
    

    谢谢你们的及时回答。根据你的想法,我用另一种方法解决了这个问题。因为我不能在查询中使用计算字段,所以我返回到DB中确实存在的字段,这是renewalDueDate,从付款日期算起一年;两者都是已知的和固定的日期。然后,在查询中,我将$user和$dateToCheck作为参数传递,减去剩余的好友天数并与该值进行比较,如下所示:

    public function scopeActive($query, \Carbon\Carbon $dateToCheck = Null) 
    {
       $query->where('some_date_field',  '>=' ($expirationDate ?? now())->toDateTimeString());
    }
    
    public function scopeActive($query, $user, $dateToCheck = Null) {
        // If no date is passed, use today()
        $dateToCheck = is_null($dateToCheck) ? Carbon::today() : Carbon::parse($dateToCheck);
    
        //Substract the friendsDaysRemaining from the dateToCheck
        $AdjustedEndDate = $DateToCheck->copy()->subDays($user->friendsDaysRemaining);
    
        //Build the query 
        $query  ->where('paid', 1) //its been paid for
                ->where('startDay', '<=', $DateToCheck) //It has started
                ->where('renewalDueDate', '>=', $AdjustedEndDate); //It has not expired
    
        return $query;
    }
    
    结果:

    收藏{#299▼ #项目:阵列:2[▼ 0 => 83 1=>6]}

    当然,您也可以传递$friendsDaysRemaining而不是$user,但这也远远不够优雅


    再次感谢。

    对不起,马辛;我原来的帖子有个错误。此行:$query->where($dateToCheck>=$expirationDate);应该是:$query->where($dateToCheck>=$this->expirationDate);。我已经改正了。我的问题是,表中没有可比较的“some_date_field”,因为日期字段是使用上面编写的scopeActive()函数计算的。每个型号的
    $this->expirationDate
    是否相同,并手动设置为所有型号的“2018-05-23 08:12:23”?这是很久以前的事了,但是你能接受你自己的答案吗?这样就可以让人们对未回答的问题视而不见了。干杯