Dev Blog

스크립트 & 소스코드 공유

실무에서 유용하게 쓰는 스크립트와 코드 조각을 블로그 게시판으로 저장하고 공유합니다.

26건의 글

phpMyAdmin으로 MySQL 데이터베이스 테이블 일괄 삭제하기

PHP 스크립트를 이용해 특정 접두어(v9_)가 붙은 MySQL 테이블을 한 번에 삭제하는 방법이다. 데이터베이스에 연결해 show tables로 전체 테이블을 조회한 뒤, 접두어가 일치하는 테이블만 drop table로 삭제하고 결과를 출력한다. 실행 전 반드시 데이터베이스 전체를 백업할 것을 권장한다.

使用这个方法前,强烈建议先备份整个数据库。至于怎么备份?你不会么?在本文下方留言吧。

具体方法:复制下面的php执行语句,保存为sql.php文件(注意配置数据库名称、密码、数据表头),通过ftp上传到网站跟目录,运行。

<?php
//设置数据库连接信息。数据库服务器地址,数据库用户名,数据密码
mysql_connect('localhost','root','123456');
//设置查询的数据库名称,比如CMSYOU当前设置的是phpcms
mysql_select_db('phpcms');
$rs=mysql_query('show tables');
while($arr=mysql_fetch_array($rs))
{
//设置要批量删除的数据库表前缀,如:v9_
$TF=strpos($arr[0],'v9_');
if($TF===0){
$FT=mysql_query("drop table $arr[0]");
if($FT){
echo "$arr[0] 删除成功!<br>";
}
}
}
?>

PHP 엑셀 다운로드 시 셀 서식(mso-number-format) 지정하기

PHP로 데이터를 엑셀 파일로 저장할 때 핸드폰 번호 앞자리 0이 사라지는 문제를 해결하는 방법이다. 출력하는 td 태그의 style에 mso-number-format을 지정해 텍스트(\@) 형식으로 강제하고, 날짜·숫자·소수점·퍼센트·통화·과학 표기법 등 다양한 셀 서식 형식도 정리했다.

이벤트 참가자 정보를 엑셀로 저장하는데 핸드폰 번호 '010...' 가 숫자로 출력되니 '10...' 로 나온다.

원래대로 '010...' 으로 나오게 하려면 숫자가 아닌 텍스트로 출력해야 한다.

셀 서식 지정할 때는 데이터 출력하는 html의 style에 MSO FORMAT을 지정하면 된다.

header("Content-type: application/vnd.ms-excel; charset=UTF-8");
header("Content-Disposition: attachment; filename = userIdentify".date("YmdHis").".xls");
header("Content-Description: PHP5 Generated Data");
header("Cache-Control: no-cache");
header("Pragma: no-cache");

// DB커넥션 파일(PDO)
require_once($_SERVER['DOCUMENT_ROOT'].'/Connection/dbconnect.php');

// 검색 조건 설정
...(생략)

// 데이터 조회
...(생략)

