ثبت پست‌ها در پایگاه داده

Registering Posts in the Database

25 بهمن 1399
پروژه ساخت شبکه ی اجتماعی: ثبت پست ها در پایگاه داده

در جلسه قبل فرم HTML خود را برای پست نویسی تکمیل کردیم، حالا نوبت به نوشتن کدهای سمت سرور برای INSERT شدن در پایگاه داده است. برای شروع به فایل Posts.php از پوشه controllers بروید تا در تابع add شروع به کدنویسی کنیم. در حال حاضر  تنها کاری که تابع add انجام می دهد نمایش فرم است بنابراین باید مانند بقیه فرم ها چک کنیم تا ببینیم درخواست ارسالی به این صفحه از نوع POST است یا خیر.

if($_SERVER['REQUEST_METHOD'] == 'POST'){
        // Sanitize POST array
        $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

        $data = [
          'title' => trim($_POST['title']),
          'body' => trim($_POST['body']),
          'user_id' => $_SESSION['user_id'],
          'title_err' => '',
          'body_err' => ''
        ];

      } else {
        $data = [
          'title' => '',
          'body' => ''
        ];
  
        $this->view('posts/add', $data);
      }

توضیح کد:

در این تابع چک می کنیم تا ببینیم آیا درخواست ارسالی POST (از سمت فرم) بوده است یا خیر. در صورتی که از سمت فرم نبود view فرم را بارگذاری می کنیم و در صورتی که POST بود می گوییم داده ها را پاک سازی کن (تابع filter_input_array) و سپس مقادیر فرم را درون اعضای data$ قرار بده. در آخر هم id کاربر را از Session مربوطه اش می گیریم و اعضایی برای خطاها (مانند خالی بودن) ایجاد می کنیم.

حالا باید کدهای زیر را نیز به این قسمت اضافه کنیم:

// Validate data
        if(empty($data['title'])){
          $data['title_err'] = 'Please enter title';
        }
        if(empty($data['body'])){
          $data['body_err'] = 'Please enter body text';
        }

        // Make sure no errors
        if(empty($data['title_err']) && empty($data['body_err'])){
          // Validated
          if($this->postModel->addPost($data)){
            flash('post_message', 'Post Added');
            redirect('posts');
          } else {
            die('Something went wrong');
          }
        } else {
          // Load view with errors
          $this->view('posts/add', $data);
        }

توضیح کد:

ابتدا چک کرده ایم که مقادیر title و body خالی نباشند. در صورتی که خالی باشند به title_err یا body_err یک پیام خطا می دهیم. سپس چک می کنیم تا هر دو مقدار err و body_err خالی باشند؛ در این صورت یعنی هیچ خطایی وجود ندارد و ما باید فرم را ثبت کنیم. برای ثبت پست نیز آن را به تابعی به نام addPost داده ایم که بعدا تعریف خواهیم کرد. سپس با استفاده از تابع کمکی که قبلا تعریف کرده بودیم (flash) یک پیام را به مخاطب نمایش می دهیم و او را به صفحه پست ها redirect می کنیم. در غیر این صورت پیام Something went wrong را به کاربر نمایش می دهیم و view را با خطاهای موجود دوباره بارگذاری می کنیم.

حالا به پوشه models و فایل post.php بروید تا تابع addPost را تعریف کنیم:

public function addPost($data){
      $this->db->query('INSERT INTO posts (title, user_id, body) VALUES(:title, :user_id, :body)');
      // Bind values
      $this->db->bind(':title', $data['title']);
      $this->db->bind(':user_id', $data['user_id']);
      $this->db->bind(':body', $data['body']);

      // Execute
      if($this->db->execute()){
        return true;
      } else {
        return false;
      }
    }

کوئری ما بسیار ساده است؛ گفته ایم مقادیر title, user_id, body را وارد جدول posts کن. سپس مانند دفعات قبل و با استفاده از توابعی که نوشتیم (توابع query و bind) کوئری را آماده اجرا می کنیم. در آخر نیز با استفاده از دستور execute کوئری اجرا می شود و اگر مشکلی نداشت به ما true را برمی گرداند.

حالا به پوشه views>posts و فایل index.php بروید و پیام flash را بالای صفحه بگذارید:

<?php require APPROOT . '/views/inc/header.php'; ?>
  <?php flash('post_message'); ?>
  <div class="row mb-3">
    <div class="col-md-6">
      <h1>Posts</h1>

تا اینجای کار باید به راحتی بتوانیم پست های خود را بنویسیم و در صفحه index مربوطه مشاهده کنیم.

حالا نوبت به نوشتن کدهای دکمه more است. اگر موس خود را روی دکمه more ببرید میبینید که دارای دارای لینکی به شکل localhost/shareposts/posts/show/2 یا چنین چیزی است. عدد آخر این لینک همان id پست ما است و ما می خواهیم با استفاده از آن با دکمه more کار کنیم.

وارد پوشه controller و فایل Posts.php را باز کنید. سپس پایین تر از تابع add تابع جدیدی به نام show ایجاد کنید. اگر یادتان باشد فریم ورک خود را طوری نوشته ایم که با URL کار کند. به طور مثال قسمت posts از آدرس localhost/shareposts/posts/show/2 به کنترلر posts ارسال می شود به همین دلیل است که تابع show را در Posts.php مینویسیم. اگر از جلسات اولیه یادتان باشد بعد از show که متد ما بود هر چه بیاید id خواهد بود. بنابراین اگر آدرس فرضی localhost/shareposts/posts/show/2 را داشته باشیم عدد 2 می شود id ما.

