symfony簡単なチュートリアル振り返り(Controller部分)

以下、メモです。

MainController.php

名前空間のインポートなどは割愛。

indexメソッド

ブログの一覧表示を行う機能を実装。

/**
     * @Route("/",name="app_main_index")
     *
     * @param BlogRepository $blogRepository
     *
     * @return Response
     */
    public function index(BlogRepository $blogRepository)
    {
        return $this->render('list.html.twig', ['blogs' => $blogRepository->findAll()]);
    }

ブログの一覧を表示するためのメソッド。@Route("/",name="app_main_index")アノテーションにより、アプリケーションのルートURL(例:http://yourwebsite.com/)にアクセスしたときにこのメソッドが呼び出される。BlogRepositoryを引数として受け取り、そのfindAllメソッドを使ってすべてのブログエントリを取得。取得したブログエントリはTwigテンプレートエンジンを使ってlist.html.twigテンプレートに渡され、ブラウザに表示される。

createBlogメソッド

ブログの新規作成を行う機能を実装。

/**
     * @Route("/create")
     *
     * @param Request $request
     *
     * @return Response
     */
    public function createBlog(Request $request, EntityManagerInterface $entityManager, SluggerInterface $slugger)
    {
        $form = $this->createForm(BlogFormType::class, new Blog());

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
          $blog = $form->getData();
          $imageFile = $form->get('imageFile')->getData();
          if ($imageFile) {
              $originalFilename = pathinfo($imageFile->getClientOriginalName(), PATHINFO_FILENAME);
              $safeFilename = $slugger->slug($originalFilename);
              $newFilename = $safeFilename.'-'.uniqid().'.'.$imageFile->guessExtension();

              try {
                  $imageFile->move(
                      $this->getParameter('image_directory'),
                      $newFilename
                  );
              } catch (FileException $e) {
                  $this->addFlash('error', 'Image cannot be saved.');
              }
              $blog->setImage($newFilename);
          }

          $entityManager->persist($blog);
          $entityManager->flush();
          $this->addFlash('success', 'ブログを作成しました!');

          return $this->redirectToRoute('app_main_index');
        }

        return $this->render('create.html.twig', [
          'form' => $form->createView()
        ]);

    }

これは新しいブログエントリを作成するためのメソッド。@Route("/create")アノテーションにより、アプリケーションの/create URL(例:http://yourwebsite.com/create)にアクセスしたときにこのメソッドが呼び出される。このメソッドはRequestオブジェクト、EntityManagerInterface、およびSluggerInterfaceを引数として受け取る。RequestオブジェクトはHTTPリクエストの情報を含みEntityManagerInterfaceはデータベース操作を行うためのオブジェクトで、SluggerInterfaceは文字列をURLフレンドリーな形式に変換するためのオブジェクト

createBlogメソッドでは、まずBlogFormTypeというフォームクラスを使ってフォームを作成。次に、handleRequestメソッドを使ってリクエストデータをフォームにバインド。フォームが送信され、そのデータが有効であることが確認されたら、フォームからブログエントリのデータを取得し、画像ファイルがアップロードされている場合はそのファイルを保存。最後に、ブログエントリをデータベースに保存し、成功メッセージをフラッシュに追加し、ユーザーをブログの一覧ページにリダイレクトする。

※URLフレンドリーな形式とは・・・URL(ウェブアドレス)に適している形式のことを。具体的には、以下のような特性を持つ文字列:

  1. ASCII文字のみ: URLはASCII文字セットのみをサポートしている。これには英数字(a-z、A-Z、0-9)と一部の記号(-、_、.、~)が含まれる。その他の文字(例えば日本語の文字や特殊記号)はURLエンコードという手法を用いてこれらのASCII文字に変換する必要がある。
  2. スペースなし: URLにはスペースを含めることができない。スペースは通常、ハイフン(-)やアンダースコア(_)で置き換えられる。
  3. 小文字化: URLは大文字と小文字を区別するため、一貫性を保つためにすべて小文字にすることが一般的。
  4. 特殊文字の除去または置換: URLには一部の記号しか含めることができないため、その他の記号は除去されるか、適切な文字に置き換えられる。

SluggerInterfaceは、これらのガイドラインに従って文字列を”スラッグ”(URLフレンドリーな文字列)に変換するためのツール。例えば、ブログのタイトルをURLの一部として使用する場合、SluggerInterfaceを使用してタイトルをスラッグに変換できる。これにより、ブログのタイトルがURLとして適切に機能し、ウェブブラウザで正しく解釈される。

editBlogメソッド

既存のブログを編集する機能。

/**
     * @Route("/edit/{id}", name="app_main_editBlog")
     *
     * @ParamConverter("blog", class="App\Entity\Blog")
     *
     * @return Response
     */
    public function editBlog($id, Request $request, EntityManagerInterface $entityManager, SluggerInterface $slugger)
    {
        $blog = $entityManager->getRepository(Blog::class)->find($id);
        $form = $this->createForm(BlogFormType::class, $blog);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $blog      = $form->getData();
            $imageFile = $form->get('imageFile')->getData();
            if ($imageFile) {
                $originalFilename = pathinfo($imageFile->getClientOriginalName(), PATHINFO_FILENAME);

                $safeFilename = $slugger->slug($originalFilename);
                $newFilename  = $safeFilename.'-'.uniqid().'.'.$imageFile->guessExtension();

                try {
                    $imageFile->move(
                            $this->getParameter('image_directory'),
                            $newFilename
                        );
                } catch (FileException $e) {
                    $this->addFlash('error', 'Image cannot be saved.');
                }
                $blog->setImage($newFilename);
            }

            $entityManager->persist($blog);
            $entityManager->flush();
            $this->addFlash('success', 'ブログを更新しました!');
            return $this->redirectToRoute('app_main_index');
        }

        return $this->render('create.html.twig', [
            'form' => $form->createView(),
        ]);
    }

