728x90

class 를 참조하기 전 자동으로 매칭 시켜 주는 함수 

path 로 클래스를 로드 할때 유용함 

spl_autoload_register(function ($class) {
    include 'classes/' . $class . '.class.php';
});

$obj = new MyClass();

 

위의 코드에서 MyClass를 호출할 때, PHP는 spl_autoload_register에 등록된 함수를 호출하여 MyClass를 로드하려고 시도합니다. 그리고 이 함수는 classes/MyClass.class.php 파일을 포함시켜 클래스를 로드합니다.

728x90
728x90

php 코드의 숫자형, 문자형 변환 과 round 함수에 대해 알아 본다.

 

Numeric to String Conversion: 숫자형을 문자형으로

$numeric_value = 123;
$string_value = (string)$numeric_value; // Typecasting
// or
$string_value = $numeric_value . "";    // Concatenation

 

String to Numeric Conversion: 문자형을 숫자형으로

$string_value = "123";
$integer_value = intval($string_value);  // For integers
$float_value = floatval($string_value);  // For floats
// or
$integer_value = (int)$string_value;    // Typecasting for integers
$float_value = (float)$string_value;    // Typecasting for floats

 

Defining Decimal Precision: 소수잠 자리수

$float_number = 123.4567;
$formatted_number = number_format($float_number, 2); // Formats to 2 decimal places
// Output: 123.46

 

Rounding Modes: 올림, 반올림

  • PHP_ROUND_HALF_UP: Round halves up
  • PHP_ROUND_HALF_DOWN: Round halves down
  • PHP_ROUND_HALF_EVEN: Round halves to even numbers
  • PHP_ROUND_HALF_ODD: Round halves to odd numbers
$number = 10.5;
$rounded_up = round($number, 0, PHP_ROUND_HALF_UP);
$rounded_down = round($number, 0, PHP_ROUND_HALF_DOWN);
echo $rounded_up;   // Output: 11
echo $rounded_down; // Output: 10
728x90
728x90

개인정보 보안이 강화 되다 보니 db 에 데이터를 암호화 해서 보관해야 하는 경우가 있다. md5 는 복호화로 암호를 풀수는 없기 때문에 그럴때는 AES (Advanced Encryption Standard)를 사용 하는 것이 좋다. 

 

<?php
function encrypt($plaintext, $key) {
    $cipher = "aes-256-cbc"; // 암호화 알고리즘 및 모드
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
    $hmac = hash_hmac('sha256', $ciphertext_raw, $key, true); // HMAC을 생성하여 데이터 무결성 보장
    return base64_encode($iv . $hmac . $ciphertext_raw);
}

function decrypt($ciphertext, $key) {
    $cipher = "aes-256-cbc";
    $c = base64_decode($ciphertext);
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = substr($c, 0, $ivlen);
    $hmac = substr($c, $ivlen, $sha2len = 32);
    $ciphertext_raw = substr($c, $ivlen + $sha2len);
    $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, OPENSSL_RAW_DATA, $iv);
    $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, true);
    if (hash_equals($hmac, $calcmac)) { // HMAC 일치 확인
        return $original_plaintext;
    }
    return false; // HMAC이 일치하지 않으면 복호화 실패
}

// 사용 예제
$key = "my_secret_key"; // 암호화에 사용할 키
$plaintext = "Hello, world!"; // 암호화할 문자열

// 암호화
$ciphertext = encrypt($plaintext, $key);
echo "암호화된 문자열: " . $ciphertext . "\n";

// 복호화
$decrypted_text = decrypt($ciphertext, $key);
if ($decrypted_text !== false) {
    echo "복호화된 문자열: " . $decrypted_text . "\n";
} else {
    echo "복호화 실패\n";
}
?>
728x90
728x90

sass 로 스타일 작업을 많이 하는데 php 에서는 바로 link 를 할수가 없다. css 파일로 컴파일 후 link 해야 하는데 php 명령어로도 컴파일이 가능하다. 아래 명령어로 해당 경로에 css 파일을 생성하게끔 한다면 php 코드에서도 sass 파일을 사용 할수 있다. 

<?php
// SASS 파일의 경로
$sass_file = 'styles.scss';

// 컴파일된 CSS 파일의 경로
$css_file = 'styles.css';

// SASS 파일을 CSS로 컴파일하는 명령
$command = "sass $sass_file $css_file";

// 명령 실행
$output = shell_exec($command);

// 결과 출력
echo $output;
?>
728x90
728x90

