2019年2月28日 星期四

Symfony4.2入門教學【第三篇】路由(Routing)


漂亮的URLs是任何嚴謹的網頁應用程式都需要的,這代表比起index.php?article_id=57這樣不美觀的URLs,更喜歡像是/read/intro-to-symfony這個樣子。

保有彈性也是很重要的一點,如果你像要將一個頁面URL從/blog變成/news該怎麼做?為了這個更動,有多少連結要追溯、更新?如果你是用Symfony的路由,這些問題都能輕鬆解決。


建立路由

路由是將URL對應到控制器(controller),假設我們希望有個路由可以對應到/blog,其他更動態的路由可以對應到更多URL,如/blog/my-post/blog/all-about-symfony

路由的設定可以寫在YAML、XML和PHP,所有的檔案類型都能提供相同的特性和效能,所以只要選一個喜歡的使用即可,如果是用PHP註解式宣告(PHP annotations),請執行一次這個指令讓系統支援這個方式。
composer require annotations
現在可以設定路由:
// 省略程式碼
由於這兩個路由:
  • 如果使用者前往/blog,與第一個路由匹配並執行函式list()
  • 如果使用者前往/blog/*,與第二個路由相符並執行函式show(),有個參數$slug會傳到show()去對應。比方說,如果使用者前往/blog/yay-routing,所以$slug等於yay-routing
只要在路由中設定{placeholder},這個部分會變成通配符(wildcard),會配對任何值,現在你的控制器將會有一個$placeholder的參數(通配符和參數名稱必須相符)。

每個路由還有一個內部名稱(internal name):blog_listblog_show},名稱可以自行決定(只要不重複),現在還沒有用到,之後可以用來產生URL

其他格式的路由
每個函式上面的@Route稱為註解(annotation),如果你傾向用YAML、XML或PHP設定路由,也沒關係!在config/資料夾內新建一個路由檔案(e.g. routes.xml),Symfony會自動使用。



本地化路由 (i18n)

路由可以提供每個地區(locale)一個獨一無二的路徑來達到本地化,Symfony提供一個方便的方法去宣告本地化路由,省去許多重複性的工作。
// 省略程式碼
當需求(request)與一個本地化路由相符時,Symfony會自動知道要要使用哪一個地區,這樣的宣告方式也同時降低重複註冊路由的需求,也就是降低因定義不一致產生錯誤的風險。

如果應用使用語言和地區(full language + territory)(e.g. fr_FR, fr_BE),你可以在路由中用語言部分代表,當你想要同一個路由使用同一個語言時,可以避免重複定義多個路徑。

對於一個國際化的應用,在所有路由前加上地區當作前綴是很常見的需求,每一個地區定義不同的前綴就能達成(如果有需要的話,預設地區可以設定空白前綴字):
// 省略程式碼


新增通配符{wildcard}的條件

想像一下有個blog_list的路由是分成很多頁的部落格貼文,路徑可能像是blog/2blog/3,如果將路由的路徑設定成blog/{page},你可能會有疑問:
  • blog_list: blog/{page}blog/*相符
  • blog_show: blog/{slug}也與blog/*相符
當兩個路由和同一個路徑都相符時,會以第一個路由為主,不幸地是這代表/blog/yay-routing將會配對blog_list,這不是我們想要的。

為了解決這個問題,我們新增一個條件(requirement),讓{page}通配符只能是數字(number, digits):
// 省略程式碼
\d+是一個通常表示式(regular expression),能與任何長度的數字配對,整理一下現在的情況:

URL Route Parameters
/blog/2 blog_list $page = 2
/blog/yay-routing blog_show $slug = yay-routing

如果你願意的話,條件可以和佔位符(placeholder)寫在同一行,句法會像這樣{placeholder_name},這個特性可以讓設定檔顯得更加簡潔,不過當條件比較複雜時,也同時降低可讀性。
// 省略程式碼
想要認識更多路由條件 - 像是HTTP method、主機名稱(hostname)和動態表示式(dynamic expressions) - 請看如何設定路由條件


設定占用符{placeholders}預設值

在前面的例子中,blog_list設定的路徑是/blog/{page},如果使用這訪問/blog/1,將會符合;當如果是/blog,將不會配對成功。只要在路徑設定一個{placeholder},就必須有值。

所以如何再一次將讓blog_list/blog配對呢?可以透過設定預設值:
// 省略程式碼
現在,當使用者前往/blog時,會對應到路由blog_list,此時$page為預設值1

如果你希望每次產生URL時都需要預設值(等同前面的舉例,強制讓/blog變成/blog/1),在佔位符前面加上字元!/blog/{!page}

New in version 4.3:
Symfony 4.3中新增了強制在產生的URL中包含預設值的功能。

和路由條件一樣,預設值和佔位符也能將定義寫在同一行,句法為{placehodler_name?defulat_value},這個功能與路由條件能夠同時使用,所以你可以把預設值、路由條件兩者與佔位符用一行定義:
// 省略程式碼
如果想把任何佔位符的預設值定為null,請在?字元後面什麼都不要加。(e.g. /blog/{page?})


列出所有路由

隨著你的專案開發,最終你會有一堆路由,如果要全部檢視請執行:
php bin/console debug:router

------------------------------ -------- -------------------------------------
 Name                           Method   Path
------------------------------ -------- -------------------------------------
 app_lucky_number              ANY    /lucky/number/{max}
 ...
------------------------------ -------- -------------------------------------


進階路由範例

綜合上述,請看下面這個進階範例:
// 省略程式碼
如同你看到的,這個路由只會在{_locale}這個部分是enfr,而且{year}是數字時,才會匹配。這個路由也顯示在佔位符之間如何使用點(dot),而非使用斜槓(slash),符合這個陸游的URL像是:
  • /articles/en/2010/my-post
  • /articles/fr/2010/my-post.rss
  • /articles/en/2013/my-latest-post.html

特殊路由參數_format
這範例也點出特殊路由參數_format,使用這個參數時,匹配的值將成為Request對象的“請求格式”。

最終,請求格式用於諸如設置響應的Content-Type之類的事情(例如,json請求格式轉換為Content-Typeapplication/json)。

有時您希望全局配置路線的某些部分,Symfony利用服務容器參數(service container parameters)為您提供了一種方法。在“如何在路由中使用服務容器參數(How to Use Service Container Parameters in your Routes)”中閱讀有關此內容的更多信息。

特殊的路由參數
就像你看到的,每個路由參數或預設值會成為控制器函式可取得的變數,除此之外,有四個特別的參數:每一個都能在你的應用裡發揮獨有的功能:
_controller
如同所示,當路由配對成功時,決定要執行哪一個控制器。

_format
用來設定請求(request)的格式(閱讀更多)

_fragment
用來設定片段標識符,這是一個自選的功能,在URL的最後加上以#字元開頭的字串,來辨識整份文件的某個段落。

_locale
用來設定請求(request)的地區(閱讀更多)

重新導向尾端斜槓(slashes)的URL
從古到今,URL遵照UNIX協定,如果當作目錄就在尾端加上斜槓(e.g. https://example.com/foo/),視為文件的話會刪掉最後的斜槓來進行導向(e.g. https://example.com/foo,雖然兩個URL可以提供不通的內容,但將兩者視為相同的URL並在它們之間重新轉向是很常見的。

Symfony遵循有和沒有尾端斜槓URL之間的重新導向這樣的邏輯(但只適用GETHEAD請求):

Route path If the requested URL is /foo If the requested URL is /foo/
/foo It matches (200status response) It makes a 301 redirect to /foo
/foo/ It makes a 301 redirect to /foo/ It matches (200status response)

如果應用內定義每個路徑了不同的路由(/foo/foo/),不會發生這種自動重定向的情形,而且總是配對正確的路由。


控制器命名方式

路由內controller格式為CONTROLLER_CLASS::METHOD
若要引用控制器的一種__invoke()的操作,不需要傳函式名稱,或者用完全合格的類名(fully qualified class name)(e.g. App\Controller\BlogController)。


產生URLs

路由系統也可以產生URL,實際上,路由是雙向系統:由URL對應到控制器、路由對應到URL。

要生成URL,你需要指定路徑會使用到的路由的名稱(e.g blog_show)和任何通配符(slug = my-blog-post),有了這些資訊,控制器就能產生URL:
class MainController extends AbstractController
{
    public function show($slug)
    {
        // ...

        // /blog/my-blog-post
        $url = $this->generateUrl(
            'blog_show',
            ['slug' => 'my-blog-post']
        );
    }
}
如果你需要從服務(service)產生URL,型態會像是UrlGeneratorInterface
// src/Service/SomeService.php

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class SomeService
{
    private $router;

    public function __construct(UrlGeneratorInterface $router)
    {
        $this->router = $router;
    }

    public function someMethod()
    {
        $url = $this->router->generate(
            'blog_show',
            ['slug' => 'my-blog-post']
        );
        // ...
    }
}

產生帶有查詢字串的URL
generate()的函式會使用整個通配符陣列(an array of wildcard value)來闡產生URL,但如果傳送了額外的值,會當作查詢字串加到URL。
$this->router->generate('blog', [
    'page' => 2,
    'category' => 'Symfony',
]);
// /blog/2?category=Symfony

產生本地化URLs
當路由是本地的(localized),Symfony會用現在的請求地區(request locale)來生成URL,如果要生成不同地區的URL,就必須傳_locale到參數陣列內。
$this->router->generate('about_us', [
    '_locale' => 'nl',
]);
// generates: /over-ons

在模板(Template)裡產生URLs
在Twig產生URLs,可以參考關於模板的文章:連結到頁面(Linking to Pages),假設你也想要在JavaScript裡產生連結,請看:如何在JavaScript產生路由URLs(How to Generate Routing URLs in JavaSript)。

產生絕對路徑(Absolute URLs)
一般情況下,路由會產生相應的URLs(e.g. /blog),從控制器,將UrlGeneratorInterface::ABSOLUTE_URL當作generateUrl()的第三個參數:
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

$this->generateUrl('blog_show', ['slug' => 'my-blog-post'], UrlGeneratorInterface::ABSOLUTE_URL);
// http://www.example.com/blog/my-blog-post
產生絕對URL時使用的主機是透過當前Request對象自動檢測的。從Web上下文(context)外部產收絕對URL時(例如在控制台命令中),這不起作用。請參閱如何從控制台生成URL(How to Generate URLs from the Console)以了解如何解決此問題。


Troubleshooting

當你在寫路由時,你可能看過這些常見的錯誤:
Controller "App\Controller\BlogController::show()" requires that you provide a value for the "$slug" argument.
這發生在你的控制器函式需要一個參數(e.g.$slug):
public function show($slug)
{
    // ..
}
但是你的路由裡沒有{slug}這個通配符(e.g. /blog/show),在路由新增{slug}/blog/show/{slug}或將參數定一個預設值(i.e. $slug = null)。
Some mandatory parameters are missing ("slug") to generate a URL for route "blog_show".
這代表你正試圖讓blog_show路由產生一個沒有slug值的URL(但slug值卻是必要的,因為路徑中有個通配符{slug}),為了修正這個問題,產生路由時請傳slug值:
$this->generateUrl('blog_show', ['slug' => 'slug-value']);

// or, in Twig
// {{ path('blog_show', {'slug': 'slug-value'}) }}


繼續前進!

路由沒問題了,現在一起揭開控制器(原文)的強大吧!



文章原文:
https://symfony.com/doc/4.2/setup.html

系列文章:

2019年2月13日 星期三

Symfony4.2入門教學【第二篇】建立第一個頁面


建立一個新頁面,有兩個步驟要做:
  1. 建立路由(route):所謂路由就是連接到網頁的URL(e.g. /about)和控制器。
  2. 建立控制器(controller):控制器是由PHP函式構成,針對你接收到請求(request)去建立一個Symfony的回應(Response),這個回應有可能是HTML、JSON字串或二進位檔(binary file)如圖片或PDF。

你更傾向影片教學?查看教學影片

Symfony 有包含HTTP 請求-回應生命週期(HTTP Request-Response lifecycle),要了解更多訊息,請看Symfony和HTTP基礎知識


新建頁面:路由和控制器(Route and Controller)

繼續之前,請先確定你已經讀完「Symfony4.2入門教學【第一篇】安裝」(原文)這篇文章,且可以用瀏覽器觀看你的Symfony應用。

架設你要建立一個頁面 - /lucky/number - 會亂數產生一個幸運數字並印在頁面上,為了達到這個目的,新建一個"Controller Class"、一個"controller"的函式(method)在class裡面。
<?php
// src/Controller/LuckyController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

class LuckyController
{
    public function number()
    {
        $number = random_int(0, 100);

        return new Response(
            'Lucky number: '.$number.''
        );
    }
}
現在你需要將這個控制器與一個可以公開存取的URL路徑(e.g. /lucky/number)連接在一起,讓使用者訪問這個頁面時能執行number()這個函式,這個連接的方式必須在檔案config/routes.yaml建立一個路由來定義。
# config/routes.yaml

# the "app_lucky_number" route name is not important yet
app_lucky_number:
    path: /lucky/number
    controller: App\Controller\LuckyController::number
就是這麼簡單!如果你已經啟動了Symfony的網頁伺服器,可以打開瀏覽器去看看:
http://localhost:8000/lucky/number
若你看到一個幸運數字印在頁面上,那就恭喜你囉!但在你跑去買樂透之前,先看看這是怎麼辦到的呢,建立頁面的兩個步驟記得嗎?
  1. 建立路由:在config/routes.yaml檔案裡,路由定義了頁面的URL要呼叫哪一個控制器,你可以在路由這一個章節學到更多,裡面也會提到如何設定參數(Variable)
  2. 建立控制器:在此建立頁面的函式,並在最後回覆一個Response的物件,你可以在控制器的章節內學到更多,裡面也會提到如何將JSON字串當作Response回傳。


註解式路由(Annotation Routes)

如果不是在YAML定義路由,取得代之,Symfony提供一個註解式(Annotation)的路由,如果要使用,請先安裝套件:
composer require annotations
你可以直接在控制器的函式上方定義路由:
// src/Controller/LuckyController.php

// ...
use Symfony\Component\Routing\Annotation\Route;

class LuckyController
{
   /**
    * @Route("/lucky/number")
    */
    public function number()
    {
        // this looks exactly the same
    }
}
是不是很簡單呢!這個頁面 -http://localhost:8000/lucky/number- 功能就跟之前一樣,Annotations絕對是個備受推薦的路由設定方法。


