简体   繁体   English

与 illuminate/database 和 illuminate/queue 的查询参数绑定问题

[英]Query parameter binding issue with illuminate/database and illuminate/queue

I'm using Illuminate\Queue outside of a Laravel app inside an add-on for a CMS.我在 CMS 的附加组件内的 Laravel 应用程序之外使用 Illuminate\Queue。 So the only instances of Laravel or Illuminate are these packages that I've required:所以 Laravel 或 Illuminate 的唯一实例是我需要的这些包:

"illuminate/queue": "^8.83",
"illuminate/bus": "^8.83",
"illuminate/contracts": "^8.83"

I'm first trying to use the Database for the queue as the default driver since the CMS is database driven, then provide options to SQS etc. I've setup everything so the migrations create my queue tables and everything seems to be wired together when I make the following call to push something to the queue.我首先尝试使用队列的数据库作为默认驱动程序,因为 CMS 是数据库驱动的,然后为 SQS 等提供选项。我已经设置了所有内容,以便迁移创建我的队列表,并且当我进行以下调用以将某些内容推送到队列中。

/** @var \Illuminate\Queue\QueueManager $queue */
$queue->push('test', ['foo' => 'bar']);

Then it ends in the following error.然后它以以下错误结束。 The parameter bindings are not working or something.参数绑定不起作用或其他原因。 It's leaving the?它离开了? in the values list.在值列表中。

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"exp_dgq_jobs" ("queue", "attempts", "reserved_at", "available_at", "created_at"' at line 1 (SQL: insert into "exp_dgq_jobs" ("queue", "attempts", "reserved_at", "available_at", "created_at", "payload") values (default, 0, ?, 1674567590, 1674567590, {"uuid":"6bf7a17e-dda3-4fed-903a-8714e5a2d146","displayName":"test","job":"test","maxTries":null,"maxExceptions":null,"failOnTimeout":false,"backoff":null,"timeout":null,"data":{"foo":"bar"}}))

I've step debugged the whole request and it feels like a bug, but then again this is really the first time I've used Laravel or one of it's packages, so maybe I'm missing something?我已经逐步调试了整个请求,感觉就像一个错误,但话又说回来,这真的是我第一次使用 Laravel 或其中一个包,所以也许我遗漏了什么? This function explicitly sets reserved_at to null, and the Connection->prepareBindings() method doesn't do anything with the?, it just leaves it as that value, so the query fails.这个 function 显式地将 reserved_at 设置为 null,并且 Connection->prepareBindings() 方法没有对 ? 做任何事情,它只是将它保留为该值,因此查询失败。

protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0)
    {
        return ['queue' => $queue, 'attempts' => $attempts, 'reserved_at' => null, 'available_at' => $availableAt, 'created_at' => $this->currentTime(), 'payload' => $payload];
    }

What am I missing?我错过了什么? Everything just looks right to me an I'm kind of at a loss.一切对我来说都是正确的,我有点不知所措。 I'm making this with PHP 7.4 in mind (for the time being).我正在考虑 PHP 7.4(暂时)。 Maybe I'll try 8.1 to see if that changes anything with the Illuminate packages.也许我会尝试 8.1 看看它是否改变了 Illuminate 包。 Using MySQL 8 too.也使用 MySQL 8。

Update: potentially relevant screenshot just before the error.更新:错误之前可能相关的屏幕截图。

Update 2: I tried PHP 8.1 and latest Laravel 9 packages, didn't make a difference.更新 2:我尝试了 PHP 8.1 和最新的 Laravel 9 个软件包,没有任何区别。

调试

For more clarity on how I"m creating my QueueManager:为了更清楚地了解我是如何创建我的 QueueManager 的:

<?php $queue = new Queue;
        $queue->addConnection([
            'driver' => 'database',
            'table' => ee('db')->dbprefix . 'dgq_jobs',
            'queue' => 'default',
            'retry_after' => 90,
            'after_commit' => false,
        ]);

        $databaseConfig = $provider->make('DatabaseConfig');

        $queue->addConnector('database', function () use ($databaseConfig) {
            $pdo = new PDO(
                sprintf('mysql:host=%s; dbname=%s', $databaseConfig['host'], $databaseConfig['database']),
                $databaseConfig['username'],
                $databaseConfig['password']
            );
            $connection = new Connection($pdo);
            $connectionResolver = new ConnectionResolver(['default' => $connection]);
            $connectionResolver->setDefaultConnection('default');

            return new DatabaseConnector($connectionResolver);
        });

        return $queue->getQueueManager();

I was able to reproduce the error you were seeing.我能够重现您看到的错误。 I haven't looked too deeply but I think it may be due to the PDO object not setting up the connection exactly as the Illuminate Queue library expects.我没有看得太深,但我认为这可能是由于 PDO object 没有完全按照 Illuminate Queue 库的预期设置连接。

This modification to using the Illuminate\Database library to create the connection solved the issue in my test environment:使用 Illuminate\Database 库创建连接的这种修改解决了我的测试环境中的问题:

$database = new \Illuminate\Database\Capsule\Manager;
$queue = new \Illuminate\Queue\Capsule\Manager;

$database->addConnection([
    'driver' => 'mysql',
    'host' => 'localhost',
    'database' => 'db_name',
    'username' => 'username',
    'password' => '',
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix' => '',
]);

$queue->addConnector('database', function () use ($database) {
    $connection = $database->getConnection();
    $connectionResolver = new \Illuminate\Database\ConnectionResolver(['default' => $connection]);
    $connectionResolver->setDefaultConnection('default');

    return new \Illuminate\Queue\Connectors\DatabaseConnector($connectionResolver);
});

$queue->addConnection([
    'driver' => 'database',
    'table' => 'jobs_table',
    'queue' => 'default',
    'retry_after' => 90,
    'after_commit' => false,
]);

$queue->getQueueManager()->push('SendEmail', ['message' => 'test']);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM