PHP와 Node.js

2024. 5. 3. 21:54·🔍 Tech 🔍/Back-End

https://medium.com/@jinalg.tagline/php-vs-node-js-choosing-the-right-backend-for-your-project-1088fa7ddca9

개발에 입문할 때 처음 배웠던 프로그래밍 언어가 Javascript였기 때문에 백엔드 작업이 필요할 때 같은 문법을 사용하는  Node 환경을 사용해 왔다.

그렇기에 Java, PHP, Ruby 같은 다른 언어를 공부하거나 볼 수 있는 기회가 없었다. 하지만 현재 회사에서는 PHP를 사용했기 때문에 Flow chart 확인 및 유지보수 그리고 추후 리펙터링과 Node.js로 컨버팅 하기 위해 느꼈던 점을 작성하고자 한다.

 

1. 호출 방식

PHP

  const registerUser = () => {
    axios.post('http://localhost/register.php', registerInfo)
      .then(response => {
        console.log(response);
      })
      .catch(error => {
        console.log(error);
      });
  };

  const changeNickname = () => {
    axios.post('http://localhost/changeNickname.php', nicknameChangeInfo)
      .then(response => {
        console.log(response);
      })
      .catch(error => {
        console.log(error);
      });
  };

일반적으로 위와 같은 프론트 코드가 있을 때 PHP 파일을 직접 호출하는 방식으로 작성한다.

// register.php

<?php
// 데이터베이스 연결
$servername = "localhost";
$username = "사용자명";
$password = "비밀번호";
$dbname = "데이터베이스명";

$conn = new mysqli($servername, $username, $password, $dbname);

// 회원가입 양식에서 전송된 데이터 가져오기
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];

// 데이터베이스에 회원 정보 추가
$sql = "INSERT INTO users (username, email, password) VALUES ('$username', '$email', '$password')";

if ($conn->query($sql) === TRUE) {
  echo "회원가입이 완료되었습니다.";
} else {
  echo "Error: " . $sql . "<br>" . $conn->error;
}

$conn->close();
?>

Node.js

 const registerUser = () => {
    axios.post('http://localhost:3000/register', registerInfo)
      .then(response => {
        console.log(response);
      })
      .catch(error => {
        console.log(error);
      });
  };

  const changeNickname = () => {
    axios.post('http://localhost:3000/changeNickname', changeNicknameInfo)
      .then(response => {
        console.log(response);
      })
      .catch(error => {
        console.log(error);
      });
  };
// index.js

const express = require('express');
const mysql = require('mysql');
const bcrypt = require('bcrypt');

const app = express();
app.use(express.json());

const db = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '',
    database: 'testdb'
});

db.connect((err) => {
    if (err) throw err;
    console.log('Connected to the database.');
});

// 회원 가입
app.post('/register', (req, res) => {
    const { id, password, nickname } = req.body;
    bcrypt.hash(password, 10, (err, hash) => {
        if (err) throw err;
        db.query('INSERT INTO users SET ?', { id: id, password: hash, nickname: nickname }, (err, result) => {
            if (err) throw err;
            res.send('User registered successfully.');
        });
    });
});

// 닉네임 변경
app.post('/changeNickname', (req, res) => {
    const { id, newNickname } = req.body;
    db.query('UPDATE users SET nickname = ? WHERE id = ?', [newNickname, id], (err, result) => {
        if (err) throw err;
        res.send('Nickname changed successfully.');
    });
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

Node의 경우 파일명을 직접 호출하지 않고 Router 방식으로 호출을 하게 된다.

위 코드는 한 번에 확인하기 위한 예시 코드이고 실제론 index -> router -> controller 순서로 진행이 되며 각각 해당하는 코드를 나누어 관리하게 된다.

 

하지만 PHP도 POST의 action 필드에 원하는 요청을 담아 위 Node 예시처럼 하나의 파일에서 다른 요청을 처리할 수도 있다.

// POST 데이터 처리
$postData = json_decode(file_get_contents('php://input'), true);

if (isset($postData['action'])) {
    switch ($postData['action']) {
        case 'register':
            // 회원 가입 로직
            $id = $postData['id'];
            $password = $postData['password']; // 비밀번호는 해싱 처리 필요
            $nickname = $postData['nickname'];

            $sql = "INSERT INTO users (id, password, nickname) VALUES ('$id', '$password', '$nickname')";
            if ($conn->query($sql) === TRUE) {
                echo "New record created successfully";
            } else {
                echo "Error: " . $sql . "<br>" . $conn->error;
            }
            break;
        
        case 'changeNickname':
            // 닉네임 변경 로직
            $id = $postData['id'];
            $newNickname = $postData['newNickname'];

            $sql = "UPDATE users SET nickname='$newNickname' WHERE id='$id'";
            if ($conn->query($sql) === TRUE) {
                echo "Record updated successfully";
            } else {
                echo "Error updating record: " . $conn->error;
            }
            break;
        
        default:
            echo "Invalid action";
    }
} else {
    echo "Action not set";
}

마찬가지로 Node에서 회원가입과 닉네임 변경을 담당하는 js 파일을 각각 만들 수 도 있다.

SOLID 패턴 중 단일 책임 원칙을 따르자면 하나의 파일은 하나의 기능만 해야 하기에 PHP의 예시처럼 모두 나누어 놓아야 하나, 프로젝트 특성, 확장성, 코드 재사용성 등 여러 가지 상황을 고려해 결정해야 할 부분인 것 같다.

10잡스
https://devtechnosys.com/insights/nodejs-vs-php/

2. 모듈 사용

Node의 경우 다른 js파일을 사용할 때 module.exports + require 를 이용하여 명시적으로 모듈을 내보내고 가져오게 된다.

// math.js
const add = (a, b) => {
  return a + b;
}

const subtract = (a, b) => {
  return a - b;
}

module.exports = {
  add,
  subtract
}

// main.js
const math = require('./math');

console.log(math.add(5, 3)); // 8
console.log(math.subtract(5, 3)); // 2

PHP는 내보내는 과정이 없어도 가져오는데 문제가 없다.

// math.php
<?php
function add($a, $b) {
  return $a + $b;
}

function subtract($a, $b) {
  return $a - $b;
}
?>

// main.php
<?php
require 'math.php';

echo add(5, 3); // 8
echo subtract(5, 3); // 2
?>

 

Node (export - require)
- 명시적으로 모듈을 내보내고 가져오기 때문에 모듈 간의 의존성을 파악하기 쉽다.
- 동일한 모듈을 여러 번 가져와도 한 번만 캐싱되어 성능상 장점이 있다.

PHP
- 내보내는 과정이 없기 때문에 모듈 간의 의존성을 파악하기 어렵다.
- Node의 모듈 시스템과 달리 파일을 매번 읽어와야 하는 단점이 있다.

 

https://levelup.gitconnected.com/caching-strategies-in-node-js-improving-performance-and-efficiency-6a7fd929e165

3. 비동기 vs 동기

// Node

const fs = require('fs').promises;

async function readFileAsync() {
  try {
    const data = await fs.readFile('example.txt', 'utf8');
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

readFileAsync();

console.log('파일 읽기 요청을 기다리는 중...');
// PHP

<?php
// 파일을 동기적으로 읽어옵니다.
$data = file_get_contents('example.txt');
echo $data;

?>

 

Node의 경우 비동기 작업이 가능하기 때문에 파일을 읽어오는 동안 '기다리는 중..." 과 같은 작업을 수행할 수 있다.

반면 PHP는 동기적으로 동작하기 때문에 파일을 읽는 동안 다른 작업을 수행할 수 없다. 따라서 파일 읽기가 완료된 후에 해당 데이터가 출력된다.

 

사용자에게 직접 보여지고 UX에 신경을 많이 써야 하는 프론트 엔드 개발에선 비동기 방식을 중요하게 생각하기 때문에 같은 언어를 사용하는 Node에 영향을 준 것이 아닌가 생각한다.

무 한 로 딩

https://radixweb.com/blog/node-js-vs-php

 

Node JS vs PHP: Which Backend to Choose for Your Project in 2024?

Node JS vs PHP: which backend framework to choose in 2024? Here is a detailed comparison between NodeJS and PHP with definition, pros and cons of each!

radixweb.com

 

https://www.excellentwebworld.com/node-js-vs-php/

 

Node.Js Vs PHP: The Ultimate Winner Is Out For Backend Development

Node JS vs PHP: which backend framework? Here is a detailed comparison between NodeJS and PHP

www.excellentwebworld.com

 

'🔍 Tech 🔍/Back-End' 카테고리의 다른 글
  • Expo Node.js FCM 푸시 알림 보내기
  • Python -> Node.js 컨버팅 회고
  • PHP -> Node.js 컨버팅 회고
Yeonhub
Yeonhub
✨ https://github.com/yeonhub 📧 lsy3237@gmail.com
  • Yeonhub
    비 전공자의 Be developer
    Yeonhub
  • 전체
    오늘
    어제
    • 전체보기 (169)
      • 🔍 Tech 🔍 (19)
        • Front-End (11)
        • Back-End (4)
        • AI (1)
        • Server (1)
        • Etc (2)
      • 💡 원티드 프리온보딩 챌린지 💡 (14)
        • PRE-ONBOARDING_AI (11월) (1)
        • PRE-ONBOARDING_FE (2월) (2)
        • PRE-ONBOARDING_FE (1월) (2)
        • PRE-ONBOARDING_FE (12월) (9)
      • 🔥 부트캠프-웹 개발 🔥 (118)
        • HTML5 (7)
        • CSS3 (21)
        • JavaScript (27)
        • JavaScript_advanced (9)
        • React (24)
        • Next (1)
        • MYSql (5)
        • Node (5)
        • 오늘하날(개인프로젝트) (12)
        • 이젠제주투어(팀프로젝트) (7)
      • 💻 CS 💻 (1)
        • 알고리즘 (1)
      • ⚡ 코딩테스트 ⚡ (11)
        • JavaScript (11)
      • 📚 Books 📚 (6)
        • 클린 아키텍처 (2)
        • 인사이드 자바스크립트 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    react native analytics
    라스콘
    node fcm
    react native firebase analytics
    expo 지도
    expo 길찾기
    node.js fcm
    react native admob
    expo fcm push
    expo node fcm
    node cron
    expo google map
    컴파운드 컴포넌트 패턴
    react native expo fcm
    javascript fcm
    프론트엔드 테스트코드
    expo admob
    react native bottom sheet
    php node
    react vite
    expo map
    node crontab
    rn bottom sheet
    Node
    bottom sheet
    expo deep linking
    python node
    라스콘4
    expo fcm
    rn admob
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Yeonhub
PHP와 Node.js
상단으로

티스토리툴바