2

Illuminate\Contracts\Container\BindingResolutionException Unable to resolve dependency [Parameter #0 [ $customerId ]] in class App\Jobs\BudgetFetch

namespace App\Http\Controllers;
use App\Jobs\BudgetFetch;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V3\GoogleAdsClientBuilder;
use Illuminate\Support\Facades\DB;

class APIController extends Controller
{
    public function index() {
        $clients = DB::table('account_names')->pluck('code');

        foreach($clients as $customerId) {
            budgetFetch::dispatch($customerId);
        }
    }
}

上面是一个简单的控制器,我把它放在一起来触发另一个工作:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V3\GoogleAdsClientBuilder;

class BudgetFetch implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {

    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle($customerId)
    {
        $clientId = "xxxxxxxxxxxx";
        $clientSecret = "xxxxxxxxxxx";
        $refreshToken = "xxxxxxxxxxxxxxxxxx";
        $developerToken = "xxxxxxxxxxxxxxxxxx";
        $loginCustomerId = "xxxxxxxxxxx";

        $oAuth2Credential = (new OAuth2TokenBuilder())
            ->withClientId($clientId)
            ->withClientSecret($clientSecret)
            ->withRefreshToken($refreshToken)
            ->build()
        ;

        $googleAdsClient = (new GoogleAdsClientBuilder())
            ->withDeveloperToken($developerToken)
            ->withLoginCustomerId($loginCustomerId)
            ->withOAuth2Credential($oAuth2Credential)
            ->build()
        ;

        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        $query = 'SELECT campaign.id, campaign.name, metrics.cost_micros, campaign_budget.amount_micros FROM campaign ORDER BY campaign.id';
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream =
            $googleAdsServiceClient->searchStream($customerId, $query);

        foreach ($stream->iterateAllElements() as $googleAdsRow) {
            /** @var GoogleAdsRow $googleAdsRow */
            $metrics = $googleAdsRow->getMetrics();
            $id = $googleAdsRow->getCampaign()->getId()->getValue();
            $name = $googleAdsRow->getCampaign()->getName()->getValue();
            $spend = $googleAdsRow->getCampaignBudget()->getAmountMicros()->getValue();
            $budget = $metrics->getCostMicrosUnwrapped();

            if($spend >= $budget){
                DB::table('budget_alerts')->insert(
                    ['campaign' => $id, 'hitBudget' => 1]
                );
            };
        }
    }
}

问题顶部的错误是我从中得到的,如果我将变量放在 __construct 中,同样的事情会发生。我已经运行了一个 php artisan clear-compiled,我在另一个类似的问题中发现了它,它似乎没有解决任何问题。

4

1 回答 1

4

$customerId应该在构造函数中:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V3\GoogleAdsClientBuilder;

class BudgetFetch implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $customerId;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($customerId)
    {
        $this->customerId = $customerId;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $customerId = $this->customerId;
        $clientId = "xxxxxxxxxxxx";
        $clientSecret = "xxxxxxxxxxx";
        $refreshToken = "xxxxxxxxxxxxxxxxxx";
        $developerToken = "xxxxxxxxxxxxxxxxxx";
        $loginCustomerId = "xxxxxxxxxxx";

        $oAuth2Credential = (new OAuth2TokenBuilder())
            ->withClientId($clientId)
            ->withClientSecret($clientSecret)
            ->withRefreshToken($refreshToken)
            ->build()
        ;

        $googleAdsClient = (new GoogleAdsClientBuilder())
            ->withDeveloperToken($developerToken)
            ->withLoginCustomerId($loginCustomerId)
            ->withOAuth2Credential($oAuth2Credential)
            ->build()
        ;

        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        $query = 'SELECT campaign.id, campaign.name, metrics.cost_micros, campaign_budget.amount_micros FROM campaign ORDER BY campaign.id';
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream =
            $googleAdsServiceClient->searchStream($customerId, $query);

        foreach ($stream->iterateAllElements() as $googleAdsRow) {
            /** @var GoogleAdsRow $googleAdsRow */
            $metrics = $googleAdsRow->getMetrics();
            $id = $googleAdsRow->getCampaign()->getId()->getValue();
            $name = $googleAdsRow->getCampaign()->getName()->getValue();
            $spend = $googleAdsRow->getCampaignBudget()->getAmountMicros()->getValue();
            $budget = $metrics->getCostMicrosUnwrapped();

            if($spend >= $budget){
                DB::table('budget_alerts')->insert(
                    ['campaign' => $id, 'hitBudget' => 1]
                );
            };
        }
    }
}

原因是作业没有立即调用。它首先被构建,然后放入队列中,它将(在某些时候)被删除和“处理”。因此handle无法直接访问您传入的任何参数dispatch。文档确实表明句柄可以接受参数,但这些只是可以使用依赖注入注入的参数。

于 2020-06-30T10:08:19.397 回答