Auto-Installing Recipes with Symfony Flex

你可能還沒有發現,當你執行composer require annotations這個指令時,發生了兩件神奇的事情,這都是多虧了強大的Composer插件 Flex

首先,annotations並非套件真正的名稱,而是一個別名(alias)(i.e. 捷徑shortcut),是由Flex解析成實際的套件sensio/framework-extra-bundle

第二,當這個套件完成下載後,Flex會自動執行食譜(Recipe),所謂食譜就是一連串指令去告訴Symfony如何統整這些外部套件。Flex食譜使得許多套件能辦到更多事情,像是新增設定檔、新增目錄、更新.gitignore,以及在.env新增設定,Flex讓安裝自動化,這麼以來你就可以專注在寫程式上。

你可以參考"Using Symfony Flex to Manage Symfony Applications"了解更多資訊,不過既然你安裝新的套件時,Flex會自動地在背景執行它的任務,這就不是那麼重要了!


指令 bin/console

你的專案已經內建了相當好用的除錯工具(debugging tool):指令bin/console,試著執行看看:
php bin/console
你應該會看到一堆指令,可以提供除錯資訊,可以幫你產生程式、產生資料庫遷移(database migration)等等,當你安裝更多套件時,可以接觸到更多指令。

若要取得伺服器內所有路由,請執行指令debug:router
php bin/console debug:router
你應該會看到app_lucky_number在最上面:

