You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eloquent Builder实例不存在[method]属性问题求助

技术问题:Eloquent Builder实例不存在[method]属性错误

错误详情

Property [method] does not exist on the Eloquent builder instance.

Builder->__get('method')
in core/app/Http/Controllers/Provider/PaymentController.php (line 210)

问题场景

将Gateway/PaymentController.php与Models/GatewayCurrency.php的代码复制到Provider/PaymentController.php和Models/ProviderCurrency.php后,Gateway站点运行正常,但Provider站点触发上述错误,错误位于core/app/Http/Controllers/Provider/PaymentController.php第210行。

相关代码

PaymentController.php

<?php

namespace App\Http\Controllers\Provider;

use App\Http\Controllers\Controller;
use App\Lib\FormProcessor;
use App\Models\AdminNotification;
use App\Models\Agent;
use App\Models\Currency;
use App\Models\Transfer;
use App\Models\ProviderCurrency;
use App\Models\Transaction;
use App\Models\User;
use App\Models\Wallet;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class PaymentController extends Controller{

    public function transfer(){ 
        $pageTitle = 'Payment Methods';
        return view($this->activeTemplate . providerView('transfer'), compact('pageTitle'));
    }

    public function transferInsert(Request $request){

        $request->validate([
            'amount' => 'required|numeric|gt:0',
            'provider_id' => 'required',
            'currency' => 'required',
        ]);

        $user = userGuard()['user'];
        $currency = Currency::enable()->find($request->currency_id);
        
        if(!$currency) {
            $notify[] = ['error', 'Invalid currency'];
            return back()->withNotify($notify);
        }

        $gate = ProviderCurrency::whereHas('method', function ($gate) {
            $gate->where('status', 1);
        })->where('provider_id', $request->provider_id)->where('currency', $request->currency)->first();

        if (!$gate) {
            $notify[] = ['error', 'Invalid provider'];
            return back()->withNotify($notify);
        }
        
        if ($gate->min_amount / $currency->rate > $request->amount || $gate->max_amount / $currency->rate < $request->amount) {
            $notify[] = ['error', 'Please follow transfer limit'];
            return back()->withNotify($notify);
        }

        $charge = $gate->fixed_charge + ($request->amount * $gate->percent_charge / 100);
        $payable = $request->amount + $charge;
        $final_amo = $payable;
        $data = new Transfer();
        $data->user_id = $user->id;

        $data->user_type = userGuard()['type'];
        $data->wallet_id = $request->wallet_id;
        $data->currency_id = $request->currency_id;

        $data->provider_id = $gate->provider_id;
        $data->method_currency = strtoupper($gate->currency);
        $data->amount = $request->amount;
        $data->charge = $charge;
        $data->rate = 1;
        $data->final_amo = $final_amo;
        $data->trx = getTrx();
        $data->save();

        session()->put('Track', $data->trx);
        return to_route(strtolower(userGuard()['type']).'.transfer.confirm');
    } 

    public function appTransferConfirm($hash)
    {  
        try {
            $id = decrypt($hash);
        } catch (\Exception $ex) {
            return "Sorry, invalid URL.";
        }
   
        $data = Transfer::where('id', $id)->where('status', 0)->orderBy('id', 'DESC')->firstOrFail();

        if($data->user_type == 'USER'){
            $user = User::findOrFail($data->user_id);
            Auth::login($user);
            logoutAnother('user');
        }
        elseif($data->user_type == 'AGENT'){
            $user = Agent::findOrFail($data->user_id);
            Auth::guard('agent')->login($user);
            logoutAnother('agent');
        }

        session()->put('Track', $data->trx);
        return to_route(strtolower(userGuard()['type']).'.transfer.confirm');
    }

    public function transferConfirm()
    {   
        $track = session()->get('Track');
        $transfer = Transfer::where('trx', $track)->where('status',0)->orderBy('id', 'DESC')->with('provider')->firstOrFail();

        if ($transfer->provider_id >= 1000) {
            return to_route(strtolower(userGuard()['type']).'.transfer.manual.confirm');
        }


        $dirName = $transfer->provider->alias;
        $new = __NAMESPACE__ . '\\' . $dirName . '\\ProcessController';

        $data = $new::process($transfer);
        $data = json_decode($data);


        if (isset($data->error)) {
            $notify[] = ['error', $data->message];
            return to_route(providerRedirectUrl())->withNotify($notify);
        }
        if (isset($data->redirect)) {
            return redirect($data->redirect_url);
        }

        // for Stripe V3
        if(@$data->session){
            $transfer->btc_wallet = $data->session->id;
            $transfer->save();
        }

        $pageTitle = 'Payment Confirm';
        return view($this->activeTemplate . $data->view, compact('data', 'pageTitle', 'transfer'));
    }

    public static function userDataUpdate($transfer,$isManual = null)
    { 
        if ($transfer->status == 0 || $transfer->status == 2) {
            $transfer->status = 1;
            $transfer->save();
        
            if($transfer->user_type == 'USER'){
                $user = User::find($transfer->user_id);
                $userType = 'USER';
            }
            elseif($transfer->user_type == 'AGENT'){   
                $user = Agent::find($transfer->user_id);
                $userType = 'AGENT';
            }
        
            $userWallet = Wallet::find($transfer->wallet_id);
            $userWallet->balance += $transfer->amount;
            $userWallet->save();
             
            $transaction = new Transaction();
            $transaction->user_id = $user->id;

            $transaction->user_type = $transfer->user_type;
            $transaction->wallet_id = $userWallet->id;
            $transaction->currency_id = $transfer->currency_id;
            $transaction->before_charge = $transfer->amount;

            $transaction->amount = $transfer->amount;
            $transaction->post_balance = $userWallet->balance;
            $transaction->charge = 0;
            $transaction->trx_type = '+';
            $transaction->details = 'Transfer money to ' . $transfer->providerCurrency()->name;
            $transaction->trx = $transfer->trx;
            $transaction->remark = 'transfer_money';
            $transaction->save();

            if (!$isManual) {
                $adminNotification = new AdminNotification();
                $adminNotification->user_type = $userType;
                $adminNotification->user_id = $user->id;
                $adminNotification->title = 'Transfer successful to '.$transfer->providerCurrency()->name;
                $adminNotification->click_url = urlPath('admin.transfer.successful');
                $adminNotification->save();
            }

            notify($user, $isManual ? 'TRANSFER_APPROVE' : 'TRANSFER_COMPLETE', [
                'method_name' => $transfer->providerCurrency()->name,
                'method_currency' => $transfer->method_currency,
                'method_amount' => showAmount($transfer->final_amo, getCurrency($transfer->method_currency)),
                'amount' => showAmount($transfer->amount, $transfer->currency),
                'charge' => showAmount($transfer->charge, $transfer->currency),
                'currency' => $transfer->currency->currency_code,
                'rate' => showAmount($transfer->rate),
                'trx' => $transfer->trx,
                'post_balance' => showAmount($userWallet->balance, $transfer->currency)
            ]);

        }
    }

    public function manualTransferConfirm()
    {
        $track = session()->get('Track');
        $data = Transfer::with('provider')->where('status', 0)->where('trx', $track)->first();

        if (!$data) {
            return to_route(providerRedirectUrl());
        }

        if ($data->provider_id > 999) {
            $pageTitle = 'Transfer Confirm';
            $method = $data->providerCurrency();
            $provider = $method->method;
            return view($this->activeTemplate . providerView('manual_confirmp',true), compact('data', 'pageTitle', 'method', 'provider'));
        }

        abort(404);
    }

    public function manualTransferUpdate(Request $request)
    {
        $track = session()->get('Track');
        $data = Transfer::with('provider')->where('status', 0)->where('trx', $track)->first();
        $userType = null;

        if($data->user_type == 'USER'){
            $user = User::find($data->user_id);
            $userType = 'USER';
        }
        elseif($data->user_type == 'AGENT'){
            $user = Agent::find($data->user_id);
            $userType = 'AGENT';
        }

        if (!$data) {
            return to_route(providerRedirectUrl());
        }

        $providerCurrency = $data->providerCurrency();
        $provider = $providerCurrency->method;
        $formData = $provider->form->form_data;

        $formProcessor = new FormProcessor();
        $validationRule = $formProcessor->valueValidation($formData);
        $request->validate($validationRule);
        $userData = $formProcessor->processFormData($request, $formData);

        $data->detail = $userData;
        $data->status = 2; // pending
        $data->save();

        $adminNotification = new AdminNotification();
        $adminNotification->user_type = $userType;
        $adminNotification->user_id = $data->getUser->id;
        $adminNotification->title = 'Transfer money request from '.$user->username;
        $adminNotification->click_url = urlPath('admin.transfer.details',$data->id);
        $adminNotification->save();
     
        notify($data->getUser, 'TRANSFER_REQUEST', [
            'method_name' => $data->providerCurrency()->name,
            'method_currency' => $data->method_currency,
            'method_amount' => showAmount($data->final_amo), getCurrency($data->method_currency),
            'amount' => showAmount($data->amount, $data->convertedCurrency),
            'charge' => showAmount($data->charge, $data->convertedCurrency),
            'rate' => showAmount(1, $data->convertedCurrency),
            'trx' => $data->trx,
            'currency' => $data->convertedCurrency->currency_code,
        ]);
       
        $notify[] = ['success', 'You transfer money request has been taken'];
        return to_route(strtolower(userGuard()['type']).'.transfer.history')->withNotify($notify);
    }


}