?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
th,td{border:0.6px solid #666;}
th{background-color: yellow;}
</style>
</head>
<body>
<h3>Table</h3>
<table>
<tr>
<th>이름</th>
<th>전화번호</th>
</tr>
<? while($rows=$stmt->fetch(PDO::FETCH_ASSOC)){ ?>
<tr>
<td><?=$rows['userName']?></td>
<!--셀 서식을 Text로 지정-->
<td style="mso-number-format:'\@'"><?=$rows['userPhone']?></td>
</tr>
<? } ?>
</table>
</body>
</html>

검색해 보면 다른 타입도 많이 나온다. 그러나 실제 사용하는 건 텍스트 형식(\@) 정도인 듯 하다.

(텍스트로 지정 하면 데이터 출력하는 그대로 나온다.)

mso-number-format:"\@"

Text // 텍스트

mso-number-format:"0"

NO Decimals // 소수점 없음

mso-number-format:"0.000"

3 Decimals // 소수점 3자리까지

mso-number-format:"#\,##0.000"

Comma with 3 dec // 숫자 자릿수 구분(,)+소수점 3자리

mso-number-format:"mm\/dd\/yy"

월/일/연도 형식 (05/15/16)

mso-number-format:"mmmm\ d\,\ yyyy"

'mmmm' 하면 월을 영문으로 표시한다. (January 1,2016)

mso-number-format:"d-mmm-yyyy"

01-mar-1998 형식. 월 표기가 다르다.

mso-number-format:"Short Date"

01/03/1998 형식. 간단하게 지정

mso-number-format:"Medium Date"

01-mar-98

mso-number-format:"m\/d\/yy\ h\:mm\ AM\/PM"

날짜 + 시간을 AM/PM으로 구분해서 표시

mso-number-format:"Short Time"

5:16 // 시간만 간단하게

mso-number-format:"Medium Time"

5:16 am

mso-number-format:"Long Time"

5:16:21:00 // 밀리 초(ms) 단위까지

mso-number-format:"Percent"

Percent - two decimals // 퍼센트 기호 + 소수점 2자리까지

mso-number-format:"0%"

Percent - no decimals // 소수점 없는 퍼센트

mso-number-format:"0.E+00"

Scientific Notation // 엑셀에서 숫자 자릿수가 매우 클 때 줄여서 표시되는 그 형식..

mso-number-format:"#\ ???\/???"

Fractions - up to 3 digits (312/943) , 분수형식

mso-number-format:"\0022£\0022#\,##0.00"

£12.76 // 영국 파운드 기호로 통화 표시(원화 표시는 없을까?)

mso-number-format:"#\,##0.00_ \;[Red]-#\,##0.00\ "

2 decimals, negative numbers in red and signed(1.56 -1.56) // 음수는 색깔을 따르게 표시

PHP로 인스타그램 해시태그 이미지 파싱해오기

PHP의 cURL 함수로 인스타그램 태그 페이지(explore/tags/태그명/?__a=1)를 요청해 해시태그 게시물의 이미지 정보를 파싱하는 방법이다. 태그명과 가져올 개수를 지정하면 graphql 응답에서 shortcode와 thumbnail_src를 꺼내 원본 이미지 링크를 출력한다. 간단한 파싱 예제 코드를 제공한다.

function scrape_insta_hash($tag) {
$url = 'https://www.instagram.com/explore/tags/'.$tag.'/?__a=1';
$ch = curl_init();
$timeout = 5;
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$insta_source = curl_exec($ch);
$insta_array = json_decode($insta_source, TRUE);
return $insta_array;
}
$tag = '공양이'; // 태그 명
$limit = 16; // 가져 올 개수
$results_array = scrape_insta_hash($tag);
$image_array= array();
for ($i=0; $i < $limit; $i++) {
$latest_array = $results_array['graphql']['hashtag']['edge_hashtag_to_media']['edges'][$i]['node'];
$image_data  = '<a href="https://www.instagram.com/p/'.$latest_array['shortcode'].'" target="_blank"><img src="'.$latest_array['thumbnail_src'].'"></a>'; // thumbnail and same sizes
array_push($image_array, $image_data);
}
foreach ($image_array as $image) {
echo $image;
}

한글 종성에 맞는 조사(은/는, 이/가, 을/를) 자동 변환 클래스

UTF-8 한글 문자열에서 마지막 글자의 종성(받침) 유무에 따라 은/는, 이/가, 을/를, 과/와 같은 올바른 조사로 자동 치환해주는 PHP 클래스를 소개한다. 명사가 변수로 치환되는 메시지 조합 시 자연스러운 한국어 문장을 만들 수 있으며, 조사별 매핑과 종성 판단 로직이 담긴 전체 코드를 제공한다.

사용자에게 보여줄 메세지 문자열을 조합하는데,

일부 명사가 변수로 치환될 경우 치환될 단어에 따라 적절한 조사를 붙여줘야 함. (아니면 왈도체를...)

조사 바로 앞의 문자에 받침(종성)이 있냐 없냐에 따라 구분되는데,

UTF-8 이라 가정하고 종성이 있는지 없는지 판단하여 적절한 조사를 치환해주는 간단한 클래스를 만들었음.

// 게임 메세지라 가정하고 치환하는 예제
$name   = '백충덕';
$monster = '고블린';
$item1 = '포션';
$item2 = '엘릭서';

$str = '몬스터 '.$monster.'{가} 나타났다.'."\n";
$str .= $name.'{은} '.$monster.'{를} 물리치고 '.$item1.'{와} '.$item2.'{를} 얻었다.'."\n";
echo Postposition::conv($str);
// 출력
// 몬스터 고블린이 나타났다.
// 백충덕은 고블린을 물리치고 포션과 엘릭서를 얻었다.

// 조사 치환 함수
// 치환대상 조사를 {가},{은} 식으로 감싼 문자을 넘기면 알아서 변환해 줌.
class Postposition
{
// 조사 리스트
// 0,2,4,6 = 종성있음
// 1,3,5,7 = 종성없음
const POSTPOSITION_LIST = '이가은는을를과와';

// 인스턴스
private static $instance = null;

// 문장에서 조사를 적절하게 변환
public static function conv($str)
{
return self::getInstance()->__conv($str);
}

// 인스턴스 반환
private static function getInstance()
{
if (self::$instance === null) self::$instance = new self;

return self::$instance;
}

// 생성자. internal encoding 세팅
private function __construct()
{
mb_internal_encoding('UTF-8');
}

// 조사 변환
private function __conv($str)
{
return preg_replace_callback("/(.)\\{([".self::POSTPOSITION_LIST."])\\}/u", array($this, 'replace'), $str);
}

// preg_replace_callback의 callback함수
private function replace($matches)
{
// 조사 바로 앞 한글자
$lastChar = $matches[1];
// 조사
$postpositionMatched = $matches[2];

// 종성 유/무에 따른 조사배열 세팅
$arrPostposition = array(
'종성없음' => $postpositionMatched,
'종성있음' => $postpositionMatched
);
$pos = mb_strpos(self::POSTPOSITION_LIST, $postpositionMatched);
if ($pos % 2 != 0) {
$arrPostposition['종성있음'] = mb_substr(self::POSTPOSITION_LIST, $pos-1, 1);
} else {
$arrPostposition['종성없음'] = mb_substr(self::POSTPOSITION_LIST, $pos+1, 1);
}

// 기본값 = '종성있음'
$lastCharStatus = '종성있음';

// 2바이트 이상 유니코드 문자
if (strlen($lastChar) > 1) {
$code = $this->utf8Ord($lastChar) - 44032;

// 한글일 경우 (가=0, 힣=11171)
if ($code > -1 && $code < 11172) {
// 초성
//$code / 588
// 중성
//$code % 588 / 28
// 종성
if ($code % 28 == 0) $lastCharStatus = '종성없음';
}
// 1바이트 ASCII
} else {
// 숫자중 2(이),4(사),5(오),9(구)는 종성이 없음
if (strpos('2459', $lastChar) > -1) {
$lastCharStatus = '종성없음';
}
}

// 종성 상태에 알맞는 조사를 붙여 반환
return $lastChar.$arrPostposition[$lastCharStatus];
}

// ord() UTF-8 버전
private function utf8Ord($char)
{
switch (strlen($char)) {
case 1:
return ord($char);
break;
case 2:
return ((ord($char[0]) & 0x1F) << 6) | (ord($char[1]) & 0x3F);
break;
case 3:
return ((ord($char[0]) & 0x0F) << 12) | ((ord($char[1]) & 0x3F) << 6) | (ord($char[2]) & 0x3F);
break;
case 4:
return ((ord($char[0]) & 0x07) << 18) | ((ord($char[1]) & 0x3F) << 12) | ((ord($char[2]) & 0x3F) << 6) | (ord($char[3]) & 0x3F);
break;
default:
return $char;
}
}
}

PHP 함수 - 한글 단어 마지막 글자 받침(종성) 확인

한글 문자열의 마지막 글자에 받침이 있는지 확인하는 PHP 함수 has_batchim()을 소개한다. UTF-8 문자열을 UTF-16BE로 변환해 마지막 글자의 유니코드 코드 포인트를 구하고, '가'의 기준값 44032를 뺀 값을 28로 나눈 나머지가 0보다 크면 받침이 있는 것으로 판별한다. 예시로 깃허브에 '을/를' 조사를 붙이는 사용법을 보여준다.

<?php
// License: Public Domain
//
// 마지막 글자에 받침이 있으면 0보다 큰 정수를 반환하고
// 받침이 없으면 0을 반환한다.
//
// 예:
// $word = '깃허브';
// echo $word . (has_batchim($word) ? '을' : '를');
function has_batchim($str, $charset = 'UTF-8') {
$str = mb_convert_encoding($str, 'UTF-16BE', $charset);
$str = str_split(substr($str, strlen($str) - 2));
$code_point = (ord($str[0]) * 256) + ord($str[1]);
if ($code_point < 44032 || $code_point > 55203) return 0;
return ($code_point - 44032) % 28;
}


Let's create something great together.

프로젝트 문의 및 견적 요청은 언제든 환영합니다.