Name Method Scheme Host Path
app_lucky_number ANY ANY ANY /lucky/number

你也會看到一些除錯用的路由(debugging route)在app_lucky_number下面,關於除錯的路由會在下一個章節更詳細的介紹。

繼續往下學,就能了解更多指令。


除錯工具列

除錯工具列(Web Debug Toolbar)是Symfony最大的特色,當你在開發時,頁面底下在這個區域會顯示大量的有助於除錯的資訊,全都包由symfony/profiler-pack這個套件來搞定。

在頁面的最下方看到都一個黑色框框,你會慢慢更了解上面訊息代表的意思,你可以隨意試試,每個icon都可以滑過去或按按看,可以看到關於路由、效能、logging等等的資訊。


Rendering a Template

如果想要讓控制器回傳一個HTML物件,你或許會希望回應(render)一個模板。幸運的是,Symfony有Twig,這個模板語言非常簡單、強大且真的很有趣。

請確定LuckyController必須延伸(extend)Symfony的class AbstractController
// src/Controller/LuckyController.php

// ...
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class LuckyController
class LuckyController extends AbstractController
{
    // ...
}
現在,render()這個方便的函式可以回傳一個模板,給一個number的變數讓你可以在Twig中使用。
// src/Controller/LuckyController.php

// ...
class LuckyController extends AbstractController
{
    /**
     * @Route("/lucky/number")
     */
    public function number()
    {
        $number = random_int(0, 100);

        return $this->render('lucky/number.html.twig', [
            'number' => $number,
        ]);
    }
}
模板檔案放在templates/目錄裡,這個目錄在安裝Twig時會自動建立,現在建立一個新目錄templates/lucky和一個新檔案number.html.twig在目錄裡:
{# templates/lucky/number.html.twig #}

<h1>Your lucky number is {{ number }}</h1>
這個{{ number }}語句是用來在Twig裡印出參數,重新整理網頁就能看到新的幸運數字。
http://localhost:8000/lucky/number
再來你可能會疑惑,網頁的除錯工具列(the Web Debug Toolbar)是不是不見了呢?這是因為現在的模板裡缺了</body>這個tag,你可自已加上body,或著延伸base.html.twig,裡面已經包含所有基礎的HTML元件。

建立及使用模板的文章內,你可以如何寫迴圈、render其他模板和利用其強大的佈局繼承系統。


查看專案架構

有個好消息,就是你已經實際操作過專案中最重要的目錄:

config/
當然是包含了設定檔,你可以設定路由、服務(services)和套件。

src/
所有的PHP程式碼都放在這裡。

templates/
所有Twig模板存放的位置。

大部分的情況下,你只會用到src/templates/config/,繼續看下去就可以更加了解這幾個目錄各別的用途。

bin/
大名鼎鼎的bin/console就在這裡,還有一些其他執行檔(executable files)。

var/
這裡的檔案都是自動產生存在這裡,像是暫存(cache)檔案(var/cache/)和log(var/log/)。

vendor/
第三方函式庫的位置,用Composer安裝的套件會自動載到這邊。

public/
這是你專案的根目錄,任何可以開放存取的檔案可以放在這裡。

當你安裝新的套件時,如果有需要會自動建立新的目錄。


下一步

恭喜你!你已經掌握Symfony,並學到如何建立一個架構優雅、具功能的、快速的、便於維護的全新方法。

好的,是時候來看看這些文章掌握基礎知識:
接著,其他一些重要的主題也值得一學,像是service container, the form system, using Doctrine (if you need to query a database)等等。

Have fun!


文章原文:
https://symfony.com/doc/4.2/page_creation.html

系列文章:

Symfony4.2入門教學【第一篇】安裝


你更傾向影片教學?查看教學影片

建立新的Symfony應用,首先請確認你使用PHP 7.1或更高的版本,並安裝composer。如果還沒,請先在系統上安裝composer,如果想要使用虛擬機器(Virtual Machine, VM),請查看Homestead

建立新的專案執行指令:
composer create-project symfony/website-skeleton my-project

這將會建立一個新的my-project目錄,在裡面下載一些相依套件,並產生你所需的基本資料夾和檔案。換句話說,你的應用程式已經準備好了。

website-skeleton。如果你想要建立規模小一點的服務,例如console applications或APIs,可以考慮使用更簡易的skeleton專案。
composer create-project symfony/skeleton my-project

# optional: install the web server bundle (explained next)
cd my-project
composer require symfony/web-server-bundle --dev


執行Symfony應用

在正式環境,我們應該利用網頁伺服器軟體,如Nginx或Apache(參考如何使用網頁伺服器),但在開發環境時,使用Symfony的PHP網頁伺服器是更方便的方法。

進到新專案的目錄下,啟動伺服器:
cd my-project
php bin/console server:run

打開瀏覽器輸入http://localhost:8000/,如果一切順利的話,就會看到預設的首頁。稍後,如果你開發工作告一段落,請可以在終端機按Ctrl+C來關閉伺服器。

如果你在啟動Symfony專案遇到問題,有可能你的系統缺少一些必要的安裝,可以使用工具Symfony Requirements Checker,來確認系統已經準備完畢。

如果你使用的是VM,你可以透過執行下面指令,讓伺服器綁定(bind)所有IP位址:
php bin/console server:start 0.0.0.0:8000
目錄可以透過網路存取的情況下,這台機器不建議接收所有介面(listen to all interfaces)。


用git管理專案

就像多數的程式專案一樣,你可以將專案儲存到像是GitHub、GitLab和Bitbucket的服務上。用指令Git初始本地端儲存庫(Repository),你就可以將程式推(push)到遠端儲存庫。
git init
git add .
git commit -m "Initial commit"
Symfony專案已經建好.gitignore的檔案,當你安裝更多套件時,系統會透過插件Flex(原文)自動去編寫、更新。


現有的Symfony專案設定方式

如果你想編寫一個現有Symfony專案,你只要先取得這個專案,再用composer安裝所需的套件。假設你的工作團隊有使用Git,可以用下面的指令來建立你的專案:
# clone the project to download its contents
cd projects/
git clone ...

# make Composer install the projects dependencies into vendor/
cd my-project/
composer install
你大概也需要檔案.env設定環境參數以符合你的系統需求,或另外做一些專案特有的項目(像是建立資料庫schema)。當你第一次編寫一個現有的Symfony專案,執行下面的指令會顯示這個應用的相關資訊,對你可能會有很大的幫助:
php bin/console about


確認安全漏洞

Symfony提供"Security Checker"這個工具,能確認你的專案相依套件中是否有任何已知的安全漏洞,請查看Security Checker的說明來建置。


The Symfony Demo Application

The Symfony Demo Application完整展現了最合適、推薦的開發方式,是一個功能齊全的應用,在程式碼也有相應的註解和有用的建議,對於Symfony的初學者能當作很好的學習工具。

想要查看程式碼並在本機端建立這個專案,請參考symfony/symfony-demo


開始寫程式

前置作業都完成了,就可以馬上開始建立第一個頁面(原文)囉!


文章原文:
https://symfony.com/doc/4.2/setup.html

系列文章:

2019年2月10日 星期日

[Symfony] ubuntu18安裝symfony 4.2教學


上次寫的這篇「[Symfony] Ubuntu16+PHP7 安裝Synfony3.4」,是用指令 symfony 新建專案,例如 symfony new my_project 3.4 會建立一個版本3.4的專案,不過最新的4.2沒辦法用這個方法,因此誕生了這篇文章,另外作業系統也改用ubuntu18囉!

一、安裝php及相關套件
安裝php(>=7.1.3),ubuntu18內建為7.2。[版本需求]
sudo apt install php

這邊的套件則是symfony專案所需
php-xml php-curl php-mbstring php-zip unzip

二、安裝composer
安裝方法在這邊寫得很詳細,如果是作業系統是windows也有說明,下面則是整理了ubuntu的安裝方法,二擇一即可。(目前是v1.8.3)

[方法一]
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

WARNING: Please do not redistribute the install code. It will change with every version of the installer. Instead, please link to this page or check how to install Composer programmatically.
這一段話是要提醒[方法一]可能會因為版本更新而改變,如果想要安裝最新版本的composer的話,會建議直接到官方這個頁面查看指令,或者使用[方法二],也就是腳本(script)來執行。

[方法二]
開一個新的空白檔案install.sh,增加執行(x)權限。
touch install.sh
chmod +x install.sh

install.sh的檔案內容
#!/bin/sh

EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"

if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
    >&2 echo 'ERROR: Invalid installer signature'
    rm composer-setup.php
    exit 1
fi

php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
exit $RESULT

接著只要執行就可以了,如果成功的話應該不會看到任何訊息,沒有消息就是好消息XD
./install.sh

這個方法可以直接安裝最新的composer,想參考更完整的說明可以看這邊

兩個方法二擇一完成之後,這時候目前的目錄下應該會有一個composer.phar的檔案,執行下面的指令,接著就可以直接在全域使用composer。
sudo cp composer.phar /bin/composer

三、新建symfony專案
建立一個名字為my-project的新專案,如果前面的步驟確實的話,會自動執行composer install完成所有的安裝。
composer create-project symfony/website-skeleton my-project

可以來看看專案囉!
cd my-project/
php bin/console server:run
預設為http://127.0.0.1:8000,打開瀏覽器看到畫面就算大功告成了!





如果安裝遇到問題,可以利用下面的方法確認。
composer require symfony/requirements-checker

這時候專案目錄public內會多一個check.php的檔案,可以打開http://127.0.0.1:8000/check.php確認可能的問題在哪,參考畫面如下:


當你排除上面所說的問題後,可以用指令來移除check.php等相關的檔案,以防透漏不必要或機密的資運給網站的訪客。
composer remove symfony/requirements-checker

參考資料:
https://symfony.com/doc/current/setup.html
https://symfony.com/doc/current/reference/requirements.html