跳转至内容

Laravel Valet

简介

正在寻找在 macOS 或 Windows 上开发 Laravel 应用更简单的方法?请查看 Laravel Herd。Herd 包含了开始 Laravel 开发所需的一切,包括 Valet、PHP 和 Composer。

Laravel Valet 是一个专为 macOS 极简主义者打造的开发环境。Laravel Valet 会将你的 Mac 配置为在系统启动时始终在后台运行 Nginx。然后,利用 DnsMasq,Valet 将所有 *.test 域名的请求代理指向本地机器上安装的站点。

换句话说,Valet 是一个占用约 7 MB 内存、运行速度极快的 Laravel 开发环境。Valet 并不是要完全取代 SailHomestead,但如果你想要灵活的基础设施、追求极致速度,或者在内存有限的机器上工作,它是一个绝佳的选择。

开箱即用,Valet 支持包括但不限于:

当然,你也可以通过自定义驱动来扩展 Valet。

安装

Valet 需要 macOS 和 Homebrew。在安装之前,请确保没有其他程序(如 Apache 或 Nginx)占用了本地机器的 80 端口。

首先,你需要确保 Homebrew 使用 update 命令保持最新状态:

1brew update

接下来,你应该使用 Homebrew 安装 PHP:

1brew install php

安装完 PHP 后,你就可以准备安装 Composer 包管理器了。此外,你应该确保 $HOME/.composer/vendor/bin 目录在系统的 "PATH" 中。Composer 安装完成后,你可以将 Laravel Valet 作为全局 Composer 包进行安装:

1composer global require laravel/valet

最后,执行 Valet 的 install 命令。这将配置并安装 Valet 和 DnsMasq。此外,Valet 所依赖的守护进程也将被配置为在系统启动时自动运行。

1valet install

Valet 安装完成后,尝试在终端中使用如 ping foobar.test 的命令 ping 任何 *.test 域名。如果安装正确,你应该会看到该域名响应 127.0.0.1

Valet 会在每次电脑开机时自动启动所需服务。

PHP 版本

除了修改全局 PHP 版本外,你可以通过 isolate 命令指示 Valet 为特定站点使用不同的 PHP 版本。

Valet 允许你使用 valet use php@version 命令切换 PHP 版本。如果指定的 PHP 版本尚未安装,Valet 会通过 Homebrew 自动安装。

2 
3valet use php

你也可以在项目根目录下创建一个 .valetrc 文件。该 .valetrc 文件应包含该站点应使用的 PHP 版本。

1php=php@8.2

创建该文件后,只需执行 valet use 命令,该命令就会通过读取文件来确定站点首选的 PHP 版本。

即使你安装了多个 PHP 版本,Valet 一次也只能服务于一个 PHP 版本。

数据库

如果你的应用需要数据库,请查看 DBngin,它提供了一个免费的一体化数据库管理工具,包含 MySQL、PostgreSQL 和 Redis。安装 DBngin 后,你可以使用 root 用户名和空密码连接到 127.0.0.1 上的数据库。

重置安装

如果你在使 Valet 正常运行时遇到问题,执行 composer global require laravel/valet 命令,然后再运行 valet install 将重置你的安装,这可以解决各种问题。在极少数情况下,可能需要通过执行 valet uninstall --force 后接 valet install 来“硬重置”Valet。

升级 Valet

你可以通过在终端运行 composer global require laravel/valet 命令来更新 Valet。升级后,建议运行 valet install 命令,以便 Valet 在必要时对配置文件进行额外的升级。

升级到 Valet 4

如果你是从 Valet 3 升级到 Valet 4,请按照以下步骤正确升级你的 Valet 安装:

  • 如果你之前添加了 .valetphprc 文件来自定义站点的 PHP 版本,请将每个 .valetphprc 文件重命名为 .valetrc。然后,在 .valetrc 文件的现有内容前加上 php=
  • 更新所有自定义驱动,以匹配新驱动系统的命名空间、扩展名、类型提示和返回类型提示。你可以参考 Valet 的 SampleValetDriver 作为示例。
  • 如果你使用 PHP 7.1 - 7.4 来服务你的站点,请确保你仍然使用 Homebrew 安装一个 8.0 或更高版本的 PHP,因为 Valet 会使用该版本(即使它不是你的主要链接版本)来运行其部分脚本。

服务站点

一旦安装了 Valet,你就可以开始服务 Laravel 应用了。Valet 提供了两个命令来帮助你:parklink

park 命令

park 命令会将你的机器上包含应用程序的目录注册。一旦目录被 Valet "parked",该目录下的所有子目录都可以在浏览器中通过 http://<directory-name>.test 访问。

1cd ~/Sites
2 
3valet park

