29일차

●29일차 (20250125029.php)
#미션
서버를 호스트전용어댑터로 두고 메인pc에 ci4.st.kr이 나오게해라
워크벤치를 설치하고 ci4.st.kr에 들어가라

1. 버추얼박스의 이더넷 수정
ip: 192.168.56.1
서브넷마스크: 255.255.255.0
dns: 192.168.56.102

2. 워크벤치 접속
CREATE USER 'ci4'@'192.168.56.1' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON ci4.* TO 'ci4'@'192.168.56.1';
FLUSH PRIVILEGES;

3. edit plus
#app/Config/Routes.php
------------------------------------------------------------------
$routes->match(['get', 'post'], 'news/create', 'News::create');
$routes->get('news/(:segment)', 'News::view/$1');
$routes->get('news', 'News::index');

$routes->get('pages', 'Pages::index');
$routes->get('(:segment)', 'Pages::view/$1');
------------------------------------------------------------------
> ci4.st.kr/news라고 안해도 됨(news를 1,2 라고 놔도 news/index로 들어가짐)

3-1. ci4.st.kr/news
> 404 에러가 뜸
> /App/Controllers/News::index 가 없다고 나옴
> 만들어주자

+)mvc

/App/Controllers/News.php
Home.php에서 복사해서

<?php

namespace App\Controllers;

class News extends BaseController
{
    public function index(): string
    {
        return view('news');
    }
}
> class 이름을 news로 바꿔주었다
> return view로 인해 Invalid file: "news/list.php가 뜸
> 만들어주자

/App/Views/news/list.php

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="/static/bootstrap.min.css" rel="stylesheet">
  <script src="/static/bootstrap.bundle.min.js"></script>
</head>
<body>

<div class="container mt-3">
  <h2>뉴스 목록</h2>
  <p>News:lists</p>
  <table class="table">
    <thead>
      <tr>
        <th>번호</th>
        <th>제목</th>
        <th>날짜</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>Doe</td>
        <td>john@example.com</td>
      </tr>
      <tr>
        <td>Mary</td>
        <td>Moe</td>
        <td>mary@example.com</td>
      </tr>
      <tr>
        <td>July</td>
        <td>Dooley</td>
        <td>july@example.com</td>
      </tr>
    </tbody>
  </table>
</div>

</body>
</html>
> 목록이 나옴

3-2. 데이터베이스 연결
#세팅
경로: /home/ci4/public_html
cp env .env
nano .env
environmetnt 주석 풀고 development 넣어주기
> 개발자 모드
database.default.hostname = localhost
database.default.database = ci4
database.default.username = ci4
database.default.password = 123456
database.default.DBDriver = MySQLi
database.default.DBPrefix =
database.default.port = 3306
> 주석 풀어주고 설정해줌

/App/Config/database.php
> default 부분 .env 랑 맞춰주자

#get_news 함수
> 데이터베이스를 불러올거임
Models/NewsModel.php

<?php
namespace App\Models;
use CodeIgniter\Model;

class NewsModel extends Model
{
    protected $table = 'news';
    protected $allowedFields = ['title', 'slug', 'body'];
    public function getNews($slug = false)
    {
        if ($slug === false) {
            return $this->findAll();
        }
        return $this->where(['slug' => $slug])->first();
    }
}
> 컨트롤러에서 불러야 동작
> 컨트롤러에서 모델에 있는 getNews를 부를것이다
> 슬러그 값이 없으면 모두 가져오고
> 있으면 슬러그 값 하나만 가져온다?

#모델 사용
controllers/news.php 수정

<?php

namespace App\Controllers;
use App\Models\NewsModel;
#이걸 추가해줘야 모델을 사용한다

class News extends BaseController
{
    public function index(): string
    {
        #$data = [] > 배열이다
        $model = model(NewsModel::class);

        $data = [
            'news'  => $model->getNews(),
            'title' => '뉴스 목록',
        ];
        #getnews 가져옴,
        #$data라는 배열로 담아서 하나는 타이틀, 하나는 뉴스로 보냄

        return view('news/list',$data);
        #데이터에 담은거 news로 보냄
    }
}
> model에서 get_news를 가져와서 데이터에 담아서 list로 보냄
> 리스트는 반복문!

[list.php]

<!DOCTYPE html>
<html lang="en">
<head>
  <title><?=esc($title)?></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="/static/bootstrap.min.css" rel="stylesheet">
  <script src="/static/bootstrap.bundle.min.js"></script>
</head>
<body>

<div class="container mt-3">
  <h2><?=esc($title)?></h2>
  <p>News:lists</p>
  <table class="table">
    <thead>
      <tr>
        <th>번호</th>
        <th>제목</th>
        <th>날짜</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>0</td>
        <td>Doe</td>
        <td>2025-01-25 00:00:00</td>
      </tr>
      <?php if (! empty($news) && is_array($news)): ?>
        <?php foreach ($news as $news_item): ?>

      <tr>
        <td><?= esc($news_item['idx']) ?></td>
        <td><?= esc($news_item['title']) ?></td>
        <td><?= esc($news_item['reg_date']) ?></td>
      </tr>

    <?php endforeach ?>

    <?php else: ?>
      <tr>
        <td colspan="3">데이터가 없습니다</td>
      </tr>
    <?php endif ?>
    </tbody>
  </table>
</div>

</body>
</html>
> 반복문을 만들어줌
> $news_item을 써서 데이터베이스에 있는 idx,title,reg_data를 가져와줌
> 데이터베이스에 있는 목록들이 나옴

3-3. 목록들 활성화
#/views/news/view.php

