CodeIgniter 4로 블로그 만들기 #16 — 플래시 메시지와 삭제 확인
지난 두 회차에서 글 수정과 삭제를 완성했습니다. 기능은 다 돌아가는데, 써 보면 한 가지가 허전합니다. 글을 등록하거나 삭제해도 화면이 말없이 목록으로 넘어갈 뿐, "잘 됐어요"라는 신호가 없습니다.
이번 회차에서 이 마무리 손질을 합니다. 세션 플래시데이터로 "글이 삭제되었습니다" 같은 1회성 안내를 남기고, 공통 레이아웃에서 한 곳에 모아 출력합니다. 덤으로 되돌릴 수 없는 삭제에는 확인 문구를 좀 더 분명하게 다듬습니다.
이번 회차의 목표
- 글 등록/수정/삭제 성공 시 세션 플래시데이터로 성공 메시지를 남긴다.
- 공통 레이아웃(
layouts/default)에 플래시 메시지 출력 영역을 한 번만 만든다. - 삭제 확인 문구를 "되돌릴 수 없다"는 경고로 강화한다.
- 플래시 알림용
.flash스타일을 추가해 디자인 일관성을 지킨다.
1. 플래시데이터란
CI4의 세션에는 플래시데이터(flashdata) 라는 개념이 있습니다. 이름 그대로 "번쩍" 하고 한 번만 보이는 값입니다. 다음 요청에서 딱 한 번 읽히고 자동으로 사라집니다.
글 삭제 흐름을 떠올려 보세요. delete()는 삭제 후 목록으로 리다이렉트합니다. 리다이렉트는 곧 브라우저의 새 요청이라, 컨트롤러가 들고 있던 변수는 다 날아갑니다. 그런데 "삭제되었습니다"라는 말은 목록 화면(다음 요청)에서 보여 줘야 합니다. 요청 하나를 건너뛰어 값을 전달하되, 한 번 쓰고 버리는 것 — 이게 정확히 플래시데이터가 하는 일입니다.
2. 컨트롤러 — 리다이렉트에 메시지 얹기
redirect()->with('message', '...')를 쓰면 리다이렉트 응답에 플래시데이터를 실을 수 있습니다. 성공하는 세 지점에 한 줄씩 붙입니다.
먼저 create()의 성공 리턴을 바꿉니다.
// 저장 성공 시: 목록으로 이동하며 플래시 메시지를 남긴다.
return redirect()->to('posts')->with('message', '글이 등록되었습니다.');
update()의 성공 리턴.
// 수정 성공 시: 해당 글 상세로 이동하며 플래시 메시지를 남긴다.
return redirect()->to('posts/' . $post->slug)->with('message', '글이 수정되었습니다.');
delete()의 성공 리턴.
$model->delete($id);
return redirect()->to('posts')->with('message', '글이 삭제되었습니다.');
->with('message', ...)가 하는 일은 session()->setFlashdata('message', ...)와 같습니다. 리다이렉트 헬퍼가 체이닝으로 간결하게 감싸 준 것뿐입니다. 이렇게 세 동작 모두 message라는 같은 키로 통일해 두면, 출력하는 쪽은 한 군데만 만들면 됩니다.
3. 레이아웃 — 한 곳에서 출력
세 컨트롤러가 저마다 다른 화면(목록, 상세)으로 리다이렉트하지만, 모두 같은 레이아웃 layouts/default를 확장합니다. 그래서 출력 코드는 레이아웃 한 곳에만 두면 어느 화면으로 가든 메시지가 보입니다.
app/Views/layouts/default.php의 <main> 안, 콘텐츠 섹션 바로 위에 넣습니다.
<main class="container">
<?php // 직전 요청에서 남긴 1회성 플래시 메시지(성공 알림 등)를 보여 준다. ?>
<?php if (session()->getFlashdata('message') !== null): ?>
<div class="flash"><?= esc(session()->getFlashdata('message')) ?></div>
<?php endif ?>
<?= $this->renderSection('content') ?>
</main>
session()->getFlashdata('message')로 플래시 값을 읽습니다. 값이 있으면(!== null) .flash 박스로 출력하고, 없으면 아무것도 그리지 않습니다. esc()로 감싸는 것도 잊지 마세요 — 메시지는 지금 우리가 정한 고정 문구지만, 출력은 습관적으로 이스케이프하는 게 안전합니다.
플래시데이터의 성질상 이 값은 한 번 읽히면 사라집니다. 사용자가 목록에서 다른 페이지로 이동하거나 새로고침하면 메시지는 더는 뜨지 않습니다. "삭제 직후 딱 한 번만 알려 준다"는 우리가 원하던 동작이 별도 코드 없이 그대로 이뤄집니다.
4. 삭제 확인 문구 강화
삭제는 되돌릴 수 없는 작업입니다. ep15에서 붙였던 확인창 문구를 더 분명하게 손봅니다. app/Views/posts/show.php의 삭제 폼에서 confirm() 문구만 바꿉니다.
<?php // 삭제는 되돌릴 수 없으므로 제출 직전에 한 번 더 확인한다. ?>
<form action="<?= site_url('posts/' . $post->id . '/delete') ?>" method="post"
onsubmit="return confirm('삭제하면 되돌릴 수 없습니다. 정말 삭제하시겠습니까?');" style="display:inline">
"정말 삭제하시겠습니까?"에서 "삭제하면 되돌릴 수 없습니다." 라는 경고를 앞에 붙였습니다. 작은 차이지만, 파괴적인 동작 앞에서는 결과를 미리 알려 주는 게 좋은 습관입니다.
5. 플래시 스타일 추가
.flash 박스가 다른 화면 요소와 튀지 않도록 CSS를 더합니다. public/assets/css/app.css에 폼 에러 스타일 근처에 한 줄을 넣습니다.
/* flash message (1회성 성공 알림) */
.flash { padding: 12px 16px; border-radius: var(--radius); margin-bottom: 20px; font-size: 14px; background: var(--color-accent-soft); color: var(--color-accent); }
색은 ep03에서 정의한 디자인 토큰(--color-accent-soft 배경, --color-accent 글자)을 그대로 씁니다. 위험을 알리는 붉은 계열의 폼 에러(.form-errors)와 달리, 성공 알림은 은은한 강조색을 써서 "잘 됐다"는 긍정 신호를 줍니다.
핵심 개념 — 왜 이렇게 하는가
하나. 리다이렉트 사이로 값을 전달하는 정석. PRG(Post/Redirect/Get) 패턴에서는 저장 후 반드시 리다이렉트를 합니다(새로고침 시 재전송 방지). 이 리다이렉트를 건너 "방금 뭘 했다"를 다음 화면에 알리는 표준 도구가 플래시데이터입니다. 쿼리스트링에 메시지를 붙이거나 일반 세션에 넣고 직접 지우는 것보다 훨씬 깔끔합니다.
두울. 출력은 한 곳에. 성공 지점은 셋(등록·수정·삭제)이지만 메시지 키를 message로 통일했기에, 출력은 레이아웃 한 군데면 충분합니다. 나중에 다른 기능이 성공 메시지를 남겨도 같은 키만 쓰면 코드를 손댈 필요가 없습니다. DRY의 작은 실천입니다.
세엣. 파괴적 동작엔 마찰을 준다. 삭제 확인창은 사용자를 귀찮게 하려는 게 아니라, 실수로 인한 손실을 막는 안전장치입니다. 되돌릴 수 없는 만큼, 결과를 명확히 알리고 한 번 멈춰 세우는 게 옳습니다.
마무리 — 커밋과 태그
이번 회차에서 한 일:
create()/update()/delete()의 성공 리다이렉트에->with('message', ...)- 레이아웃에
getFlashdata('message')출력 영역 추가 - 삭제 확인 문구를 "되돌릴 수 없다"로 강화
.flash스타일로 디자인 일관성 유지
git add .
git commit -m "feat: 플래시 메시지와 삭제 확인"
git tag ep16
이걸로 섹션 4의 글 작성 CRUD가 거의 마무리됩니다. 검증·CSRF·권한·안내까지, 실전에서 필요한 조각이 얼추 다 모였습니다.
다음 회차
다음 글에서는 섹션 4의 마지막인 slug 기반 URL과 테스트 정리를 합니다. 지금까지 컨트롤러가 임시로 post-랜덤값 같은 slug를 만들어 채워 왔는데, 이걸 제목으로부터 자동 생성하도록 PostModel의 beforeInsert/beforeUpdate 콜백으로 옮깁니다. 한국어 제목까지 다루는 slug 정책과, 중복 slug에 -2, -3을 붙이는 처리, 그리고 자동 slug에 맞춰 기존 테스트를 손보는 작업까지 이어집니다.
이번 회차 요약
- 다루는 파일:
app/Controllers/Posts.php(성공 시->with('message', ...)) /app/Views/layouts/default.php(getFlashdata출력) /app/Views/posts/show.php(삭제 확인 문구) /public/assets/css/app.css(.flash)- 핵심: 플래시데이터는 다음 요청에서 한 번만 읽히고 사라진다. 리다이렉트 사이로 성공 알림을 전달하는 표준 도구. 키를
message로 통일해 출력은 레이아웃 한 곳에만.
댓글 0
아직 댓글이 없습니다.