1. 오토셋 APM 인스톨러 ( apache + php7.2 + mariadb ) 설치 | https://itadventure.tistory.com/93
2. 코드이그나이터 4 ( codeigniter 4 ) 설치 | https://itadventure.tistory.com/95
3. 비주얼 스튜디오 코드 에디터 설치 & 한글 설정 | https://itadventure.tistory.com/96
4. 폴더열기 / 웹페이지 편집(1) | https://itadventure.tistory.com/97
5. 웹페이지 편집(2) | https://itadventure.tistory.com/101
6. 코드이그나이터4의 URL 규칙 | https://itadventure.tistory.com/105
7. php, 네임스페이스 [ namespace ] ?! | https://itadventure.tistory.com/118
8. 코드이그나이터의 네임스페이스, 그리고 모델 | https://itadventure.tistory.com/122
9. 코드이그나이터 뷰의 파라미터 전달 | https://itadventure.tistory.com/147
10. 코드이그나이터 뷰를 나눠 볼까요? | https://itadventure.tistory.com/174
11. MYSQL 이 뭐여? [ 마이에스큐엘은 서류철이다! ] | https://itadventure.tistory.com/175
12. MYSQL 콘솔에 접속해보자! | https://itadventure.tistory.com/178
13. MySql에 넣었다가 꺼냈다가, 뭘? | https://itadventure.tistory.com/265
14. 검색진열대 MYSQL | https://itadventure.tistory.com/267
15. 편집의 왕자 MySQL | https://itadventure.tistory.com/269
16. 코드이그나이터4, MYSQL과 손잡다. | https://itadventure.tistory.com/271
17. MySQL -> 컨트롤러 -> 뷰 트리플 패스! | https://itadventure.tistory.com/272
18. 코드이그나이터! MySQL 에 입력하다! ( insert ) | https://itadventure.tistory.com/273
19. 해킹을 막아라! MySQL인젝션 보안 | https://itadventure.tistory.com/274
20. MySQL과 친해지는 phpmyadmin | https://itadventure.tistory.com/277
21. 코드이그나이터4에서 책 정보를 편집해볼까요? | https://itadventure.tistory.com/280
22. 코드이그나이터4에서 책을 지워봅시다. DELETE! | https://itadventure.tistory.com/282
23. 코드이그나이터4, 페이징 기술 | https://itadventure.tistory.com/285
24. 코드이그나이터4. 검색! | https://itadventure.tistory.com/295
25. 코드이그나이터4. 검색어 자동 추천! | https://itadventure.tistory.com/303
26. 코드이그나이터4. 네이버 검색 따라잡기-1. 대용량 자료 쾌속 검색!(1) | https://itadventure.tistory.com/304
27. 코드이그나이터4. 네이버 검색 따라잡기-2. 대용량 자료 쾌속 검색!(2) | https://itadventure.tistory.com/306
28. 코드이그나이터4. 네이버 검색 따라잡기-3. 대용량 자료 쾌속 검색!(3) | itadventure.tistory.com/310
29. 코드이그나이터4. 코드이그나이터답게 모델화! M!(Model) | itadventure.tistory.com/363
30. 코드이그나이터4. 네이버검색 따라잡기-4. 한글풀어쓰기 검색
지난번에 만든 크레이한글 클래스는 사실 이번 강좌를 위한 것입니다.
네이버 검색을 유심히 살펴보다 보면 검색하는 부분에 아주 특화된 기능이 숨어 있는 것을 보실 수 있습니다.
이른바 한글 자소 검색인데요.
만약 스니커를 검색하려고 '스니ㅋ' 까지만 타이핑하면 스니 + ㅋ 으로 시작되는 단어들이 주루륵 나옵니다.
그래서 한글을 모두 타이핑하지 않고 단어를 선택해서 검색할 수가 있는데요.
어떤 원리일까요?
크레이는 네이버 개발자가 아니라서 자세한 원리는 알 수는 없지만,
아마도 각 내용도 한글 풀어쓰기로 저장, 검색 기능도 한글 풀어쓰기로 검색하기 때문일 것으로 추정됩니다.
이를테면 '스니커즈' 를 'ㅅㅡㄴㅣㅋㅓㅈㅡ'로 보관한다면
검색할 때 'ㅅㅡㄴㅣㅋ'까지만 타이핑해도 앞의 문장이 같으니까 검색이 되는 원리이지요.
이번 시간에는 이걸 만들어 볼겁니다.
역시 주저리 주저리 설명드리면 본문이 너무 길어지니 변경된 부분과 간략한 설명으로 진행하겠습니다.
우선 지난번 공개해드린 크레이한글 클래스를 코드이그나이터용으로 수정하였습니다.
app\Models\CrayHangulModel.php 파일로 저장해주세요.
그냥 라이브러리라고 생각하고 사용해주시면 됩니다. 설명드리기에는 꽤 내용이 깁니다.
노파심에 말씀드리지만 한글이 들어 있어 utf-8 형식으로 저장해 주셔야 합니다.
비주얼 스튜디오 코드 에디터를 사용하면 자동으로 utf-8이니 추가로 하실 일은 없습니다.
<?php namespace App\Models;
// 제목 : 크레이한글 클래스 ( UTF-8 )
// 설명 : 한글 자소 분리, 한글 조합을 자유롭게 수행합니다.
// 제작자 : 크레이 ( 이용운 )
// 첫오픈 : 2020. 10. 10
// 블로그 : 크레이의 IT 탐구 / https://itadventure.tistory.com
// 주석만 삭제하지 않으면 자유롭게 사용하셔도 좋습니다.
class CrayHangulModel {
private $cho_start=0xac00; // 초성이 시작되는 코드
private $cho_length=588; // 초성간 간격
private $jung_length=28; // 중성간 간격
// 초성 19글자
private $cho_char=array(
"ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ",
"ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ",
"ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ",
"ㅋ", "ㅌ", "ㅍ", "ㅎ");
// 중성 21글자
private $jung_char=array(
"ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ",
"ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ",
"ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ",
"ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ",
"ㅣ"
);
// 중성 27글자 + 공백1개 ( 받침이 없는 경우 )
private $jong_char=array(
"", "ㄱ", "ㄲ", "ㄳ", "ㄴ",
"ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ",
"ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ",
"ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ",
"ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ",
"ㅌ", "ㅍ", "ㅎ"
);
// 중성 - 겹자음 자소글자를 두 글자로 나눈 것
private $jong_char2=array(
"", "ㄱ", "ㄲ", "ㄱㅅ", "ㄴ",
"ㄴㅈ", "ㄴㅎ", "ㄷ", "ㄹ", "ㄹㄱ",
"ㄹㅁ", "ㄹㅂ", "ㄹㅅ", "ㄹㅌ", "ㄹㅍ",
"ㄹㅎ", "ㅁ", "ㅂ", "ㅂㅅ", "ㅅ",
"ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ",
"ㅌ", "ㅍ", "ㅎ"
);
// 한글 한글자를 3개의 초중종성 글자 배열로 분할해줍니다. ( 3바이트 UTF8 기준 )
// 입력)
// $char : UTF8 한글 한글자
// $jong_split : 종성이 2개의 자소인 경우 분리할지 여부, ㄳ => ㄱ, ㅅ ( 기본 = false )
// 리턴)
// 한글자소를 배열로 리턴합니다.
public function split_han($char, $jong_split=false)
{
// 1바이트 코드인 경우
if(strlen($char)<=1)return array($char);
// UTF8 코드표 주소 추출
$c1=substr($char, 0, 1);
$c2=substr($char, 1, 1);
$c3=substr($char, 2, 1);
$p=ord($c1) * 65536 + ord($c2) * 256 + ord($c3);
// 한글이 아닌 경우
if($p<0xeab080 || $p>0xed9ea3 )return array($char);
// 1110XXXX 10XXXXXX 10XXXXXX
// UNICODE 코드 추출
$unicode =
(( ord($c1) & 15 ) << 12) +
(( ord($c2) & 0x3f ) << 6) +
(( ord($c3) & 0x3f ));
// 한글 인덱스
$hanindex = $unicode - $this->cho_start;
// 초성 추출
$cho=floor($hanindex / $this->cho_length);
$hanindex-=$cho * $this->cho_length;
$jung=floor($hanindex / $this->jung_length);
$hanindex-=$jung * $this->jung_length;
$jong=$hanindex;
if($jong_split==false)
$jongarr = $this->jong_char[$jong];
else
$jongarr = $this->jong_char2[$jong];
// echo $unicode." ( $cho / $jung / $jong ) <br/>";
if(strlen($jongarr)==6)
$jong_array=array(
substr($jongarr,0,3),
substr($jongarr,3,3)
);
else if(strlen($jongarr)==3)
$jong_array=array($jongarr);
else
$jong_array=array();
return array_merge(
array(
$this->cho_char[$cho],
$this->jung_char[$jung]
),
$jong_array
);
}
// 한글 조합, 한글 자소 배열을 입력, 합체된 한글 한글자를 얻습니다.
// 입력)
// $chars : 한글 자소 배열. 예) array("ㄱ", "ㅏ", "ㄹ");
// 리턴)
// 합쳐진 한글 한글자를 리턴합니다.
public function join_han($chars)
{
if(count($chars)<=1)return implode("", $chars);
// 초성이 없으면 그냥 원본 리턴
$cho=array_search($chars[0], $this->cho_char);
if($cho===false)return implode("", $chars);
// 중성이 없으면 그냥 원본 리턴
$jung=array_search($chars[1], $this->jung_char);
$jung2=array_search($chars[2], $this->jung_char);
$jong_start=2;
// 겹모음 예외 처리
if($chars[1]=="ㅗ" && $chars[2]=="ㅏ"){
$jung=array_search("ㅘ", $this->jung_char);
$jong_start++;
}
else if($chars[1]=="ㅗ" && $chars[2]=="ㅐ"){
$jung=array_search("ㅙ", $this->jung_char);
$jong_start++;
}
else if($chars[1]=="ㅗ" && $chars[2]=="ㅣ"){
$jung=array_search("ㅚ", $this->jung_char);
$jong_start++;
}
else if($chars[1]=="ㅜ" && $chars[2]=="ㅓ"){
$jung=array_search("ㅝ", $this->jung_char);
$jong_start++;
}
else if($chars[1]=="ㅜ" && $chars[2]=="ㅔ"){
$jung=array_search("ㅞ", $this->jung_char);
$jong_start++;
}
else if($chars[1]=="ㅡ" && $chars[2]=="ㅣ"){
$jung=array_search("ㅢ", $this->jung_char);
$jong_start++;
}
if($jung===false)return implode("", $chars);
// 종성은 합쳐서 조사
$jongstr="";
for($i=$jong_start;$i<count($chars);++$i)
$jongstr.=$chars[$i];
$jong=array_search($jongstr, $this->jong_char);
// 종성글자가 나눠졌을 수 있으니 한번 더 조사
if($jong===false)$jong=array_search($jongstr, $this->jong_char2);
// 종성이 있는데도 못 찾은 경우
if(strlen($jongstr)>0 && $jong===false)
{
// 종성 한글자만 찾아서 넣는다.
$jong=array_search($chars[$jong_start], $this->jong_char);
$addret="";
for($i=$jong_start+1;$i<count($chars);++$i)
$addret.=$chars[$i];
}
$unicode=$this->cho_start + $cho*$this->cho_length + $jung*$this->jung_length + $jong;
// $unicode=chr($unicode >> 8).chr($unicode & 0xff);
// XXXX XXXX XX XXXXXX
// 1110XXXX 10XXXX XX 10XXXXXX
$utf8code=
( ( ($unicode & 0xf000) << 4 ) | 0xe00000 ) +
( ( ($unicode & 0x0fc0) << 2 ) | 0x008000 ) +
( ( ($unicode & 0x003f) ) | 0x00080 );
$utf8=chr($utf8code>>16).chr(($utf8code>>8)&0xff).chr($utf8code&0xff);
return $utf8.$addret;
}
// 한글 풀어쓰기 - UTF8 전용
// 입력)
// $str : 문장 - 한영 혼용 가능
// $jong_split : 종성이 2개의 자소인 경우 분리할지 여부, ㄳ => ㄱ, ㅅ ( 기본 = false )
// 리턴)
// 풀어쓰기한 자소한글 문장을 리턴합니다.
public function hangulPuli($str, $jong_split=false)
{
$result="";
for($col=0;$col<strlen($str);++$col)
{
$c=substr($str,$col,1);
if((ord($c)&0x80)==0) // 일반 글자
$result.=$c;
else {
$c.=substr($str, $col+1, 2);
$col+=2;
$result.=implode("", $this->split_han($c, $jong_split));
}
}
return $result;
}
// 한글 조합 - UTF8 전용
// 입력)
// $str : 문장 - 한글 자소로 구성된 문장
// 리턴)
// 모아쓰기한 자소한글 문장을 리턴합니다.
public function hangulJohap($str)
{
$str=$this->hangulPuli($str, true);
// 자소 단위로 배열에 넣는다
$chars=array();
$cut=array();
for($col=0,$cnt=0;$col<strlen($str);++$col)
{
$c=substr($str,$col,1);
if((ord($c)&0x80)==0){ // 일반 글자
$chars[$cnt]=$c;
$cut[$cnt]=true;
$cnt++;
}
else {
$c.=substr($str, $col+1, 2);
$col+=2;
$chars[$cnt]=$c;
if(in_array($c, $this->jung_char)) { // 모음인 경우
// 바로 앞글자가 자음인 경우만
if(in_array($chars[$cnt-1], $this->cho_char)) {
$cut[$cnt-1]=true; // 해당 부분 커트 정의
}
}
$cnt++;
}
}
// cut 단위로 문장 재구성
$result="";
$cc=array();
for($i=0;$i<count($chars);++$i)
{
if($cut[$i]==true){
$result.=$this->join_han($cc);
$cc=array($chars[$i]);
}
else {
$cc[]=$chars[$i];
}
}
$result.=$this->join_han($cc);
return $result;
}
// 뒤에서 자소 1글자를 삭제
// 입력)
// $str : 문장
// 리턴)
// 자소 1개를 삭제한 문장을 리턴
public function str_backspace($str){
$str=$this->hangulPuli($str, true);
// 자소 단위로 배열에 넣는다
$chars=array();
for($col=0,$cnt=0;$col<strlen($str);++$col)
{
$c=substr($str,$col,1);
if((ord($c)&0x80)==0){ // 일반 글자
$chars[$cnt]=$c;
$cnt++;
}
else {
$c.=substr($str, $col+1, 2);
$col+=2;
$chars[$cnt]=$c;
$cnt++;
}
}
// 마지막 글자를 제외하고 모두 합침
$result="";
for($i=0;$i<count($chars)-1;++$i)
{
$result.=$chars[$i];
}
return $this->hangulJohap($result);
}
};
?>
그 외 수정된 소스들입니다.
이 파일은 app\Models\BookModel.php 이고
<?php namespace App\Models;
use CodeIgniter\Model;
use App\Models\CrayHangulModel;
class BookModel extends Model
{
public $db;
// 클래스 생성자
public function __construct()
{
$this->db = \Config\Database::connect("default", false);
}
public function get_query()
{
$sql = "select * FROM book";
return $this->db->query($sql);
}
// 단어 사전 만들기
public function MakeBookWord()
{
// 크레이한글 모델 클래스
$CrayHangul = new CrayHangulModel();
ini_set('memory_limit', -1);
$query_cnt = $this->db->query("SELECT count(*) as cnt FROM book");
$total = $query_cnt->getResultArray()[0]['cnt'];
$limit=1000; // 1000 건씩 끊어서 처리
$word_arr=array();
$special_chars=array(
"[", "]", "(", ")", ",", ":", ";", "<", ">",
"&", "?"
);
// 유지할 단어 + - * / . %
for($step=0;$step<$total;$step+=$limit)
{
$results = $this->db->query(
"SELECT number, title FROM book
order by number
limit $step, $limit"
)->getResultArray();
foreach($results as $result)
{
foreach($special_chars as $char){
$result['title']=str_replace($char, " ", $result['title']);
}
$explode = array_unique(explode(" ", trim($result['title'])));
foreach($explode as $word)
{
if(strlen($word)<=1)continue;
if(!empty($word_arr[$word]))$word_arr[$word].=",";
$word_arr[$word].=$result['number'];
}
}
}
echo count($word_arr)."개<br/>";
ob_flush(); flush();
$cnt=0;
$this->db->query("drop table book_search");
$this->db->query("create table book_search (
word varchar(120),
numbers text
)");
$i=0;
$this->db->transStart();
foreach($word_arr as $word=>$numbers){
$i++;
$word_puli = $CrayHangul->hangulPuli($word);
echo "$i: $word => $word_puli / ".$numbers."<br/>";
$sql="insert into book_search (word, numbers)
values ('".addslashes($word_puli)."', '".addslashes($numbers)."')";
$this->db->query($sql);
$cnt++;
if($cnt>=100)
{
$this->db->transComplete();
$this->db->transStart();
$cnt=0;
}
}
$this->db->transComplete();
$this->db->query("ALTER TABLE book_search ADD INDEX(word);");
echo "단어사전 입력이 완료되었습니다.";
}
// 책 삽입
public function BookInsert($data)
{
$set=array();
foreach($data as $fld=>$value)
$set[]="$fld='".
$this->db->escapeString($value).
"'";
$this->db->query(
"insert into book set ".
implode(", ", $set)
);
}
// 책 수정
public function BookEdit($number, $data)
{
$set=array();
foreach($data as $fld=>$value)
$set[]="$fld='".
$this->db->escapeString($value).
"'";
$this->db->query("update book set ".
implode(", ", $set).
"where number=".$number." limit 1"
);
}
// 책 삭제
public function BookDelete($number)
{
$this->db->query("delete from book
where number=".$number." limit 1"
);
}
// 검색조건에 따른 갯수, where 쿼리문 추출
public function BookSearchCount($searchword)
{
// 크레이한글 모델 클래스
$CrayHangul = new CrayHangulModel();
$searchword=$CrayHangul->hangulPuli($searchword);
$where_sql="";
if($searchword!=""){
$query_search=$this->db->query(
$sql="SELECT numbers FROM book_search
where word like '".addslashes($searchword)."%'");
$results_search = $query_search->getResultArray();
$numbers = array();
foreach($results_search as $one)
{
$tmp=explode(",", $one['numbers']);
$numbers = array_merge($numbers, $tmp);
}
$total=count($numbers);
sort($numbers);
$numbers=implode(",", $numbers);
if($numbers!="")
$where_sql="where number in ($numbers)";
else $where_sql="where 0";
}
else
{
$query_count = $this->db->query(
"SELECT count(*) FROM book $where_sql");
$results_count = $query_count->getResultArray();
$total = $results_count[0]['count(*)'];
}
return array($where_sql, $total);
}
// ajax 쿼리
function BookSearchAjax($searchword)
{
// 크레이한글 모델 클래스
$CrayHangul = new CrayHangulModel();
$searchword=$CrayHangul->hangulPuli($searchword);
$query = $this->db->query(
"SELECT numbers FROM book_search
where word like '".addslashes($searchword)."%'");
$results = $query->getResultArray();
$numbers=array();
foreach($results as $result)
$numbers=array_merge(
$numbers,
explode(",", $result['numbers']));
sort($numbers);
$numbers=implode(",", $numbers);
if($numbers=="")die();
$query = $this->db->query(
"SELECT distinct title FROM book where
number in ($numbers) limit 10");
$results = $query->getResultArray();
return $results;
}
}
단어사전을 만드는 app\Controllers\MakeBookWord2.php 파일입니다.
BookModel 클래스에 기능을 넣어버려서 아주 간단해졌습니다.
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Models\BookModel;
class MakeBookWord2 extends Controller
{
public function index()
{
// 도서에 관련된 기능이 내장된 클래스를 오브젝트 생성
$BookModel = new BookModel();
// 사전을 만드는 기능 실행
$BookModel->MakeBookWord();
}
}
책을 검색하는 목록 app\Controllers\BookList7.php 파일입니다.
검색 쿼리 부분이 BookModel 로 빠져서 좀 더 심플해졌습니다.
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Models\BookModel;
class BookList7 extends Controller
{
function get_time() {
$t=explode(" ",microtime());
return (float)$t[0]+(int)$t[1];
}
public function index()
{
$start = $this->get_time();
$db = \Config\Database::connect("default", false);
$page=$this->request->getVar("page");
$searchword=trim($this->request->getVar("searchword"));
$BookModel = new BookModel();
list($where_sql, $total)=$BookModel->BookSearchCount($searchword);
$pageview=20;
if($page=="")$page=1;
$startlimit=($page-1)*$pageview;
$totalpage = ceil($total / $pageview);
// 페이지 목록
$page_begin=$page;
if($page_begin>$totalpage-10)$page_begin=$totalpage-10;
if($page_begin<1)$page_begin=1;
$page_end=$page+9;
if($page_end>$totalpage)$page_end=$totalpage;
$pagestr="{$total}건, {$totalpage}페이지 / ";
if($page>1)
$pagestr .=
"<a href='?page=1&searchword=$searchword'
style='text-decoration:none'>처음</a> ... ";
for($i=$page_begin;$i<=$page_end;++$i){
$pagestr .=
"<a href='?page=$i&searchword=$searchword'
style='text-decoration:none'>";
if($i==$page)
$pagestr .=
"<span style='color:red;font-weight:bold'>[";
$pagestr .= "$i";
if($i==$page)$pagestr .= "</span>]";
$pagestr .= "</a> ";
}
if($i-1<$totalpage)
$pagestr .=
" ... <a href='?page=$totalpage&searchword=$searchword'
style='text-decoration:none'>끝</a>";
$query = $db->query(
"SELECT * FROM book $where_sql
order by number desc
limit $startlimit, $pageview");
$results = $query->getResultArray();
$data = [
'title'=>"도서 목록",
'booklist'=>$results,
'pagestr'=>$pagestr,
'searchword'=>$searchword
];
$end = $this->get_time();
echo "응답속도:".($end - $start)."<br/>";
return view('booklist7', $data);
}
}
타이핑할 때 실행되는 ajax 페이지 app\Conrollers\BookAjax7.php 파일도
BookModel 로 기능을 넣어버려 간단해졌습니다.
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Models\BookModel;
class BookAjax7 extends Controller
{
public function index()
{
$db = \Config\Database::connect("default", false);
$BookModel = new BookModel();
$searchword=trim($this->request->getVar("searchword"));
$results = $BookModel->BookSearchAjax($searchword);
$data = [
'booklist'=>$results
];
return view('bookajax', $data);
}
}
책목록 스킨 파일이 변경된 페이지들을 호출하기 위해 링크들이 변경되었습니다.
app\Views\booklist7.php
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
.title_style { font-size:12pt; color:blue}
.author_style { font-size:9pt; color:gray}
#preview {
top:0px;left:0px;
width:500px;height:200px;
border:1px solid black;`
background-color:white;
overflow:auto;
}
</style>
<script>
function findbook()
{
if($('#searchword').val()=='')
{
$("#preview").hide();
return;
}
$.ajax({
url: "./bookAjax7",
type: "POST",
data: {searchword : $('#searchword').val() },
dataType: "html",
success: function(data) {
$("#preview").html(data);
$("#preview").show();
}
});
}
function search_input(obj)
{
$("#searchword").val($(obj).text());
document.frm.submit();
}
</script>
<u><b><?=$title?></b></u><br/>
<?=$pagestr?>
<form name="frm" method=post action="bookList7">
제목 검색 : <input type=text name=searchword id=searchword value="<?=$searchword?>" onkeyup="findbook()">
<input type=submit value="검색">
<input type=button value="단어사전만들기" onclick="location.href='MakeBookWord2'">
<input type=button value="책 입력" onclick="location.href='bookInput'">
</form>
<div style="position:relative">
<div id="preview" style="position:absolute;display:none;background-color:white">
</div>
</div>
<hr/>
<? foreach ($booklist as $book){?>
<span class=title_style><?= $book['title']?></span>
<span class=author_style>/ <?= $book['author']?></span>
<span class=author_style>/ <a href="bookEdit?number=<?= $book['number']?>">[편집]</a></span>
<span class=author_style>/ <a href="bookDelete?number=<?= $book['number']?>">[삭제]</a></span>
<br/>
<? } ?>
<hr/>
<?=$pagestr?><br/>
여기까지가 수정된 파일의 전부인데요.
변경된 부분만 살펴보겠습니다.
제일 먼저 단어 사전을 생성하는 부분이 변경되었는데요.
단어사전을 생성하는 MakeBookWord2.php 파일의 소스에서 use 문을 제외하면 단 2줄로 단어 사전을 생성하도록 되어 있습니다. BookModel 의 MakeBookWord 메소드를 호출하는 것이지요.
use App\Models\BookModel;
:
// 도서에 관련된 기능이 내장된 클래스를 오브젝트 생성
$BookModel = new BookModel();
// 사전을 만드는 기능 실행
$BookModel->MakeBookWord();
원래 여기 있던 소스가 BookModel 에 하나의 메소드로 들어갔다고 보시면 됩니다.
// 단어 사전 만들기
public function MakeBookWord()
{
:
}
그런데 한가지 변경된 부분이 있습니다.
그건 바로 한글 풀어쓰기 인데요.
단어 사전을 만들때 한글을 풀어쓰기로 보관합니다.
아래와 같이 말이지요.
이 부분의 소스는 아래와 같습니다.
크레이 한글 클래스를 이용해서 한글풀어쓰기 기능을 적용한 다음 테이블에 저장할 때 사용하는 것이지요.
// 크레이한글 모델 클래스
$CrayHangul = new CrayHangulModel();
:
$word_puli = $CrayHangul->hangulPuli($word);
echo "$i: $word => $word_puli / ".$numbers."<br/>";
$sql="insert into book_search (word, numbers)
values ('".addslashes($word_puli)."', '".addslashes($numbers)."')";
검색하는 부분도 마찬가지입니다.
역시 BookModel 클래스의 BookSearchCount() 메소트로 관련 내용이 편입되었는데요.
검색을 시작하기 전에 먼저 풀어쓰기로 바꿔 놓고 시작합니다. 타이핑할 때 보이는 Ajax 검색도 마찬가지이지요.
public function BookSearchCount($searchword)
{
// 크레이한글 모델 클래스
$CrayHangul = new CrayHangulModel();
$searchword=$CrayHangul->hangulPuli($searchword);
변경 내용을 http://localhost/bookList7 페이지에서 작동시키면 그 결과는 아래와 같습니다.
'단ㅍ' 까지만 입력하면 '단편'으로 시작하는 도서들이 검색되고,
'블ㄹ' 까지만 입력하면 '블로그', '블록체인', '블랙', '블라드' 등의 책들이 함께 검색되는 것이지요,.
오늘도 필요하신 분에게 도움이 되셨는지 모르겠습니다 :)
즐거운 주말들 되시길 바랍니다.
여기까지 읽어주셔서 감사합니다.
'코드이그나이터와 php7와 mysql' 카테고리의 다른 글
코드이그나이터4 개발자 모드 활성화하기 (0) | 2020.10.21 |
---|---|
코드이그나이터4. 네이버검색 따라잡기-5. 영타한글 변환 검색 (0) | 2020.10.18 |
PHP '크레이한글' 클래스 - 한글 조합(오토마타) / 자소 분리 (0) | 2020.10.10 |
코드이그나이터4. 코드이그나이터답게 모델화! (0) | 2020.10.09 |
코드이그나이터4. 네이버 검색 따라잡기-3. 대용량 자료 쾌속 검색!(3) (0) | 2020.07.21 |