before

SELECT 
  a.no,
  a.code,
  b.price,
  b.start_date,
  b.end_date
FROM product a
left join sale b
on a.code = b.code
Union
SELECT 
  a.no,
  a.code,
  b.price,
  b.start_date,
  b.end_date
FROM product a
right join sale b
on a.code = b.code
order by no desc

Error Code : 1221 Incorrect usage of UNION and ORDER BY

 

오류 발생

- union과 order by를 같이 사용할 때에는 select 문을 괄호로 감싸줘야 한다.

 

after

(
SELECT 
  a.no,
  a.code,
  b.price,
  b.start_date,
  b.end_date
FROM product a
left join sale b
on a.code = b.code
)
Union
(
SELECT 
  a.no,
  a.code,
  b.price,
  b.start_date,
  b.end_date
FROM product a
right join sale b
on a.code = b.code
)
order by no desc;​

 


WRITTEN BY
beautifulhill

,

아주 간단하게 메일을 보낼 수 있지만

예쁘게 꾸민 html 코드로 메일을 보낼 수도 있다.

 

1. mailtest.php

$to      = '받는사람@gmail.com';
$subject = 'html을 보냈습니다.';
$fp = fopen('mailtest.html',"r");
$message = fread($fp,filesize('mailtest.html'));

$name = '김광인';
$age = '21';
$gender = '남자';
$message = str_replace('{name}', $name, $message);
$message = str_replace('{age}', $age, $message);
$message = str_replace('{gender}', $gender, $message);
echo $message;


// html 메일을 보낼 때 꼭 이헤더가 붙어야한다.
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=utf-8';

// Additional headers
$headers[] = 'To: Kim<받는사람@gmail.com>';
$headers[] = 'From: Admin<test@naver.com>';
$headers[] = 'Cc: Kim1<참조인1@naver.com>,Kim2<참조인2@gmail.com>';
$headers[] = 'Bcc: 숨은참조인3@gmail.com';


$result =mail($to, $subject, $message, implode("\r\n", $headers));
echo "메일 성공여부 : ";
if($result){echo "성공";}else{echo "실패";}

2_1. mailtest.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
table tr td{
border: 1px solid #5da399;
text-align: center;
padding: 10px;
}
</style>
</head>

<body>
	<table>
		<tr>
			<td>이름</td>
			<td>{name}</td>
		</tr>		
		<tr>
			<td>나이</td>
			<td>{age}</td>
		</tr>		
		<tr>
			<td>성별</td>
			<td>{gender}</td>
		</tr>
	</table>
</body>
</html>

 

 

이렇게 하면, mailtest.html은

 

다음과 같이 출력된다.

 

메일을 보낸 후

메일함을 확인해보면

 

다음과 같이 스타일이 적용이 하나도 안된 상태로 온다.

따라서 html의 스타일을 inline방식으로 바꾼다.

 

2_2. mailtest.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">

</style>
</head>

<body>
	<table style="border-collapse: collapse;text-align: center;">
		<tr>
			<td style="border: 1px solid #5da399;padding: 10px;">이름</td>
			<td style="border: 1px solid #5da399;padding: 10px;">{name}</td>
		</tr>		
		<tr>
			<td style="border: 1px solid #5da399;padding: 10px;">나이</td>
			<td style="border: 1px solid #5da399;padding: 10px;">{age}</td>
		</tr>		
		<tr>
			<td style="border: 1px solid #5da399;padding: 10px;">성별</td>
			<td style="border: 1px solid #5da399;padding: 10px;">{gender}</td>
		</tr>
	</table>
</body>
</html>

 

 

스타일이 잘 적용된 상태로 메일이 보내진다.

 

다 끝난 것 같지만 아직 문제가 하나 남았다.

 

잘 살펴보자

 

 

분명 받는 사람은 나 하나고 참조인이 2명인데, 왜 받는사람이 두명인 것인가?

 

이는 mailtest.php에서 $to 와 $headers[] = 'To: Kim<받는사람@gmail.com>';