就是这么简单。现在,你在 "parked" 目录下创建的任何应用程序都将自动通过 http://<directory-name>.test 约定进行服务。例如,如果你的 parked 目录下有一个名为 "laravel" 的目录,那么该目录下的应用程序将可以通过 http://laravel.test 访问。此外,Valet 还允许你使用通配符子域名(http://foo.laravel.test)访问站点。

link 命令也可以用于服务 Laravel 应用。如果你只想服务目录中的单个站点,而不是整个目录,这个命令非常有用。

1cd ~/Sites/laravel
2 
3valet link

一旦应用程序使用 link 命令链接到 Valet,你就可以使用其目录名称访问该应用程序。因此,上述示例中链接的站点可以通过 http://laravel.test 访问。此外,Valet 还会自动允许你使用通配符子域名(http://foo.laravel.test)访问该站点。

如果你想以不同的主机名服务应用程序,可以将主机名传递给 link 命令。例如,你可以运行以下命令使应用程序在 http://application.test 可用:

1cd ~/Sites/laravel
2 
3valet link application

当然,你也可以使用 link 命令在子域名上服务应用程序。

1valet link api.application

你可以执行 links 命令查看所有已链接目录的列表。

1valet links

unlink 命令可用于销毁站点的符号链接。

1cd ~/Sites/laravel
2 
3valet unlink

使用 TLS 加密站点

默认情况下,Valet 通过 HTTP 服务站点。但是,如果你想通过 HTTPS/TLS 使用 HTTP/2 服务站点,可以使用 secure 命令。例如,如果你的站点由 Valet 在 laravel.test 域名上服务,则应运行以下命令来保护它:

1valet secure laravel

要“取消保护”(unsecure)站点并恢复到通过纯 HTTP 服务,请使用 unsecure 命令。与 secure 命令一样,该命令接受你想要取消保护的主机名。

1valet unsecure laravel

设置默认站点

有时,你可能希望配置 Valet 在访问未知的 test 域名时提供“默认”站点,而不是显示 404。为此,你可以在 ~/.config/valet/config.json 配置文件中添加一个 default 选项,包含应作为默认站点的路径。

1"default": "/Users/Sally/Sites/example-site",

各站点自定义 PHP 版本

默认情况下,Valet 使用你的全局 PHP 安装来服务站点。但是,如果你需要在不同站点间支持多个 PHP 版本,可以使用 isolate 命令指定特定站点应使用的 PHP 版本。isolate 命令会配置 Valet 为当前工作目录中的站点使用指定的 PHP 版本。

1cd ~/Sites/example-site
2 
3valet isolate [email protected]

如果站点名称与包含它的目录名称不匹配,你可以使用 --site 选项指定站点名称。

1valet isolate [email protected] --site="site-name"

为方便起见,你可以使用 valet phpcomposerwhich-php 命令,根据站点配置的 PHP 版本代理调用相应的 PHP CLI 或工具。

1valet php
2valet composer
3valet which-php

你可以执行 isolated 命令来查看所有已隔离的站点及其 PHP 版本列表。

1valet isolated

要将站点恢复到 Valet 全局安装的 PHP 版本,可以在该站点的根目录下调用 unisolate 命令。

1valet unisolate

共享站点

Valet 包含一个命令来向公众共享你的本地站点,这是在移动设备上测试站点或与团队成员和客户共享站点的简便方法。

Valet 开箱即支持通过 ngrok 或 Expose 共享站点。在共享站点之前,你应该使用 share-tool 命令更新 Valet 配置,指定 ngrokexposecloudflared

1valet share-tool ngrok

如果你选择了一个工具但未通过 Homebrew(对于 ngrok 和 cloudflared)或 Composer(对于 Expose)安装它,Valet 会自动提示你安装。当然,这两个工具都需要你在开始共享站点之前验证你的 ngrok 或 Expose 账户。

要共享站点,请在终端中导航到该站点目录并运行 Valet 的 share 命令。一个可公开访问的 URL 将被放入你的剪贴板,可以直接粘贴到浏览器中或与团队分享。

1cd ~/Sites/laravel
2 
3valet share

要停止共享站点,可以按 Control + C

如果你正在使用自定义 DNS 服务器(如 1.1.1.1),ngrok 共享可能无法正常工作。如果是这种情况,请打开 Mac 的系统设置,转到网络设置,打开高级设置,进入 DNS 选项卡,并将 127.0.0.1 添加为第一个 DNS 服务器。

通过 Ngrok 共享站点

使用 ngrok 共享站点需要你创建一个 ngrok 账户设置一个身份验证令牌。拥有令牌后,你可以用该令牌更新 Valet 配置:

1valet set-ngrok-token YOUR_TOKEN_HERE

你可以向 share 命令传递额外的 ngrok 参数,例如 valet share --region=eu。更多信息,请查阅 ngrok 文档