このメソッドは、既存のブログエントリを編集するためのもの。@Route("/edit/{id}", name="app_main_editBlog")アノテーションにより、/edit/{id}の形式のURL(例:http://yourwebsite.com/edit/123)にアクセスしたときにこのメソッドが呼び出される。ここで、{id}は編集したいブログエントリのIDを表す。

このメソッドでは、まず指定されたIDのブログエントリをデータベースから取得。次に、そのブログエントリを元にBlogFormTypeというフォームを作成。その後、リクエストデータをフォームにバインドし、フォームが送信され、そのデータが有効であることを確認。データが有効であれば、フォームからブログエントリのデータを取得し、画像ファイルがアップロードされている場合はそのファイルを保存。最後に、ブログエントリをデータベースに保存し、成功メッセージをフラッシュに追加し、ユーザーをブログの一覧ページにリダイレクト。

deleteBlogメソッド

ブログを削除する機能を実装。

/**
     * @Route("/delete/{id}", name="app_blog_delete")
     *
     * @param Blog                   $blog
     * @param EntityManagerInterface $em
     *
     * @return RedirectResponse
     */
    public function deleteBlog($id, EntityManagerInterface $em): RedirectResponse
    {
        $blog = $em->getRepository(Blog::class)->find($id);

        $em->remove($blog);
        $em->flush();
        $this->addFlash('success', 'ブログを削除しました!');

        return $this->redirectToRoute('app_main_index');
    }

:このメソッドは、既存のブログエントリを削除するためのもの。@Route("/delete/{id}", name="app_blog_delete")アノテーションにより、/delete/{id}の形式のURL(例:http://yourwebsite.com/delete/123)にアクセスしたときにこのメソッドが呼び出される。ここで、{id}は削除したいブログエントリのIDを表す。

このメソッドでは、まず指定されたIDのブログエントリをデータベースから取得。次に、そのブログエントリをデータベースから削除し、成功メッセージをフラッシュに追加。最後に、ユーザーをブログの一覧ページにリダイレクトする。

【補足:routing】アノテーションではうまく実装できずにroutes.yamlで定義

アノテーションではうまくルーティングが通らなかったため(原因は分かっていないです)、一旦routes.yamlでルーティングを設定することに。

index:
    path: /
    controller: App\Controller\MainController::index

create:
    path: /create
    controller: App\Controller\MainController::createBlog

app_main_createblog:
    path: /create
    controller: App\Controller\MainController::createBlog

app_main_index:
    path: /
    controller: App\Controller\MainController::index

app_main_editblog:
    path: /edit/{id}
    controller: App\Controller\MainController::editBlog
    requirements:
      id: \d+

app_blog_delete:
    path: /delete/{id}
    controller: App\Controller\MainController::deleteBlog
    requirements:
      id: \d+

【参考サイト】

上記のサイトを基本的になぞりながら、一部コードを変更したりしながら進めました。プロジェクト全体をGithubに置いてくれていたのでそれで全体像を確認したり、あとは公式サイトやその他サイトをググったりしながら完成。

この記事を書いた人