Models/ProviderCurrency.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class ProviderCurrency extends Model
{
    protected $casts = ['status' => 'boolean'];

    // Relation
    public function method()
    {
        return $this->belongsTo(Provider::class, 'provider_id', 'code');
    }

    public function currencyIdentifier()
    {
        return $this->name ?? $this->method->name . ' ' . $this->currency;
    }

    public function scopeBaseCurrency()
    {
        return $this->method->crypto == 1 ? 'USD' : $this->currency;
    }

    public function scopeBaseSymbol()
    {
        return $this->method->crypto == 1 ? '$' : $this->symbol;
    }

}

问题原因

错误根源在ProviderCurrency模型的两个scope方法:scopeBaseCurrency和scopeBaseSymbol。

Laravel中,以scope开头的方法是查询作用域,这类方法的第一个参数是Eloquent Builder实例,而非模型实例。但当前代码直接在scope方法中使用$this->method,此时$this指向Builder对象,该对象不存在method属性,因此触发错误。

另外,这两个方法的用途是获取属性值,并非构建查询逻辑,完全不适合定义为scope方法。

解决方案

将这两个scope方法改为普通实例方法,去掉scope前缀,修改后的ProviderCurrency.php代码如下:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class ProviderCurrency extends Model
{
    protected $casts = ['status' => 'boolean'];

    // Relation
    public function method()
    {
        return $this->belongsTo(Provider::class, 'provider_id', 'code');
    }

    public function currencyIdentifier()
    {
        return $this->name ?? $this->method->name . ' ' . $this->currency;
    }

    public function baseCurrency()
    {
        return $this->method->crypto == 1 ? 'USD' : $this->currency;
    }

    public function baseSymbol()
    {
        return $this->method->crypto == 1 ? '$' : $this->symbol;
    }

}

同时,检查代码中调用这两个方法的地方,将原来的查询链式调用(如ProviderCurrency::baseCurrency())改为实例调用(如$providerCurrency->baseCurrency()),确保在模型实例上调用这些方法。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:52:02