通过 Expose 共享站点

使用 Expose 共享站点需要你创建一个 Expose 账户通过身份验证令牌进行验证

你可以查阅 Expose 文档以获取有关其支持的其他命令行参数的信息。

在本地网络共享站点

默认情况下,Valet 限制传入流量仅能通过内部 127.0.0.1 接口,以确保你的开发机器不会暴露于来自互联网的安全风险中。

如果你希望允许本地网络上的其他设备通过机器的 IP 地址(例如:192.168.1.10/application.test)访问机器上的 Valet 站点,则需要手动编辑该站点的相应 Nginx 配置文件,以移除对 listen 指令的限制。你应该移除 80 和 443 端口 listen 指令上的 127.0.0.1: 前缀。

如果你尚未对该项目运行 valet secure,则可以通过编辑 /usr/local/etc/nginx/valet/valet.conf 文件为所有非 HTTPS 站点开启网络访问。但是,如果你是通过 HTTPS 服务该项目(即已对该站点运行过 valet secure),则应编辑 ~/.config/valet/Nginx/app-name.test 文件。

更新 Nginx 配置后,运行 valet restart 命令以应用配置更改。

站点特定的环境变量

一些使用其他框架的应用可能依赖于服务器环境变量,但没有提供在项目内配置这些变量的方法。Valet 允许你通过在项目根目录下添加 .valet-env.php 文件来配置站点特定的环境变量。该文件应返回一个包含站点/环境变量对的数组,这些变量将添加到数组中指定的每个站点的全局 $_SERVER 数组中。

1<?php
2 
3return [
4 // Set $_SERVER['key'] to "value" for the laravel.test site...
5 'laravel' => [
6 'key' => 'value',
7 ],
8 
9 // Set $_SERVER['key'] to "value" for all sites...
10 '*' => [
11 'key' => 'value',
12 ],
13];

代理服务

有时,你可能希望将 Valet 域名代理到本地机器上的另一个服务。例如,你可能偶尔需要在运行 Docker 中独立站点时使用 Valet;但是,Valet 和 Docker 不能同时绑定到 80 端口。

为了解决这个问题,你可以使用 proxy 命令生成代理。例如,你可以将所有来自 http://elasticsearch.test 的流量代理到 http://127.0.0.1:9200

1# Proxy over HTTP...
2valet proxy elasticsearch http://127.0.0.1:9200
3 
4# Proxy over TLS + HTTP/2...
5valet proxy elasticsearch http://127.0.0.1:9200 --secure

你可以使用 unproxy 命令移除代理。

1valet unproxy elasticsearch

你可以使用 proxies 命令列出所有已代理的站点配置。

1valet proxies

自定义 Valet 驱动

你可以编写自己的 Valet “驱动”来服务运行在 Valet 原生不支持的框架或 CMS 上的 PHP 应用。当你安装 Valet 时,会创建一个 ~/.config/valet/Drivers 目录,其中包含一个 SampleValetDriver.php 文件。该文件包含一个示例驱动实现,展示了如何编写自定义驱动。编写驱动只需实现三个方法:servesisStaticFilefrontControllerPath

所有这三个方法都接收 $sitePath$siteName$uri 作为参数。$sitePath 是你在机器上所服务站点的完全限定路径,例如 /Users/Lisa/Sites/my-project$siteName 是域名的“主机”/“站点名称”部分(my-project)。$uri 是传入请求的 URI(/foo/bar)。

完成自定义 Valet 驱动后,请将其放在 ~/.config/valet/Drivers 目录中,并遵循 FrameworkValetDriver.php 命名约定。例如,如果你正在为 WordPress 编写自定义驱动,文件名应该是 WordPressValetDriver.php

让我们看看自定义 Valet 驱动中每个应实现的方法的示例。

serves 方法

如果你的驱动程序应该处理传入的请求,serves 方法应返回 true。否则,该方法应返回 false。因此,在此方法内,你应该尝试确定给定的 $sitePath 是否包含你试图服务的项目类型。

例如,假设我们正在编写一个 WordPressValetDriver。我们的 serves 方法可能如下所示:

1/**
2 * Determine if the driver serves the request.
3 */
4public function serves(string $sitePath, string $siteName, string $uri): bool
5{
6 return is_dir($sitePath.'/wp-admin');
7}

isStaticFile 方法

isStaticFile 应确定传入请求是否针对“静态”文件,例如图像或样式表。如果文件是静态的,该方法应返回磁盘上静态文件的完全限定路径。如果传入请求不是针对静态文件,则该方法应返回 false

1/**
2 * Determine if the incoming request is for a static file.
3 *
4 * @return string|false
5 */
6public function isStaticFile(string $sitePath, string $siteName, string $uri)
7{
8 if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) {
9 return $staticFilePath;
10 }
11 
12 return false;
13}