form 태그를 넘길때 $_POST 로 받는 다고 가정 할때 값이 없을때 오류가 날 수 있으므로 존재 여부를 먼저 isset 로 체크해 준다. 다중 체크박스를 ques_1[] 로 선언 했을 경우 아래 예제 처럼 || 로 값을 모두 implode 로 합쳐서 db에 저장하고 explode 로 배열로 반환 받을 수 있다. 

$num = 1; // 예제로 1로 설정, 실제로는 필요한 값에 따라 변경

if (isset($_POST["ques_" . $num]) && $_POST["ques_" . $num] !== "") {
    $selectedOptions = $_POST["ques_" . $num];
    $as_name = implode('||', $selectedOptions);
} else {
    // 선택된 값이 없을 때의 처리
    $as_name = ""; // 또는 다른 기본 값으로 설정
}

 

$as_name = "value1||value2||value3";

// ||로 구분된 문자열을 배열로 변환
$selectedOptions = explode('||', $as_name);

// 각 값에 대한 처리
foreach ($selectedOptions as $option) {
    echo "Value: $option\n";
}
728x90
728x90

php 작업 중 db 에 암호화 해서 데이터를 넣어야 할 경우 다시 복호화 해서 사용자 화면에는 보여져야 하는 경우 AES 예제로 암호화 키 값을 넣어서 만들수 있는 예제 이다. 

 

$encryptionKey 값에 임의의 값을 넣어서 사용하면 된다. 

 

<?php

// 암호화 키 (16, 24 또는 32 바이트 여야 함)
$encryptionKey = 'your_secret_key';

// 암호화할 데이터
$dataToEncrypt = 'Hello, this is a secret message!';

// 암호화
$encryptedData = encryptData($dataToEncrypt, $encryptionKey);
echo 'Encrypted Data: ' . $encryptedData . "\n";

// 복호화
$decryptedData = decryptData($encryptedData, $encryptionKey);
echo 'Decrypted Data: ' . $decryptedData . "\n";

function encryptData($data, $key) {
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
    $encrypted = openssl_encrypt($data, 'aes-256-cbc', $key, 0, $iv);
    return base64_encode($iv . $encrypted);
}

function decryptData($data, $key) {
    $data = base64_decode($data);
    $ivLength = openssl_cipher_iv_length('aes-256-cbc');
    $iv = substr($data, 0, $ivLength);
    $encrypted = substr($data, $ivLength);
    return openssl_decrypt($encrypted, 'aes-256-cbc', $key, 0, $iv);
}

?>

 

함수로 만들어 두면 변환해야 하는 데이터와 key 만 주면 되기에 조금 더 편하게 이용해 볼 수 있다. 

728x90
728x90

요즘 비대면 결제 부터 많은 계약서들이 온라인으로 진행이 되고 있다. 그 중 빠질 수 없는 부분이 동의를 하고 서명하는 부분인데 이 서명란을 모바일 , pc 마우스나 터치로 그리고 이미지로 저장 받는 로직이 필요할때가 많다. 

 

서명을 그리는 부분은 canvas 태그와 스크립트로 가능하고 파일을 저장하는 로직은 php 코드에서 진행한다. 이때 유의할 점은 스크롤이 생기면 캔버스가 자리를 제대로 인식하지 않기 때문에 서명 페이지는 다른 글이 나오는 중간에 넣기 보다 새창을 띄워서 서명을 따로 받고 저장 된 이미지를 본문에 보여주는 식의 코드가 오류가 없다. 

 

아래는 서명을 받는 스크립트와 이미지로 저장하는 로직 까지 같이 메모해 본다. 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    canvas {
      border: 2px solid #000;
			touch-action: none;
    }
  </style>
