본문 바로가기

World Wide Web/PHP Lecture

[PHP] mbstring 없이 한글 문자열 다루기

보통 PHP에서 한글 글자수를 센다던가, substr을 통해 자른다던가, 한글자씩 분리한다던가 할 때 php-mbstring 확장을 사용한다.

 

만약 자신이 만들고 있는 PHP 앱이 빠른 속도를 요구한다면, mbstring 확장을 떨쳐 내는 것은 이를 위한 좋은 방법이 될 수 있다. 실제로 해외의 여러 커뮤니티에서도 mb_strlen() 등은 매우 느리다고 이야기하고 있고, 그래서 구글링 끝에 얻은 대안 두 개를 소개한다.

 

1. iconv_

php-iconv 모듈에 속해 있는데 대부분 내장이라 뭘 따로 설치할 필요는 없다.

<?php
$str = '가나다';
echo microtime();
for($i=0; $i<1000; ++$i){
    mb_strlen($str);
}
echo microtime();

echo microtime();
for($i=0; $i<1000; ++$i){
    iconv_strlen($str);
}
echo microtime();

echo microtime();
for($i=0; $i<1000; ++$i){
    count(preg_split('//u', $str));
}
echo microtime();

속도를 측정해 보고 싶어서 다음과 같이 코드를 작성 후 실행하였다.

strlen을 측정하는 세 가지 방법을 사용하였다. 각 방법으로 1000회씩 실시해 그 소요시간의 차를 구해보겠다.

 

출력

0.15499200 1620953054

0.15879300 1620953054

0.15879800 1620953054

0.15966200 1620953054

0.15966400 1620953054

0.16053900 1620953054

 

분석해 보면, mb_strlen()은 0.003801초

iconv_strlen()은 0.000864초

count(preg_split(...))은 0.000875초가 걸렸다.

물론 하단에 서술하겠지만 count(preg_split()) 은 함수를 하나 더 써야해서 속도가 더 느릴 것이다.

이렇게 해 보면 mb_strlen이 얼마나 느린 함수인지 알 수 있다.

2. preg_split

출처:

stackoverflow.com/questions/3666306/how-to-iterate-utf-8-string-in-php

 

How to iterate UTF-8 string in PHP?

How to iterate a UTF-8 string character by character using indexing? When you access a UTF-8 string with the bracket operator $str[0] the utf-encoded character consists of 2 or more elements. For

stackoverflow.com

<?php
function u_strlen($text){
    $result = array_slice(preg_split('//u', $text), 1, -2);
    return count($result);
}

function u_substr($text, $offset, $len=null){
	$result = preg_split('//u', $text,-1,PREG_SPLIT_NO_EMPTY);
    return array_slice($result, $offset, $len);
}

function u_strpos($haystatck, $needle, $offset=0){
	$split = preg_split('//u', $haystack,-1,PREG_SPLIT_NO_EMPTY);
    $result = array_slice($result, $offset);
    return array_search($needle, $result);
}

$sample = '다람쥐 헌 쳇바퀴에 타고파';
echo u_strlen($sample); // 14
echo u_substr($sample, 1); // 람쥐 헌 쳇바퀴에 타고파
echo u_strpos($sample, '쳇바퀴'); // 6

 

 

 

정규식 함수를 쓰기 때문에 얼핏 보면 느려보일 수 있다. 그러나 메모리를 더 많이 먹을지언정 속도는 더 빨라졌다는 것이 해당 stackoverflow 페이지의 주 내용이다.

 

여기서 주의할 점은, PREG_SPLIT_NO_EMPTY 옵션을 주지 않으면 맨 앞과 맨 뒤에 공백이 생긴다.