때문인다. to를 두번 지정해준 것이므로 "$headers[] = 'To: Kim<받는사람@gmail.com>';" 지워줘야 한다.

 

그럼 다음과 같이 받는 사람이 한명으로 제대로 나온다.


WRITTEN BY
beautifulhill

,

mail()함수를 사용하여 php로도 간단한 메일을 전송할 수 있다.

단, mail()함수는 리눅스에서만 사용가능하다는 단점

 

매뉴얼을 보면

mail ( string $to , string $subject , string $message [, mixed $additional_headers [, string $additional_parameters ]] ) : bool

라고 나와있다.

 

mail(받는 사람의 이메일, 제목, 메시지 [, 헤더 [, 파라미터]]) 이며 성공시 true, 실패시 false를 반환한다.

 

1. 받는사람주소, 제목, 메시지는 mail함수의 필수 파라미터이다. 이것만을 사용하여 간단히 메일을 보낼 수 있다.

$message는 70자를 초과할 경우 자동 줄바꿈을 하도록 wordwrap() 함수를 사용하도록 권한다.

$message = "안녕하세요. 이 메일은 1992년 영국으로부터 시작된 메일이며 확인 즉시 10명에게 전달해야합니다. 그렇지 않으면....";
$message = wordwrap($message, 70, "\r\n");

$result = mail('받을사람이메일@gmail.com', '제목입니다.', $message);
echo "메일 성공여부 : ";
if($result){echo "성공";}else{echo "실패";}

 

 

2. 헤더를 추가해보자.

헤더에는 From(보내는 사람), Cc : 참조할 사람, Bcc: 숨은 참조 Reply-To: 답장할 메일주소 등을 추가할 수 있으며,

헤더는 CRLF(\r\n)로 구분해야한다.

$to      = '받는사람이메일@gmail.com';
$subject = '제목입니다.';
$message = '안녕하세요. 이 메일은 1992년 영국으로부터 시작된 메일이며 확인 즉시 10명에게 전달해야합니다. 그렇지 않으면....';

$headers = 'From: 보내는 메일주소@naver.com' . "\r\n" .
    'Reply-To: 답장 누르면 답메일 보낼 주소(보통은 from과 같음)@naver.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();
    
$result =mail($to, $subject, $message, $headers);
echo "메일 성공여부 : ";
if($result){echo "성공";}else{echo "실패";}

 

2-1. 헤더는 배열로도 가능하다.

$to      = '받는사람이메일@gmail.com';
$subject = '제목입니다.';
$message = '안녕하세요. 이 메일은 1992년 영국으로부터 시작된 메일이며 확인 즉시 10명에게 전달해야합니다. 그렇지 않으면....';

$headers = array(
    'From' => '보내는 메일주소@naver.com',
    'Reply-To' => '답장 누르면 답메일 보낼 주소(보통은 from과 같음)@naver.com',
    'X-Mailer' => 'PHP/' . phpversion()
);

$result =mail($to, $subject, $message, $headers);
echo "메일 성공여부 : ";
if($result){echo "성공";}else{echo "실패";}

 

 

이렇게 보낼 경우 '메일을 보내는 페이지.php'에서는 

 

 

메일함에 가면 메일이 잘 도착해 있다.

 

 

 


WRITTEN BY
beautifulhill

,

BLOB(Binary Large OBject) 타입은 65535 바이트를 넘는 바이너리 데이터 타입이다.

mysql workbench에서 BLOB 이라고 뜨며 데이터가 보이지 않는 경우가 있다.

 

BLOB

 

이를 해결하기 위해 1. 워크벤치의 설정을 변경하거나 2. mysql의 cast() 함수를 사용한다.

 

 

 

1. 워크벤치에서 Edit > Preferences > SQL Editor > SQL Execution > Treat BINARY/VARBINARY as nonbinary character string 을 체크한다.

BLOB이 바이너리 데이터이기 때문에 바이너리 데이터를 논바이너리 문자열로 출력하도록 설정한다.

 

Edit > Preferences
SQL Execution > Treat BINARY/VARBINARY as nonbinary character string

 

이렇게 하면 

 