<!DOCTYPE html>
<html lang="en">
<head>
  <title><?=esc($title)?></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="/static/bootstrap.min.css" rel="stylesheet">
  <script src="/static/bootstrap.bundle.min.js"></script>
</head>
<body>

<div class="container mt-3">
  <h2><?=esc($title)?></h2>
  <p>News:view</p>
  <h2></h2>
  <div class="card">
    <div class="card-body">
        뉴스 보기<br>
        제목 :<br>
        내용 :<br>
        날짜 :<br>
        
        <hr>
        <a href="/news">목록</a> 수정 삭제
    </div>
  </div>
</div>

</body>
</html>
> ci4.st.kr/news/(숫자 or 영어)
> 이 코드대로 창이 활성화 되게끔 만들어줄거임
> controllers/news.php에 들어가서 view 함수를 추가
> 목록에 들어가면 창이 뜸

+) 플라스크(파이썬 기반 최신 프레임워크)

#링크를 걸고 데이터베이스에 연결
> 목록 하나의 데이터에도 연결

[list.php]
<td><a href="/news/<?= esc($news_item['slug']) ?>"><?= esc($news_item['title']) ?></a></td> > title에 링크를 걸어줌

idx, title, slug, body, reg_date
> 슬러그가 들어와야햠
> 불러오는 값에 들어가는 값이 영어여야 되는듯
> 아니면 링크를 걸때 숫자인 idx로 넣는것도 방법
> 숫자든 영어든 들어오면 view로 넘어감(route에서 확인)

[news.php]

    public function view($slug = null)
    {
        $model = model(NewsModel::class);
        $data['news']=$model->getNews($slug);

        if (empty($data['news'])) {
            throw new \CodeIgniter\Exceptions\PageNotFoundException('데이터'.$slug.'를 찾을 수 없습니다');
        }

        $data = [
            'news'  => $model->getNews($slug),
            'title' => '뉴스 보기',
        ];

        return view('news/view',$data);
    }
> view함수 수정
> news 배열로 get news 함수를 불러와서 데이터베이스 안에 있는
[[idx][title][slug][body][reg_date]]를 불러옴

[view.php]

제목 : <?= esc($news['title']) ?>
내용 : <?= esc($news['body']) ?>
날짜 : <?= esc($news['reg_date']) ?> 
> 추가해줌
> 목록 중 하나를 들어가면 데이터 안에 넣었던 내용들이 웹에 뜸
(news 1)
> 전 사진을 못 찍음, 링크 활성화는 안되어있는 상태
(news a)

#등록하기
[list.php]
table 닫아주는 코드 아래에 <a href="/news/create">등록</a>
> 등록란 만들어줌
(news)

[create.php]
> news 아래에 만들어줌

<!DOCTYPE html>
<html lang="en">
<head>
  <title><?=esc($title)?></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="/static/bootstrap.min.css" rel="stylesheet">
  <script src="/static/bootstrap.bundle.min.js"></script>
</head>
<body>

<div class="container mt-3">
  <h2><?=esc($title)?></h2>
  <p>News::create</p> 
  <form action="/news/create" method="post">
    <div class="mb-3 mt-3">
      <label for="title">제목</label>
      <input type="text" class="form-control" id="title" placeholder="제목 입력" name="title">
    </div>
    <div class="mb-3 mt-3">
      <label for="slug">슬러그</label>
      <input type="text" class="form-control" id="slug" placeholder="슬러그 입력" name="slug">
    </div>
    <div class="mb-3 mt-3">
      <label for="body">제목</label>
      <input type="text" class="form-control" id="title" placeholder="내용 입력" name="body">
    </div>
    <button type="submit" class="btn btn-primary">등록</button>
  </form>
  <a href="/news">목록</a>
</div>

</body>
</html>
(get)

[news.php]
글쓰기 get
등록 post

    public function create()
    {
        //echo "글쓰기 작동";
        echo $this->request->getMethod();
        $model = model(NewsModel::class);
        
        if ($this->request->getMethod() === 'POST' && $this->validate([
            'title' => 'required|min_length[3]|max_length[255]',
            'body'  => 'required',
        ])) {

            $model->save([
                'title' => $this->request->getPost('title'),
                'slug'  => url_title($this->request->getPost('title'), '-', true),
                'body'  => $this->request->getPost('body'),
            ]);

            return view('news/success');

        } else {
        $data = [
            #'news'  => $model->getNews($slug),
            'title' => '뉴스 등록',
        ];
            return view('news/create',$data);
        }              
    }
2개의 조건 만족 > 저장
> post 방식으로 보냈고 유효성 검사(제목길이, 내용유무)를 통과하면 배열로 받아서 저장하겠다
> (else) get 방식이면 입력폼으로 가라
> get 방식으로 오면 create.php 가 나옴
> post 방식으로 오면 success.php로 갈거임 (만들어줌)

[success.php]

<!DOCTYPE html>
<html lang="en">
<head>
  <title><?=esc($title)?></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="/static/bootstrap.min.css" rel="stylesheet">
  <script src="/static/bootstrap.bundle.min.js"></script>
</head>
<body>

<div class="container mt-3">
  <h2><?=esc($title)?></h2>
  <p>News:view</p>   
  <div class="card">
    <div class="card-body">
        <?=esc($title)?><br>

        제목 : <?= esc($news['title']) ?><br>
        내용 : <?= esc($news['body']) ?><br>
        날짜 : <?= esc($news['reg_date']) ?><br>
        
        <hr>
        <a href="/news">목록</a> 수정 삭제

    </div><em></em>
  </div>
</div>

</body>
</html>
(success)

전체 최종 코드
ci4.st.kr(D:2025_산대특/code)