只有当 serves 方法针对传入请求返回 true 且请求 URI 不为 / 时,才会调用 isStaticFile 方法。

frontControllerPath 方法

frontControllerPath 方法应返回应用程序“前端控制器”的完全限定路径,通常是“index.php”文件或等效文件。

1/**
2 * Get the fully resolved path to the application's front controller.
3 */
4public function frontControllerPath(string $sitePath, string $siteName, string $uri): string
5{
6 return $sitePath.'/public/index.php';
7}

本地驱动

如果你想为单个应用程序定义自定义 Valet 驱动,请在该应用程序的根目录下创建一个 LocalValetDriver.php 文件。你的自定义驱动可以扩展基础 ValetDriver 类,或扩展现有的特定应用驱动(如 LaravelValetDriver)。

1use Valet\Drivers\LaravelValetDriver;
2 
3class LocalValetDriver extends LaravelValetDriver
4{
5 /**
6 * Determine if the driver serves the request.
7 */
8 public function serves(string $sitePath, string $siteName, string $uri): bool
9 {
10 return true;
11 }
12 
13 /**
14 * Get the fully resolved path to the application's front controller.
15 */
16 public function frontControllerPath(string $sitePath, string $siteName, string $uri): string
17 {
18 return $sitePath.'/public_html/index.php';
19 }
20}

其他 Valet 命令

命令 描述
valet list 显示所有 Valet 命令的列表。
valet diagnose 输出诊断信息以辅助调试 Valet。
valet directory-listing 确定目录列表行为。默认为 "off",即为目录渲染 404 页面。
valet forget 在 "parked" 目录中运行此命令,将其从已 park 的目录列表中移除。
valet log 查看 Valet 服务所编写的日志列表。
valet paths 查看所有 "parked" 路径。
valet restart 重启 Valet 守护进程。
valet start 启动 Valet 守护进程。
valet stop 停止 Valet 守护进程。
valet trust 为 Brew 和 Valet 添加 sudoers 文件,允许运行 Valet 命令时无需输入密码。
valet uninstall 卸载 Valet:显示手动卸载说明。传递 --force 选项可强制删除所有 Valet 资源。

Valet 目录与文件

在排除 Valet 环境问题时,你可能会发现以下目录和文件信息很有帮助:

~/.config/valet

包含所有 Valet 配置。建议定期备份此目录。

~/.config/valet/dnsmasq.d/

该目录包含 DNSMasq 配置。

~/.config/valet/Drivers/

该目录包含 Valet 驱动。驱动决定了特定的框架/CMS 如何被服务。

~/.config/valet/Nginx/

该目录包含所有 Valet 的 Nginx 站点配置。这些文件在运行 installsecure 命令时会重新生成。

~/.config/valet/Sites/

该目录包含所有已链接项目的符号链接。

~/.config/valet/config.json

此文件是 Valet 的主配置文件。

~/.config/valet/valet.sock

此文件是 Valet 的 Nginx 安装所使用的 PHP-FPM 套接字。只有在 PHP 运行正常时才会存在。

~/.config/valet/Log/fpm-php.www.log

此文件是 PHP 错误的用户日志。

~/.config/valet/Log/nginx-error.log

此文件是 Nginx 错误的用户日志。

/usr/local/var/log/php-fpm.log

此文件是 PHP-FPM 错误系统日志。

/usr/local/var/log/nginx

该目录包含 Nginx 访问日志和错误日志。

/usr/local/etc/php/X.X/conf.d

该目录包含各种 PHP 配置设置的 *.ini 文件。

/usr/local/etc/php/X.X/php-fpm.d/valet-fpm.conf

此文件是 PHP-FPM 资源池配置文件。

~/.composer/vendor/laravel/valet/cli/stubs/secure.valet.conf

此文件是用于为站点构建 SSL 证书的默认 Nginx 配置文件。

磁盘访问

自 macOS 10.14 起,对某些文件和目录的访问默认受到限制。这些限制包括桌面、文档和下载目录。此外,对网络卷和可移动卷的访问也受到限制。因此,Valet 建议你的站点文件夹位于这些受保护位置之外。

但是,如果你希望从这些位置之一服务站点,则需要授予 Nginx“完全磁盘访问权限”。否则,你可能会遇到服务器错误或 Nginx 的其他不可预知行为,尤其是在服务静态资源时。通常,macOS 会自动提示你授予 Nginx 对这些位置的完全访问权限。或者,你可以通过 系统偏好设置 > 安全性与隐私 > 隐私 手动授予,并选择 完全磁盘访问权限。接下来,在主窗口窗格中启用任何 nginx 条目。