</head>
<body>
  <canvas id="drawCanvas" width="300" height="200"></canvas>
  <button id="saveButton">Save Image</button>

  <script>
    const canvas = document.getElementById('drawCanvas');
    const context = canvas.getContext('2d');

    let isDrawing = false;

    function startDrawing(e) {
			e.preventDefault(); // 모바일에서 스크롤 방지
      isDrawing = true;
      draw(e);
    }

    function stopDrawing() {
      isDrawing = false;
      context.beginPath();
    }

    function draw(e) {
      if (!isDrawing) return;

      context.lineWidth = 2;
      context.lineCap = 'round';
      context.strokeStyle = '#000';

			// 모바일 터치 이벤트 처리
			if (e.touches) {
				context.lineTo(e.touches[0].clientX - canvas.offsetLeft, e.touches[0].clientY - canvas.offsetTop);
			} else {
				// 마우스 이벤트 처리
				context.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
			}

			context.stroke();
			context.beginPath();

			// 모바일 터치 이벤트 처리
			if (e.touches) {
				context.moveTo(e.touches[0].clientX - canvas.offsetLeft, e.touches[0].clientY - canvas.offsetTop);
			} else {
				// 마우스 이벤트 처리
				context.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
			}
			/*
      context.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
      context.stroke();
      context.beginPath();
      context.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
			*/
    }

    function saveImage() {
      const dataUrl = canvas.toDataURL(); // Canvas의 데이터 URL을 얻습니다.

      // PHP로 데이터 전송
      const xhr = new XMLHttpRequest();
      xhr.open('POST', 'save_image.php', true);
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
          alert(xhr.responseText); // 서버에서의 응답 처리 (예: 성공 메시지)
        }
      };
      xhr.send('image=' + encodeURIComponent(dataUrl));
    }

    canvas.addEventListener('mousedown', startDrawing);
    canvas.addEventListener('mousemove', draw);
    canvas.addEventListener('mouseup', stopDrawing);
    canvas.addEventListener('mouseout', stopDrawing);
    canvas.addEventListener('touchstart', startDrawing);
    canvas.addEventListener('touchmove', function (e) {
      e.preventDefault();
      draw(e.touches[0]);
    });
    canvas.addEventListener('touchend', stopDrawing);

    document.getElementById('saveButton').addEventListener('click', saveImage);
  </script>
</body>
</html>

 

이미지 저장 로직

<?php
if (isset($_POST['image'])) {
    $dataUrl = $_POST['image'];

    // 데이터 URL에서 base64 부분을 제거합니다.
    $data = explode(',', $dataUrl);
    $base64Data = $data[1];

    // base64 디코딩
    $imageData = base64_decode($base64Data);

    // 파일 경로 및 파일 이름 설정
    $filePath = '../uploads/';
    $fileName = uniqid('image_') . '.png';
    $fileFullPath = $filePath . $fileName;

    // 파일 저장
    file_put_contents($fileFullPath, $imageData);

    // 파일 경로 또는 파일 이름을 클라이언트에게 전달 (예: 성공 메시지)
    echo '이미지가 성공적으로 저장되었습니다. 파일 경로: ' . $fileFullPath;
} else {
    // 이미지 데이터가 전송되지 않았을 경우 에러 메시지
    echo '이미지 데이터가 전송되지 않았습니다.';
}
?>
728x90
728x90

시간을 비교해서 입장시간이 되었을때 오픈을 해야 하는 경우가 종종 있다. Date Time 을 이용해서 php 에서는 아래와 같이 비교해 볼 수 있다.  날짜 형식에 맞게 $cd_date, $cd_time 값을 맞춰 넣어야 결과값이 잘 도출 되는 점을 유의해야 한다. 

 

$cd_date = "2023-09-16";
$cd_time = "10:00";

// 현재 날짜와 시간을 가져옵니다.
$currentDateTime = new DateTime();

// $cd_date$cd_time을 DateTime 객체로 변환합니다.
$cdDateTime = new DateTime($cd_date . ' ' . $cd_time);

// 현재 시간이 강의실 입장 가능한 시간 이후인지 확인합니다.
$isEntryAllowed = $currentDateTime >= $cdDateTime;

// true 또는 false 값을 반환합니다.
if ($isEntryAllowed) {
return true;
} else {
return false;
}

Date Time 으로 생각보다 간단하게 시간 비교는 가능하다. 

 

아래 코드는 특정일자를 기준으로 월요일, 화요일 처럼 특정 요일별로 날짜를 증가하며 이후 일자를 계산 하는 로직이다. 

 

2023-09-18 일을 시작으로 10회 차 월, 화 요일만 해당하는 날짜만 구하는 함수이다. 

$ci_start_date = "2023-09-18";
$ord_total_times = 10; 

// 1: 월요일, 2: 화요일 , 3: 수요일이라고 가정했을때 
$days = array(1, 2);
$daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

$startDateTime = new DateTime($ci_start_date); // 시작 날짜


$classDates = [];
$currentDate = clone $startDateTime;

while (count($classDates) < $ord_total_times) {
if (in_array((int)$currentDate->format('N'), $days)) {
array_push($classDates, clone $currentDate);
}

$currentDate->modify('+1 day');
}

foreach ($classDates as $date)
echo $date->format('Y-m-d')."<br>";

 

 

[결과값]

2023-09-18
2023-09-19
2023-09-25
2023-09-26
2023-10-02
2023-10-03
2023-10-09
2023-10-10
2023-10-16
2023-10-17

 

 

728x90

+ Recent posts