简介
正在寻找在 macOS 或 Windows 上开发 Laravel 应用更简便的方法?请了解 Laravel Herd。Herd 包含了开始 Laravel 开发所需的一切,包括 Valet、PHP 和 Composer。
Laravel Valet 是为极简主义 macOS 用户打造的开发环境。Laravel Valet 会将你的 Mac 配置为在机器启动时在后台始终运行 Nginx。然后,借助 DnsMasq,Valet 会将 *.test 域名下的所有请求代理到你本地机器上已安装的站点。
换句话说,Valet 是一个极速的 Laravel 开发环境,仅占用约 7 MB 内存。Valet 并非 Sail 或 Homestead 的完全替代品,但如果你想获得灵活的基础配置、追求极致速度,或者在内存有限的机器上工作,它是一个极佳的替代方案。
开箱即用,Valet 的支持包括但不限于:
- Laravel
- Bedrock
- CakePHP 3
- ConcreteCMS
- Contao
- Craft
- Drupal
- ExpressionEngine
- Jigsaw
- Joomla
- Katana
- Kirby
- Magento
- OctoberCMS
- Sculpin
- Slim
- Statamic
- Static HTML
- Symfony
- WordPress
- Zend
不过,你可以使用自定义驱动扩展 Valet。
安装
Valet 需要 macOS 和 Homebrew。安装前,应确保没有其他程序(如 Apache 或 Nginx)占用本地机器的 80 端口。
开始之前,你需要先使用 update 命令确保 Homebrew 是最新版本:
brew update接下来,应使用 Homebrew 安装 PHP:
brew install php安装完 PHP 后,就可以安装 Composer 包管理器。此外,应确保 $HOME/.composer/vendor/bin 目录已加入系统的 “PATH” 中。安装 Composer 后,可将其作为全局 Composer 包来安装 Laravel Valet:
composer global require laravel/valet最后,可执行 Valet 的 install 命令。该命令会配置并安装 Valet 和 DnsMasq。此外,Valet 所依赖的守护进程也会被配置为在系统启动时运行:
valet installValet 安装完成后,尝试在终端使用 ping foobar.test 之类的命令对任意 *.test 域名执行 ping 操作。如果 Valet 安装正确,你应该会看到该域名在 127.0.0.1 上有响应。
Valet 会在机器每次启动时自动启动所需的服务。
PHP 版本
无需修改全局 PHP 版本,你可以使用 isolate 命令指示 Valet 为每个站点分别指定 PHP 版本。
Valet 允许你使用 valet use php@version 命令切换 PHP 版本。如果指定的 PHP 版本尚未安装,Valet 会通过 Homebrew 进行安装:
valet use[email protected]
valet use php你还可以在项目根目录创建一个 .valetrc 文件。.valetrc 文件中应包含该站点要使用的 PHP 版本:
[email protected]创建该文件后,只需执行 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 提供两个命令来帮助你运行应用:park 和 link。
park 命令
park 命令用于注册机器上包含应用的目录。一旦将目录“停靠”(park)到 Valet,该目录下的所有目录都可通过浏览器在 http://<directory-name>.test 访问:
cd ~/Sites
valet park就是这么简单。现在,你在“停靠”目录中创建的任何应用都会自动按照 http://<directory-name>.test 的规范提供服务。因此,如果停靠目录中包含名为 “laravel” 的目录,该目录中的应用可通过 http://laravel.test 访问。此外,Valet 会自动允许你使用通配子域名访问站点(http://foo.laravel.test)。
link 命令
link 命令同样可用于为 Laravel 应用提供服务。如果你只想为某个目录下的单个站点提供服务,而非整个目录,这个命令就十分有用:
cd ~/Sites/laravel
valet link使用 link 命令将应用链接到 Valet 后,就可以通过目录名访问该应用。因此,上例中链接的站点可通过 http://laravel.test 访问。此外,Valet 会自动允许你使用通配子域名访问站点(http://foo.laravel.test)。
如果想让应用通过不同的主机名提供服务,可将主机名传递给 link 命令。例如,你可以运行以下命令,让应用在 http://application.test 处可用:
cd ~/Sites/laravel
valet link application当然,你也可以使用 link 命令在子域名上提供应用服务:
valet link api.application你可以执行 links 命令,查看所有已链接目录的列表:
valet links可以使用 unlink 命令删除站点的符号链接:
cd ~/Sites/laravel
valet unlink使用 TLS 保障站点安全
默认情况下,Valet 通过 HTTP 提供站点服务。不过,如果你想使用加密的 TLS 并通过 HTTP/2 提供站点服务,可以使用 secure 命令。例如,如果你的站点通过 laravel.test 域名由 Valet 提供服务,则应运行以下命令来保护它:
valet secure laravel若要“解除保护”某个站点并恢复为通过普通 HTTP 提供流量服务,请使用 unsecure 命令。与 secure 命令类似,此命令接受你希望解除保护的主机名:
valet unsecure laravel提供默认站点
有时,你可能希望将 Valet 配置为:在访问未知的 test 域名时返回一个“默认”站点,而不是返回 404。为此,你可以向 ~/.config/valet/config.json 配置文件中添加一个 default 选项,其值为应作为默认站点提供服务的路径:
"default": "/Users/Sally/Sites/example-site",针对站点的 PHP 版本
默认情况下,Valet 使用你全局安装的 PHP 来提供站点服务。不过,如果你需要在不同站点中支持多个 PHP 版本,可以使用 isolate 命令来指定某个站点应使用的 PHP 版本。isolate 命令会将 Valet 配置为:对位于当前工作目录中的站点使用指定的 PHP 版本:
cd ~/Sites/example-site
valet isolate[email protected]如果你的站点名称与包含该站点的目录名称不一致,可以使用 --site 选项来指定站点名称:
valet isolate[email protected] --site="site-name"为方便起见,你可以使用 valet php、composer 和 which-php 命令,根据站点配置的 PHP 版本,将调用代理到相应的 PHP CLI 或工具:
valet php
valet composer
valet which-php你可以执行 isolated 命令,以列出所有已隔离的站点及其 PHP 版本:
valet isolated若要将某个站点恢复为 Valet 全局安装的 PHP 版本,可以在该站点的根目录下调用 unisolate 命令:
valet unisolate共享站点
Valet 内置了一条命令,可以将你的本地站点共享给全世界,让你能够便捷地在移动设备上测试站点,或将其共享给团队成员与客户。
Valet 开箱即用地支持通过 ngrok 或 Expose 共享站点。在共享站点之前,你应使用 share-tool 命令更新 Valet 配置,指定 ngrok、expose 或 cloudflared:
valet share-tool ngrok如果你选择了一个工具,但尚未通过 Homebrew(针对 ngrok 与 cloudflared)或 Composer(针对 Expose)安装它,Valet 会自动提示你进行安装。当然,这两个工具都需要你先完成 ngrok 或 Expose 账户的认证,才能开始共享站点。
要共享站点,请在终端中进入站点目录,然后运行 Valet 的 share 命令。一个可公开访问的 URL 将会被放入你的剪贴板,可直接粘贴到浏览器中,或分享给你的团队:
cd ~/Sites/laravel
valet share若要停止共享站点,可以按下 Control + C。
如果你使用的是自定义 DNS 服务器(例如 1.1.1.1),ngrok 共享可能无法正常工作。如果你的机器出现此情况,请打开 Mac 的系统设置,进入“网络”设置,打开“高级”设置,然后进入 DNS 选项卡,并将 127.0.0.1 添加为首选 DNS 服务器。
通过 Ngrok 共享站点
使用 ngrok 共享站点需要你先创建 ngrok 账户并设置身份验证令牌。获取身份验证令牌后,你可以用该令牌更新 Valet 配置:
valet set-ngrok-token YOUR_TOKEN_HERE 你可以向 share 命令传递额外的 ngrok 参数,例如 valet share --region=eu。如需了解更多信息,请参阅ngrok 文档。
通过 Expose 共享站点
使用 Expose 共享站点需要你先创建 Expose 账户,并通过身份验证令牌在 Expose 中完成身份验证。
如需了解它支持的额外命令行参数,请参阅Expose 文档。
在本地网络共享站点
默认情况下,Valet 会将入站流量限制在内部 127.0.0.1 接口上,以避免你的开发机暴露于来自互联网的安全风险。
如果你希望允许本地网络上的其他设备通过你机器的 IP 地址访问你机器上的 Valet 站点(例如:192.168.1.10/application.test),你需要手动编辑该站点对应的 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 数组中,并应用到数组中指定的每个站点:
<?php
return [
// 将 laravel.test 站点的 $_SERVER['key'] 设置为 "value"...
'laravel' => [
'key' => 'value',
],
// 为所有站点将 $_SERVER['key'] 设置为 "value"...
'*' => [
'key' => 'value',
],
];代理服务
有时你可能希望将 Valet 域名代理到你本地机器上的另一个服务。例如,你可能偶尔需要在运行 Docker 中独立站点的同时运行 Valet;但 Valet 与 Docker 不能同时绑定到 80 端口。
要解决这一问题,可以使用 proxy 命令生成一个代理。例如,你可以将来自 http://elasticsearch.test 的所有流量代理到 http://127.0.0.1:9200:
# 通过 HTTP 代理...
valet proxy elasticsearch http://127.0.0.1:9200
# 通过 TLS + HTTP/2 代理...
valet proxy elasticsearch http://127.0.0.1:9200 --secure你可以使用 unproxy 命令移除代理:
valet unproxy elasticsearch你可以使用 proxies 命令列出所有已代理的站点配置:
valet proxies自定义 Valet 驱动
你可以编写自己的 Valet “驱动”,用于服务那些运行在 Valet 原生不支持的框架或 CMS 上的 PHP 应用。安装 Valet 时,会创建 ~/.config/valet/Drivers 目录,其中包含一个 SampleValetDriver.php 文件。该文件包含一个示例驱动实现,用于演示如何编写自定义驱动。编写驱动只需实现三个方法:serves、isStaticFile 与 frontControllerPath。
这三个方法都会接收 $sitePath、$siteName 和 $uri 作为参数。$sitePath 是你机器上正在提供服务的站点的完整路径,例如 /Users/Lisa/Sites/my-project。$siteName 是域名中的“主机”/“站点名”部分(my-project)。$uri 是传入请求的 URI(/foo/bar)。
完成自定义 Valet 驱动后,请按照 FrameworkValetDriver.php 的命名约定将其放入 ~/.config/valet/Drivers 目录。例如,如果你正在为 WordPress 编写自定义 valet 驱动,文件名应为 WordPressValetDriver.php。
让我们来看一下自定义 Valet 驱动需要实现的各方法的示例实现。
serves 方法
serves 方法应当返回 true,表示你的驱动程序需要处理传入的请求。否则,该方法应当返回 false。因此,在该方法内部,你应当尝试判断给定的 $sitePath 是否包含你正在尝试服务的对应类型项目。
例如,假设我们正在编写一个 WordPressValetDriver。我们的 serves 方法可能会像这样:
/**
* 判断驱动程序是否处理该请求。
*/
public function serves(string $sitePath, string $siteName, string $uri): bool
{
return is_dir($sitePath.'/wp-admin');
}isStaticFile 方法
isStaticFile 应当判断传入的请求是否针对“静态”文件,例如图片或样式表。如果该文件是静态文件,该方法应当返回该静态文件在磁盘上的完整路径。如果传入的请求并非针对静态文件,该方法应当返回 false:
/**
* 判断传入的请求是否针对静态文件。
*
* @return string|false
*/
public function isStaticFile(string $sitePath, string $siteName, string $uri)
{
if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) {
return $staticFilePath;
}
return false;
} 只有当 serves 方法针对传入的请求返回 true,且请求 URI 不是 / 时,才会调用 isStaticFile 方法。
frontControllerPath 方法
frontControllerPath 方法应当返回应用程序“前端控制器”的完整路径,通常是一个“index.php”文件或等效文件:
/**
* 获取应用程序前端控制器的完整解析路径。
*/
public function frontControllerPath(string $sitePath, string $siteName, string $uri): string
{
return $sitePath.'/public/index.php';
}本地驱动程序
如果你想为单个应用程序定义自定义的 Valet 驱动程序,可以在应用程序的根目录下创建一个 LocalValetDriver.php 文件。你的自定义驱动程序可以继承基础的 ValetDriver 类,也可以继承现有的特定应用程序驱动程序,例如 LaravelValetDriver:
use Valet\Drivers\LaravelValetDriver;
class LocalValetDriver extends LaravelValetDriver
{
/**
* 判断驱动程序是否处理该请求。
*/
public function serves(string $sitePath, string $siteName, string $uri): bool
{
return true;
}
/**
* 获取应用程序前端控制器的完整解析路径。
*/
public function frontControllerPath(string $sitePath, string $siteName, string $uri): string
{
return $sitePath.'/public_html/index.php';
}
}其他 Valet 命令
| 命令 | 说明 |
|---|---|
valet list | 显示所有 Valet 命令的列表。 |
valet diagnose | 输出诊断信息,以帮助调试 Valet。 |
valet directory-listing | 设置目录列表行为。默认值为“off”,此时对目录访问会返回 404 页面。 |
valet forget | 在“挂载(parked)”目录中运行此命令,可将其从挂载目录列表中移除。 |
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 站点配置。运行 install 和 secure 命令时,这些文件会被重新生成。
~/.config/valet/Sites/
此目录包含所有已链接项目的符号链接。
~/.config/valet/config.json
此文件是 Valet 的主配置文件。
~/.config/valet/valet.sock
此文件是 Valet 的 Nginx 安装所使用的 PHP-FPM socket。只有当 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 条目。