다음과 같이 BLOB타입의 데이터도 잘 출력된다.

 

 

 

2. CAST 함수를 사용한다.

cast함수 사용법 : cast(value as datatype)

Datatype은 다음과 같이 있는데, 문자열로 출력을 할 것이기 때문에 CHAR 선택

DATE Converts value to DATE. Format: "YYYY-MM-DD"
DATETIME Converts value to DATETIME. Format: "YYYY-MM-DD HH:MM:SS"
TIME Converts value to TIME. Format: "HH:MM:SS"
CHAR Converts value to CHAR (a fixed length string)
SIGNED Converts value to SIGNED (a signed 64-bit integer)
UNSIGNED Converts value to UNSIGNED (an unsigned 64-bit integer)
BINARY Converts value to BINARY (a binary string)


이렇게 SQL문을 작성하면 다음과 같이 문자열로 잘 출력된다.

select cast(PASSWORD('qqq111') as char(10000));

 


WRITTEN BY
beautifulhill

,

php만으로도 캡챠기능을 만들 수 있지만, 좀 더 확실하고 안전한 구글 리캡챠를 사용해보자.

 

 

 

완성샷

 

 

1. 구글 리캡챠 홈페이지(https://developers.google.com/recaptcha/intro) 에 들어가서 'sign up for an API key pair'를 클릭

 

 

 

2. 라벨을 마음대로 적고 reCAPTCHA v2를 선택하고 동의 한다.

 

 

3. 사이트 키와 비밀키를 복사해둔다.

 

 

4. 코드 작성

 

 1. joinForm.php

<html>
  <head>
    <title>reCAPTCHA demo: Simple page</title>
    <script src="https://www.google.com/recaptcha/api.js" async defer>
	</script>
  </head>

  <body>
	<form action="join.php" method="post">
	<table style="margin:auto;">
		<tr>
			<td>아이디</td>
			<td><input type="text" name="id"></td>
		</tr>
		<tr>
			<td>비밀번호</td>
			<td><input type="password" name="pw"></td>
		</tr>
		<tr>
			<td>비밀번호 확인</td>
			<td><input type="password" name="pw2"></td>
		</tr>
		<tr>
			<td colspan="2">
			<div id="captcha" class="g-recaptcha" data-sitekey="사이트키"></div>
			</td>
		</tr>
	</table>
	<div style="text-align:center;">
		<button type="submit">가입하기</button>
	</div>
	</form>
    </script>
  </body>
</html>

 

 2. join.php

<?
$captcha = $_POST['g-recaptcha-response'];
$secretKey = '시크릿키';
$ip = $_SERVER['REMOTE_ADDR'];

$data = array(
  'secret' => $secretKey,
  'response' => $captcha,
  'ip' => $ip
);
$parameter = http_build_query($data);
$url = "https://www.google.com/recaptcha/api/siteverify?".$parameter;

$response = file_get_contents($url);
$responseKeys = json_decode($response, true);

if ($responseKeys["success"]) {
  echo '캡챠 성공';
	echo '<br/>';
	echo '가입을 진행하세요.';
} else {
  	echo '<script>
			alert(\'가입실패\');
			history.go(-1);
		  </script>';
}
?>

 


WRITTEN BY
beautifulhill

,

CAPTCHA((Completely Automated Public Turing test to tell Computers and Humans Apart)는 사용자가 실제 사람인지 컴퓨터 프로그램인지 구분하기 위해 사용되는 기술로 주로 회원가입이나 결제 시에 보게 된다.

captcha 프로그램이 임의의 문자와 숫자를 일그러지거나 왜곡된 이미지로 변환하기 때문에 기계는 알아보기 힘드나 사람은 알아볼 수 있다.

구글 reCAPTCHA(리캡챠), 네이버 캡챠 등 잘 만들어진 api들이 있고 코드이그나이터의 경우 캡챠헬퍼를 제공하지만, php만으로도 간단하게 캡챠 기능을 만들 수 있다.

 

캡챠 완성샷

1. captcha.php

<?
session_start();

//이미지 크기
$img = imagecreate(100,50);

//캡챠 폰트 크기
$size = 30;
//캡챠 폰트 기울기
$angle = 0;
//캡챠 폰트 x,y위치
$x = 10;
$y = 40;
//이미지의 바탕화면은 흰색
$background = imagefill($img,0,0,imagecolorallocatealpha($img,255, 255, 255, 100));
//폰트 색상
$text_color = imagecolorallocate($img, 233, 14, 91);
//폰트 위치
$font = 'font/tvn_bold.ttf';

//캡챠 텍스트
$str = substr(md5(rand(1,10000)),0,5);
//가입 시 캡챠 텍스트 확인을 위해 session에 담는다.
$_SESSION['str'] = $str;

//글자를 이미지로 만들기
imagettftext($img,$size,$angle,$x,$y,$text_color,$font,$str);

Header("Content-type: image/jpeg");
imagejpeg($img,null,100);
imagedestroy($img);
?>

 

2. joinForm.php

-captcha.php 뒤에 date파라미터를 쓴 이유 : 캡챠와 사용자가 입력한 글자가 맞지 않을 경우 뒤로가기를 통해 joinForm.php로 돌아온다. 이 때 captcha.php가 한번 더 호출되면서 session에 새로운 캡챠 값이 저장이 되지만, 이미지는 캐시에 저장된 이미지(이미 보여준 이미지)가 나오기 때문이다.

<form action="join.php" method="post">
	<table style="margin:auto;">
		<tr>
			<td>아이디</td>
			<td><input type="text" name="id"></td>
		</tr>
		<tr>
			<td>비밀번호</td>
			<td><input type="password" name="pw"></td>
		</tr>
		<tr>
			<td>비밀번호 확인</td>
			<td><input type="password" name="pw2"></td>
		</tr>
		<tr>
			<td rowspan="2"><img src="captcha.php?date=<?echo date('h:i:s')?>"></td>
			<td>왼쪽 이미지의 글자를 입력하세요.</td>
		</tr>
		<tr>
			<td><input type="text" name="captcha"></td>
		</tr>
	</table>
	<div style="text-align:center;">
		<button type="submit">가입하기</button>
	</div>
</form>

 

3. join.php

<?
session_start();
if($_POST['captcha'] === $_SESSION['str']){
	echo '캡챠 성공';
	echo '<br/>';
	echo '가입을 진행하세요.';
}else{
	echo '<script>
    		alert(\'입력하신 글자가 다릅니다.\');
            history.go(-1);
         </script>';
}
?>

WRITTEN BY
beautifulhill

,

1.php.ini 위치 확인

   1) Bitnami의 경우 'C:\Binami\wampstack-7.3.11-0\php' 디렉토리에 위치

   2) info.php파일을 만들어 <?php phpinfo() ?>를 작성하면 다음과 같이 php.ini 위치 확인 가능

 

2. php.ini 파일 수정

   1) 에러 메시지 보이기

      display_errors = Off > display_errors = On 으로 수정

 

 

 

   2)  php 내용을 수정해도 바로 적용이 안돼요. >>> php 수정 후 바로 적용하기

      opcache.enable=1 > opcache.enable=0으로 수정하여 캐시를 사용하지 않도록!

 

 

 

  3) php 태그(<??>)가 안먹혀요 >>> <?php ?> 를 <? ?>로 짧은 태그 사용하기

     short_open_tag = Off > short_open_tag = On 으로 수정

 

   

 

   4) 다른 폴더에 코드 저장하고 싶어요 >>> root directory 변경하기

      C:/Bitnami/wampstack-7.3.11-0/apache2/conf/bitnami 디렉토리의 bitnami.conf 파일에서 

      9~10줄 (DocumentRoot "저장할 위치")로 수정 (*apache2의 위치는 php.ini처럼 phpinfo()를 통해 확인 가능하다.)

 

 

3. 아파치 재실행

   php.ini 파일을 수정해도 아파치를 재실행 하지 않으면 적용 되지 않는다.

 

 


WRITTEN BY
beautifulhill

,