## **简介**
Valet 是为 Mac 打造的极简 Laravel 开发环境【只需要占用 7M 内存】,没有 Vagrant,没有虚拟机,也无需配置`/etc/hosts`文件,还可以使用本地隧道公开分享你的站点。启动 Mac 后,Laravel Valet 会在后台静默运行[Nginx](https://www.nginx.com/),然后通过[DnsMasq](https://en.wikipedia.org/wiki/Dnsmasq),Valet 会代理所有针对`*.test`域名的请求指向本地安装的站点目录。
Valet 并不是想要替代 Vagrant 或者 Homestead,只是提供了另外一种选择,更加灵活、极速、以及占用更小的内存空间。正因如此,我们将 Valet 称之为轻量级的开发环境。
Valet 开箱支持但不限于以下软件和工具:
* [Laravel](https://laravel.com/)
* [Lumen](https://lumen.laravel.com/)
* [Bedrock](https://roots.io/bedrock/)
* [CakePHP 3](https://cakephp.org/)
* [Concrete5](http://www.concrete5.org/)
* [Contao](https://contao.org/en/)
* [Craft](https://craftcms.com/)
* [Drupal](https://www.drupal.org/)
* [Jigsaw](http://jigsaw.tighten.co/)
* [Joomla](https://www.joomla.org/)
* [Katana](https://github.com/themsaid/katana)
* [Kirby](https://getkirby.com/)
* [Magento](https://magento.com/)
* [OctoberCMS](https://octobercms.com/)
* [Sculpin](https://sculpin.io/)
* [Slim](https://www.slimframework.com/)
* [Statamic](https://statamic.com/)
* Static HTML
* [Symfony](https://symfony.com/)
* [WordPress](https://symfony.com/)
* [Zend](https://framework.zend.com/)
以上支持的驱动文件位于`~/.composer/vendor/laravel/valet/cli/drivers`目录下,当然,你还可以通过自定义驱动扩展 Valet,自定义的驱动文件存放在`~/.valet/Drivers`目录。
## **安装**
安装之前要确保没有其他程序如Apache 或 Nginx 绑定到本地的 80 端口。安装步骤如下:
* 使用`brew update`安装或更新 Homebrew 到最新版本;
* 通过 Homebrew 安装 PHP 7.3:`brew install php`;
* 通过 Composer 安装 Valet:`composer global require laravel/valet`(确保`~/.composer/vendor/bin`目录在系统路径中);
* 运行`valet install`命令,这将会自动配置并安装 Valet 和 DnsMasq,然后注册 Valet 后台随机启动。
安装完 Valet 后,尝试使用命令在终端 ping 一下任意`*.test`域名(如`ping foobar.test`),如果 Valet 安装正确就会看到来自`127.0.0.1`的响应:
![](https://img.kancloud.cn/02/bd/02bdb081045237c9a5824fac7745c734_1032x248.jpeg)
每次系统启动的时候 Valet 会在后台自动启动,不需要再次手动运行`valet start`或`valet install`。
### **数据库**
> ### 注:已安装 MySQL 数据库忽略本条。
如果你需要数据库,可以在命令行通过`brew install mysql@5.7`安装MySQL,安装完成后就可以通过`brew services start mysql@5.7`来启动它,然后通过用户名`root`和一个空密码连接到本地数据库(主机是`127.0.0.1`)。
### **PHP版本**
Valet 允许你使用`valet use php@version`来切换 PHP 的版本,如果指定 PHP 版本不存在的话,Valet 会通过 Brew 自动帮你安装:
~~~
valet use php@7.2
valet use php // 默认PHP版本
~~~
## **升级**
你可以在终端使用`composer global update`命令来升级 Valet。升级之后,最好运行下`valet install`命令以便 Valet 在必要情况下对配置文件进行升级。
> Valet 2.0 将 Valet 底层的 web 服务器从 Caddy 替换成了 Nginx,升级到这个版本之前需要运行以下命令来停止和卸载已经在后台运行的 Caddy:
~~~
valet stop
valet uninstall
~~~
基于 Valet 的安装方式,你可以通过 Git 或 Composer 来升级最新版本,如果你是通过 Composer 安装的 Valet,需要通过如下方式更新到最新的主版本:
~~~
composer global require laravel/valet
~~~
最新的 Valet 源码下载好之后,运行`install`命令(升级之后,需要 re-park 和 re-link 站点):
~~~
valet install
valet restart
~~~
## **访问站点**
Valet 安装完成后,就可以启动服务站点,Valet 为此提供了两个命令:`park`和`link`。
### `park`**命令**
* 在 Mac 系统中创建一个新目录,例如`mkdir ~/Sites`,然后进入这个目录并运行`valet park`。这个命令会将当前所在目录作为 Web 根目录。
* 然后,在新建的目录中创建一个新的 Laravel 站点即可:`laravel new blog`。
这就是我们要做的全部工作。现在,所有在`Sites`目录中创建的 Laravel 项目都可以通过`http://folder-name.test`这种方式在浏览器中访问,是不是很方便?
### `link`**命令**
`link`命令也可以用于访问本地 Laravel 站点,当你想要提供单个访问站点时这个命令很有用。
* 首先切换到你的某个项目并运行`valet link app-name`,这样 Valet 会在`~/.config/valet/Sites`中创建一个符号链接指向当前工作目录。
* 运行完`link`命令后,可以在浏览器中通过`http://app-name.test`访问站点。
要查看所有的链接目录,可以运行`valet links`命令。你也可以通过`valet unlink app-name`来删除符号链接。
### **通过 TLS 保护站点**
默认情况下,Valet 使用 HTTP 协议,如果你想要使用 HTTP/2 通过加密的 TLS 为站点提供服务,可以使用`secure`命令。如果你的站点域名是`laravel.test`,就可以使用如下命令:
~~~
valet secure laravel
~~~
要想回到"非安全"的 HTTP,可以使用`unsecure`命令。和`secure`命令一样,该命令接收主机名作为参数:
~~~
valet unsecure laravel
~~~
## **分享站点**
Valet 还提供了一个命令用于将本地站点共享给其他人,这不需要任何额外工具即可实现(和 Homestead 一样,底层也是通过 Ngrok 实现):切换到站点所在目录并运行`valet share`,这会生成一个可以公开访问的 URL 并插入剪贴板,以便你直接复制到浏览器地址栏,就是这么简单:
![](https://img.kancloud.cn/c2/c0/c2c006abc2fe83116e6a7cbb42ca9773_1346x640.jpeg)
你可以通过`http://8f3361ed.ngrok.io/`或`https://8f3361ed.ngrok.io`从任意联网机器访问站点(因为已经公开到互联网上)。要停止共享站点,使用`Control + C`快捷键结束该命令即可。
## **自定义 Valet 驱动**
你还可以编写自定义的 Valet 驱动为非 Valet 原生支持的 PHP 应用提供服务。安装完 Valet 时系统会创建一个`~/.config/valet/Drivers`目录,该目录中有一个`SampleValetDriver.php`文件,这个文件中有一个演示如何编写自定义驱动的示例。
自定义驱动类可以继承自`ValetDriver`基类或者继承自已存在的应用指定驱动类如`LaravelValetDriver,`编写它只需要实现三个方法:`serves`、`isStaticFile`和`frontControllerPath`。
这三个方法接收`$sitePath`、`$siteName`和`$uri`值作为参数,其中`$sitePath`表示站点目录,如`~/Sites/my-project`,`$siteName`表示主域名部分,如`my-project`,而`$uri`则是输入的请求地址,如`/foo/bar`。
编写好自定义的 Valet 驱动后,将其放到`~/.config/valet/Drivers`目录并遵循`FrameworkValetDriver.php`这种命名方式,举个例子,如果你是在为 WordPress 编写自定义的 Valet 驱动,对应的文件名称为`WordPressValetDriver.php`。
### `serves`**方法**
如果自定义驱动需要继续处理输入请求,`serves`方法会返回`true`,否则该方法返回`false`。因此,在这个方法中应该判断给定的`$sitePath`是否包含你服务类型的项目。
例如,假设我们编写的是`WordPressValetDriver`,那么对应`serves`方法如下:
~~~
/**
* Determine if the driver serves the request.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return void
* @translator laravelacademy.org
*/
public function serves($sitePath, $siteName, $uri)
{
return is_dir($sitePath.'/wp-admin');
}
~~~
### `isStaticFile`**方法**
`isStaticFile`方法会判断输入请求是否是静态文件,例如图片或样式文件,如果文件是静态的,该方法会返回磁盘上的完整路径,如果输入请求不是请求静态文件,则返回`false`:
~~~
/**
* Determine if the incoming request is for a static file.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return string|false
*/
public function isStaticFile($sitePath, $siteName, $uri)
{
if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) {
return $staticFilePath;
}
return false;
}
~~~
> 注:`isStaticFile`方法只有在`serves`方法返回`true`并且请求 URI 不是`/`的时候才会被调用。
### `frontControllerPath`**方法**
`frontControllerPath`方法会返回前端控制器的完整路径,通常是`index.php`:
~~~
/**
* Get the fully resolved path to the application's front controller.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return string
*/
public function frontControllerPath($sitePath, $siteName, $uri)
{
return $sitePath.'/public/index.php';
}
~~~
关于自定义 Valet 驱动可以参考学院君为 Flarum 论坛编写的扩展教程:[在 Mac 开发环境 Laravel Valet 中配置运行 Flarum 论坛系统](http://laravelacademy.org/post/5679.html)。
## **其他常用 Valet 命令**
| | 描述 |
| :-- | :-- |
| `valet forget` | 从「parked」目录运行该命令以便从 parked 目录列表中移除该目录 |
| `valet paths` | 查看你的「parked」路径 |
| `valet restart` | 重启 Valet |
| `valet start` | 启动 Valet |
| `valet stop` | 关闭 Valet |
| `valet uninstall` | 卸载 Valet |
更多 Valet 命令,可以通过运行`valet list`查看。