【问题标题】:Laravel doesn't connect to database from web, but it does work from the CLILaravel 不能从 Web 连接到数据库,但它可以通过 CLI 工作
【发布时间】:2022-01-10 14:01:45
【问题描述】:

我有一个未经修改的新 Laravel 项目,我正在尝试启动并运行我的第一个模型。我使用./vendor/bin/sail up 以默认设置运行网络服务器和 MySQL。我可以从 DBeaver 访问数据库,迁移运行良好,我什至可以使用 tinker 从终端访问我的数据库数据:

$ php artisan tinker
Psy Shell v0.10.12 (PHP 7.4.3 — cli) by Justin Hileman
>>> use App\Models\User;
>>> User::all()
=> Illuminate\Database\Eloquent\Collection {#4290
     all: [
       App\Models\User {#4292
         id: 1,
         name: "Johannes Molenaar",
         email: "gunes.dani@example.net",
         email_verified_at: "2022-01-10 13:51:35",
         #password: "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi",
         #remember_token: "bhuBvEAZ9c",
         created_at: "2022-01-10 13:51:35",
         updated_at: "2022-01-10 13:51:35",
       },
     ],
   }

现在,当我尝试在我的 routes/web.php 文件(或与此相关的控制器)中执行任何此操作时,它不起作用:

Route::get('/', function() {
    App\Models\User::all();
});

我得到的错误是:

照亮\数据库\查询异常

SQLSTATE[HY000] [2002] 连接被拒绝(SQL: select * from `users`)

无论我使用什么模型或 ORM 函数,它们都会给我同样的错误。我检查了我的.env 配置,但我认为该配置中的错误也意味着工匠将无法访问数据库。

.env 文件:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tgi_laravel
DB_USERNAME=sail
DB_PASSWORD=password

config/database.php:

'connections' => [
    'mysql' => [
        'driver' => 'mysql',
        'url' => env('DATABASE_URL'),
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'prefix_indexes' => true,
        'strict' => true,
        'engine' => null,
        'options' => extension_loaded('pdo_mysql') ? array_filter([
            PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        ]) : [],
    ],
    // sqlite, pgsql and sqlsrv here
],

有没有人知道这里会出什么问题?如果有任何其他信息需要评估此问题,请告诉我。


编辑:

我在 web 项目中使用 php 8.1.1,但 Tinker 似乎在 7.4.3 上运行。将服务器的 php 版本更改为 7.4.27 并不能解决此问题(将 docker 映像更改为 sail-7.4/app)。

清除配置缓存不起作用 (php artisan config:clear)。

DB_HOST 更改为localhost(而不是127.0.0.1)会将错误更改为“没有这样的文件或目录”。

【问题讨论】:

  • "我在 web 项目中使用 php 8.1.1,但 Tinker 似乎在 7.4.3 上运行" 您如何确认这一点?为什么在您的服务器上运行 2 个版本的 PHP?默认情况下,MySQL 已禁用网络,您应该通过套接字使用 localhost 而不是 127.0.0.1。您是否确认数据库正在运行,并且您是否已将 PHP 配置为使用适当的套接字文件?
  • @miken32 Tinker 在启动时提到它的版本(见我的帖子),我使用phpversion() 吐出网络服务器正在使用的版本。不同之处在于 Tinker 在我的本地 php 版本上运行,而网络服务器在 Docker 容器中运行。正如我稍后添加的那样,无论如何它似乎没有任何区别。
  • 很明显,如果你的 Laravel 应用在一个 docket 容器中,你也必须从容器中运行 artisan 命令!
  • 这仍然不能解决我的问题。
  • @miken32 你确实给了我一个很好的提示:从 docker 容器中运行 php artisan tinker 不起作用。这让我相信 MySQL 可以从容器外部访问,但不能从容器内部访问。这让我找到了最终的解决方案,谢谢!

标签: php mysql laravel


【解决方案1】:

DB_HOST 更改为mysql 解决了这个问题。

问题是我无法从容器内访问 MySQL 服务器,但我能够从容器外部访问它。这就解释了为什么 DBeaver 和 Artisan Tinker(从容器外的命令行运行)能够连接,但我的 Laravel 服务器却不能。从 docker 容器中运行 php artisan tinker(使用 docker-compose exec laravel.test bash)也不起作用。

我克隆了一个新的 Laravel 项目,发现 .env 配置有所不同:

DB_CONNECTION=mysql
DB_HOST=mysql             # Instead of 127.0.0.1
DB_PORT=3306
DB_DATABASE=example_app   # And this is a default that didn't
                          # contribute to the problem obviously
DB_USERNAME=sail
DB_PASSWORD=password

【讨论】:

    【解决方案2】:

    所以也许在配置文件中使用 localhost 而不是 127.0.0.1

    【讨论】:

    • 欢迎来到 Stack Overflow Julien!请务必阅读这篇文章:stackoverflow.com/help/how-to-answer。您的回答没有解释它是如何解决问题的,不幸的是它也根本没有解决它。用户模型已正确加载,如果在 Laravel 项目中,错误出在数据库包或配置中。
    • 也许我的最后一句话是正确的
    • 请在您的答案中添加一些解释,以便其他人可以从中学习。调试标志如何解决数据库问题?
    • 这只是一个建议,我读得太快了,但也许改变 SQL 的连接端口可能是解决方案。不知道。正如我的个人资料中所说,我是一个初学者,只是想提供帮助
    • 很公平,但 Nico 是对的:编辑您的答案以删除冗余信息并解释为什么更改端口可能有效。我在另一个端口上尝试过,遗憾的是它对我不起作用。
    【解决方案3】:

    'localhost' 和 '127.0.0.1' 之间出现不同错误的事实表明 127.0.0.1 是正确的连接字符串;它找不到本地主机,但 127.0.0.1 不依赖任何查找。

    我的猜测可能是用户“sail”在数据库中没有适当的权限来访问该表。我会进入 MySQL / Maria,并在 forge 上授予所有权限。* TO 'sail'@'localhost' 然后再试一次。

    此外,我对sail 不是很熟悉,但快速浏览一下表明除了“sail up”之外,您可能还需要指定数据库,即DB_DATABASE=forge。

    查看您的配置文件,用户的密码为空。我假设您只是对其进行了编辑,但请确保您的开发实例上的配置文件是正确的!

    【讨论】:

    • 我已使用这种方法为sai 用户授予所有权限:gist.github.com/jjsquady/e12ce89c9029d520ce08f60a9ff8f304(将用户从 laravel 更改为sai)。不幸的是,它并没有解决问题。
    • 我确实在我的配置中指定了DB_DATABASE,并且密码不是空的(而是password),所以这也不应该是问题。
    • localhost 不“依赖于任何查找”,它使用通常更快、更安全的非网络套接字连接; mysql 默认情况下已禁用网络,因此 OP 可能会弄乱配置。 “连接被拒绝”错误并不表示身份验证或授权问题,而是网络问题。
    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2020-07-07
    • 2016-04-05
    • 1970-01-01
    • 2016-03-30
    • 2013-03-19
    • 2021-06-07
    • 2019-04-12
    • 2012-10-24
    相关资源
    最近更新 更多