## **簡介**
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`的響應:

每次系統啟動的時候 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 并插入剪貼板,以便你直接復制到瀏覽器地址欄,就是這么簡單:

你可以通過`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`查看。