با همین منطق تابع show را می نویسیم و به آن پارامتری به نام id$ می دهیم:

public function show($id){

      $data = [
      ];

      $this->view('posts/show', $data);
    }

فعلا تابع را به همین شکل رها می کنیم تا اول فایل show.php را در پوشه views>posts ایجاد کنیم. داخل این فایل header و footer را بارگذاری کنید و با سلیقه خودتان کدهای HTML این قسمت را بنویسید. فعلا برای تست این کدها را وارد کنید:

<?php require APPROOT . '/views/inc/header.php'; ?>
<a href="<?php echo URLROOT; ?>/posts" class="btn btn-light"><i class="fa fa-backward"></i> Back</a>
<?php require APPROOT . '/views/inc/footer.php'; ?>

حالا اگر روی دکمه more کلیک کنیم باید به صفحه ای دیگر منتقل شویم که یک دکمه back داشته باشد. زمانی که این اتفاق افتاد مطمئن می شویم که کار درست پیش می رود.

به فایل Posts.php برگردید. برای تابع show از متدی به نام getPostById استفاده می کنیم:

public function show($id){
      $post = $this->postModel->getPostById($id);

      $data = [
      ];

      $this->view('posts/show', $data);
    }

حالا به فایل Post.php در پوشه models بروید تا متد getPostById را تعریف کنیم. پایین تر از تابع addPost این تابع را بدین شکل تعریف می کنیم:

public function getPostById($id){
      $this->db->query('SELECT * FROM posts WHERE id = :id');
      $this->db->bind(':id', $id);

      $row = $this->db->single();

      return $row;
    }

کوئری بسیار ساده است. Id پست را می گیریم (از URL با دکمه More می آید) و با استفاده از دستور SELECT آن را دریافت می کنیم تا نمایش داده شود. به Posts.php برگردید و این ردیف برگشتی را به data بدهید:

public function show($id){
      $post = $this->postModel->getPostById($id);

      $data = [
        'post' => $post,
      ];

      $this->view('posts/show', $data);
    }

حالا باید اطلاعات کاربر را نیز بگیریم اما model مربوط به user را بارگذاری نکرده ایم بنابراین در بالای فایل Posts.php و درون constructor این کار را انجام می دهیم:

$this->userModel = $this->model('User');

سپس در پایین صفحه و درون تابع show کد زیر را اضافه می کنیم:

$user = $this->userModel->getUserById($post->user_id);

اکنون می توانیم user را نیز به data اضافه کنیم. تا تابع به این شکل در بیاید:

public function show($id){
      $post = $this->postModel->getPostById($id);
      $user = $this->userModel->getUserById($post->user_id);

      $data = [
        'post' => $post,
        'user' => $user
      ];

      $this->view('posts/show', $data);
    }

حالا به صفحه User.php در پوشه models می رویم و تابع getUserById را تعریف می کنیم تا متغیر user$ در آرایه data معنی پیدا کند:

// Get User by ID
    public function getUserById($id){
      $this->db->query('SELECT * FROM users WHERE id = :id');
      // Bind value
      $this->db->bind(':id', $id);

      $row = $this->db->single();

      return $row;
    }

این هم از اطلاعات کاربر. روش انجام این کار دقیقا مانند دریافت پست ها است.

حالا می توانیم به فایل Show.php برویم و کدهای HTML را تکمیل کنیم. شما می توانید با سلیقه خودتان این کدها را تغییر دهید:

<?php require APPROOT . '/views/inc/header.php'; ?>
<a href="<?php echo URLROOT; ?>/posts" class="btn btn-light"><i class="fa fa-backward"></i> Back</a>
<br>
<h1><?php echo $data['post']->title; ?></h1>
<div class="bg-secondary text-white p-2 mb-3">
  Written by <?php echo $data['user']->name; ?> on <?php echo $data['post']->created_at; ?>
</div>
<p><?php echo $data['post']->body; ?></p>

<?php if($data['post']->user_id == $_SESSION['user_id']) : ?>
  <hr>
  <a href="<?php echo URLROOT; ?>/posts/edit/<?php echo $data['post']->id; ?>" class="btn btn-dark">Edit</a>

  <form class="pull-right" action="<?php echo URLROOT; ?>/posts/delete/<?php echo $data['post']->id; ?>" method="post">
    <input type="submit" value="Delete" class="btn btn-danger">
  </form>
<?php endif; ?>

<?php require APPROOT . '/views/inc/footer.php'; ?>

قسمتی که شرط ['data['post']->user_id == $_SESSION['user_id را داریم یعنی اگر پست مربوطه متعلق به کاربر است (همخوانی session و ستون user_id). دلیل این کار این است که دکمه های ویرایش یا حذف پست فقط برای صاحب همان پست نمایش داده شود و دیگر کاربران نتوانند پست های یکدیگر را ویرایش یا حذف کنند.

همچنین دلیل استفاده از form برای دکمه delete این است که میخواهیم این درخواست از طریق POST به سرور برسد نه از راه های دیگر. کد نویسی آن را در جلسات آینده انجام خواهیم داد.

دانلود فایل های پروژه تا این جلسه

در قسمت بعدی کارایی دکمه ویرایش (edit) را اضافه خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش ساخت شبکه اجتماعی توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.