개발 꿀팁/PHP

PHP 프로젝트에서 캐시된 다양한 응용 프로그램 구현

Jammie 2022. 10. 28. 12:00
반응형

1. CDN 캐시의 원리와 소개
1.각지에 여러 세트의 정적 스토리지 서비스를 배치하는 것은 본질적으로 공간 비용 교환 시간입니다.

2. CDN은 도메인과 실제 서버 사이의 연결 고리이며, cdn 노드를 추가한 후 사용자가 액세스할 때 가장 가까운 노드 내용을 자동으로 선택하며, 원본 서버는 존재하지 않습니다.

3. CDN은 본질적으로 일종의 파일 배포 시스템으로, 업데이트가 매우 적은 정적 콘텐츠를 저장하기에 적합하며, 파일 업데이트가 느립니다.

참고: cdn 파일 동기화에는 두 가지 방법이 있습니다.

첫 번째: 파일이 업데이트되면 원본 서버에서 cdn으로 내용을 푸시합니다.

두 번째: cdn의 만료 시간을 설정하고 만료 후 원본 서버에 최신 데이터를 다시 요청합니다.

일반적으로 중소기업은 알리 클라우드의 cdn 배포 시스템, 바이두 클라우드 콘텐츠 배포 네트워크 cdn 등 무료 클라우드 cdn을 채택합니다.

초대형 회사의 경우 자체적으로 cdn 시스템을 구축하는 방식이 될 수 있지만 비용이 많이 든다.



2. 데이터 파일 캐시 프로그램
원리: 업데이트 빈도가 매우 낮고 읽기 확률이 높은 데이터를 파일로 캐시하고, 획득 시 데이터베이스를 조회하지 않고 캐시된 파일의 내용을 직접 읽고 분석합니다.

코드 구현:

1. 먼저 데이터베이스를 조회하고, 조회된 데이터를 .json 정적 파일로 생성한다

public  function BannerToJson(){
    //1.데이터베이스에서대응초점도의데이터를추출해야합니다,
    $BannerModel = new  BannerBiz();
    $json = $BannerModel->GetBannerJson(7);

    //2. 데이터를 정리하여 json 형식으로 생성한다,
    $RewriteModel = new RewriteBiz();
    $result = $RewriteModel->ToJson($json);
    if ($result){
        echo "포커스 맵 생성 성공";
    }else{
        echo "초점 지도 생성 실패";
    }
}

2.이후 프런트 데스크에서 요청시 ajax에서 요청하기 전에 생성된 json 파일을 직접 생성하면 데이터베이스를 조회할 필요가 없습니다(단점:실시간성이 떨어짐)

//첫 페이지의 윤파도
$.ajax({
    url: "/json/banner.json" ,
    type: "get",
    dataType: "json",
    async: false,
    success: function(json){
        if(json != null){
            for(var i=0;i<json.length;i++){
                $('.mainpage-slideshow-top .banner').append('<a href="'+json[i].url+'"><img src="'+json[i].pic+'" </a>');
            }
        }
        },
    error: function(){
            console.log( "AJAX fail");
        }
    });

//jquery.slideshow.js 필요, 라운딩 간격 및 테마 색상 변경 가능
$(".mainpage-slideshow-top").slideShow({color: "#f10823"});

요약: 이 계획은 redis 캐시나 memcache 캐시와 유사하며, 데이터를 다른 곳에 먼저 캐시하여 빈번한 데이터베이스 조회를 피한다.

단점: 이 계획에는 실시간성이 상대적으로 떨어지는 단점이 있으며 캐시된 데이터 파일을 정기적으로 업데이트하기 위해 일정 작업을 작성하거나 다른 방법이 필요합니다.이 방법은 뉴스 사이트에 더 적합하며 정보 업데이트가 특별히 빈번하지 않습니다.



3. 전체 페이지 정적화
전체 페이지 정적화는 크게 두 가지로 나뉘는데, 하나는 smarty와 유사한 템플릿 엔진으로 구현하고 다른 하나는 ob으로 구현하며, 여기에서는 smarty 캐시와 유사한 방식으로 구현하지만 페이지 정적화를 위해 ob 방식을 사용하는 것이 좋습니다.

비고: ob 페이지 정적화

데이터 파일 캐시와 전체 페이지의 정적화 비교:

데이터 캐시 프로그램:

다만 데이터를 정적 파일로 만든 뒤 프런트 데스크에서 ajax로 데이터 캐시 파일을 요청해 데이터를 받아 사용자에게 보여준다.

전체 페이지 정적화:

데이터베이스에서 조회한 데이터와 프론트 페이지를 직접 결합하여 정적 파일을 생성하여 하드 디스크에 저장하고 사용자가 방문하면 생성된 전체 정적 페이지를 직접 요청하며 데이터베이스 조회도 없고 ajax 요청도 없으면 사용자에게 페이지를 직접 보여주면 됩니다.


코드 구현 방식:

일반적으로 cms(콘텐츠 관리 시스템)에서 사용되며, smarty와 같이 앞뒤로 분리된 아이디어를 사용하여 페이지 공유 영역을 템플릿으로 만들고 변수 영역을 남겨두고, 백그라운드에서 내용을 수정할 때 변수를 템플릿으로 대체하여 HTML을 생성합니다.사용자가 방문할 때, HTML 페이지가 직접 표시됩니다.

전체 페이지 정적화:

장점:

검색엔진 최적화(seo)에 유리하고 수록 속도도 빨라진다.

서버 부담을 줄이고 데이터베이스 요청 및 연산량을 줄입니다.

페이지 열림 속도를 높여 cdn 배포에 편리합니다.

정적 파일이기 때문에 버그와 침입을 방지했습니다.

문장류 사이트에 아주 적합합니다.

코드 구현:

컨트롤러 섹션:

/**
 * 전체 페이지 정적 코드 구현
 */
public function ChannelToHtml(){

    //1.데이터베이스에서필요한데이터를취출한다[데이터를취출하는것은일반적인첨삭개조이므로관심할필요없다]
    $channel_ids = array(1,2,3,4);
    $ChannelBiz = new ChannelBiz();
    $channel_data = array();
    foreach ($channel_ids as $channel_id) {
        //channel_id 사이클에 따라 해당 데이터를 추출하고 4개의 데이터를 동일한 배열에 넣습니다
        array_push($channel_data , $ChannelBiz->GetChannelContent($channel_id));
    }

    //2. 데이터베이스에서 가져온 병합된 데이터를 HTML 템플릿의 해당 위치로 바꾸기
    $RewriteBiz = new RewriteBiz();
    $res = $RewriteBiz -> ToHtml('channel',$channel_data);
    if ($res) {
        echo '섹션 생성 성공';
    } else {
        echo '섹션 생성 실패';
    }

}
public function ToHtml($type, $data){

if ('channel' == $type){

//1.배열을 통해 대응하는 4개의 모듈의 HTML을 가져옵니다.
$html_part = $this->GetChannelPart($data);
//2. 전체 페이지의 HTML 템플릿을 가져옵니다.
$html_template = file_get_contents(SITE_PATH.'/public/template/channel.html');
//3. 4개의 섹션을 템플릿의 해당 위치로 대체합니다.
$res_html = str_replace('<{channel_list}>', $html_part, $html_template)
// 4.합성된 html를 정적 파일로 생성한다. [fopen, fwrite, fclose 이 세트는 file_put_contens에 해당하며 비슷한 역할을 한다]
$file = fopen(SITE_PATH.'/public/channel/channel.html', 'w');
$res = fwrite($file, $res_html);
fclose($file)
if ($res) {
return true;
} else {
return false;
}
}
}
public function GetChannelPart($data ,$i = 1){
    $html = file_get_contents(SITE_PATH.'/public/template/channel_part.html');
    $res_html = '';
    foreach ($data as $channel_data) {
        $part_html = $html;
        $part_sub_channel = $part_goods = $part_goods_foot = $part_brand =  '';
        $part_html = str_replace('<{i}>',$i,$part_html);
        $part_html = str_replace('<{channel_title}>',$channel_data['Info']['title'],$part_html);
        //하위 섹션,
        foreach ($channel_data['SubChannel'] as $sub_channel) {
            $part_sub_channel .= "<li><a href=\"".$sub_channel['url']."\">".$sub_channel['title']."</a></li>";
        }
        $part_html = str_replace('<{channel_link}>',$part_sub_channel,$part_html);

        //상품 부분,
        $part_html = str_replace('<{main_goods}>','<a href="'.$channel_data['Goods'][1][0]['url'].'"><img src="'.$channel_data['Goods'][1][0]['pic_url'].'"></a>',$part_html);

        //소품 부분,
        foreach ($channel_data['Goods'][2] as $good) {
            $part_goods .=  '<li><a href="'.$good['url'].'"><p>'.$good['title'].'</p><p>'.$good['subtitle'].'</p><img src="'.$good['pic_url'].'"></a></li>';
        }
        $part_html =  str_replace('<{four_goods}>',$part_goods,$part_html);

        //소품 부분,
        foreach ($channel_data['Goods'][3] as $good) {
            $part_goods_foot .=  '<li><a href="'.$good['url'].'"><p>'.$good['title'].'</p><p>'.$good['subtitle'].'</p><img src="'.$good['pic_url'].'"></a></li>';
        }
        $part_html = str_replace('<{foot_goods}>',$part_goods_foot,$part_html);

        //브랜드,,
        foreach ($channel_data['Brand'] as $good) {
            $part_brand .=  '<li><a href="'.$good['url'].'"><img src="'.$good['pic_url'].'"></a></li>';
        }
        $part_html =  str_replace('<{brands}>',$part_brand,$part_html);
        
        $res_html .= $part_html;
        
        $i++;
        
    }

    return $res_html;

}

HTML 템플릿:

channel.html 및 channel_part.html

<!DOCTYPE html>
<html>
<head>
    <title>징시 채널 페이지</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="/static/css/reset.css">
    <link rel="stylesheet" type="text/css" href="/static/css/common.css">
    <link rel="stylesheet" type="text/css" href="/static/css/main.css">
    <link rel="icon" href="/static/img/icon.ico">
    <script type="text/javascript" src="/static/js/jquery.js"></script>
    <script type="text/javascript" src="/static/js/jquery.slideshow.js"></script>
    <script type="text/javascript" src="/static/js/jquery.smimgslide.js"></script>
    <script type="text/javascript" src="/static/js/jquery.countdown.js"></script>
    <script type="text/javascript" src="/static/js/main.js"></script>
</head>
<body>
<div class="header">
    <div class="header-nav common-container">
        <ul class="header-nav-list">
            <li><h3><a href="#">초살</a></h3></li>
            <li><h3><a href="#">쿠폰</a></h3></li>
            <li><h3><a href="#">반짝 구매하다</a></h3></li>
            <li><h3><a href="#">경매</a></h3></li>
            <li><h3><a href="#">패션타운</a></h3></li>
            <li><h3><a href="#">징시 슈퍼마켓</a></h3></li>
            <li><h3><a href="#">신선하다</a></h3></li>
            <li><h3><a href="#">글로벌 구매</a></h3></li>
            <li><h3><a href="#">징시 파이낸셜</a></h3></li>
        </ul>
    </div>
</div>
<div class="lovelife">
    <div class="common-container clearfloat lovelife-box">
        <div class="common-title">
            <i></i>
            <h2>삶을 사랑하다</h2>
            <i></i>
        </div>
        <ul class="lovelife-list clearfloat">

            <{channel_list}>


        </ul>
    </div>
</div>
<!-- footer start -->
<div class="footer">
    <div class="footer-slogans">
        <ul>
            <li class="footer-slogans-item1"><i></i>
                <h3>품종이 완비되어 손쉽게 쇼핑할 수 있다</h3></li>
            <li class="footer-slogans-item2"><i></i>
                <h3>다창직발, 빠른 배송</h3></li>
            <li class="footer-slogans-item3"><i></i>
                <h3>정품 상품, 정교한 서비스</h3></li>
            <li class="footer-slogans-item4"><i></i>
                <h3>매일 저가로 마음껏 골라 걱정 없다</h3></li>
        </ul>
    </div>
    <div class="common-container clearfloat">
        <div class="footer-sevice clearfloat">
            <table class="footer-sevice-table">
                <thead>
                <tr>
쇼핑안내 </th>
배송방식</th>
결제수단 </th>
A/S </th>
이색 서비스 </th>
</tr>
</thead>
<tbody>
<tr>
<td><ahref="#">쇼핑 프로세스</a></td>
<td><ahref="#">방문수거</a></td>
<td><ahref="#">착불</a></td>
<td><ahref="#">애프터서비스</a></td>
<td><ahref="#"> 보물섬 탈취</a></td>
</tr>
<tr>
<td><ahref="#">회원소개</a></td>
<td><ahref="#">211 한시달 </a></td>
<td><ahref="#">온라인결제</a></td>
<td><ahref="#">가격보호</a></td>
<td><ahref="#">DIY 로딩</a></td>
</tr>
<tr>
<td><ahref="#">생활여행</a></td>
<td><ahref="#">배송서비스 조회</a></td>
<td><ahref="#">할부 </a></td>
<td><ahref="#">환불 안내 </a></td>
<td><ahref="#">연보서비스</a></td>
</tr>
<tr>
<td><ahref="#">자주 묻는 질문</a></td>
<td><ahref="#">배송비 부과기준</a></td>
<td><ahref="#">우체국 입금</a></td>
<td><ahref="#">재수리/반품교환</a></td>
<td><ahref="#">징시E카드</a></td>
</tr>
<tr>
<td><ahref="#">가전</a></td>
<td><ahref="#">해외배송</a></td>
<td><ahref="#">회사이체</a></td>
<td><ahref="#">주문취소</a></td>
<td><ahref="#">경서통신</a></td>
</tr>
<tr>
<td><ahref="#">고객센터로 연락</a></td>
<td></td>
<td></td>
<td></td>
<td><ahref="#">징시JD+</a></td>
</tr>
</tbody>
</table>
<div class="footer-sevice-info">
<h5> 징시 자영 커버 구현 </h5>
<p>징시는 전국 2,654개 구와 현에 자체 배송 서비스를 제공하고 착불, POS 카드 결제 및 A/S 방문 서비스를 지원합니다. </p>
<p><ahref="#">상세보기></a></p>
</div>
</div>
<div class="footer-lists">
<ul class="footer-lists-links">
<li><ahref="#"> 우리에 대하여</a></li>
<li>|</li>
<li><ahref="#">연락주세요</a></li>
<li>|</li>
<li><ahref="#">상가 입점</a></li>
<li>|</li>
<li><ahref="#">마케팅센터</a></li>
<li>|</li>
<li><ahref="#">휴대폰 징시</a></li>
<li>|</li>
<li><ahref="#">우정링크</a></li>
<li>|</li>
<li><ahref="#">판매조합</a></li>
<li>|</li>
<li><ahref="#">징시커뮤니티</a></li>
<li>|</li>
<li><ahref="#">리스크 모니터링</a></li>
<li>|</li>
<li><ahref="#">경서공익</a></li>
<li>|</li>
<li><ahref="#">English Site</a></li>
<li>|</li>
<li><ahref="#">ContactUs</a></li>
</ul>
<br>
<ul class="footer-lists-line1">
<li><ahref="#">경공망정비 11000002000088호</a></li>
<li>|</li>
<li>경ICP증070359호</li>
<li>|</li>
<li><ahref="#">인터넷의약품정보서비스자격증번호(경)-영업성-2014-0008</a></li>
<li>|</li>
<li>신출발경자제대120007호</li>
</ul>
<br>
<ul class="footer-lists-line2">
<li>인터넷출판허가증번호 신출망증(경)자 150호</li>
<li>|</li>
<li><ahref="#"> 출판물 영업 허가증 </a></li>
<li>|</li>
<li><ahref="#">인터넷문화경영허가증경닷컴[2014]2148-348호</a></li>
<li>|</li>
<li> 위법 및 불량정보 신고전화 : 4006561155</li>
</ul>
<br>
<ul class="footer-lists-line3">
<li>Copyright &copy; 2004 - 2016 징시 JD.com 저작권 소유 </li>
<li>|</li>
<li> 소비자 권리 보호 핫라인: 4006067733&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;<ahref="#">> 사업자등록
</ul>
<br>
<ul class="footer-lists-line4">
<li> 징시닷컴: <ahref="#"> 징시지갑</a></li>
<li>|</li>
<li><ahref="#">경서운</a></li>
</ul>
<br>
<ul class="footer-lists-icons">
<li class="footer-lists-icons-item1"><ahref="#"></a></li>
<li class="footer-lists-icons-item2"><ahref="#"></a></li>
<li class="footer-lists-icons-item3"><ahref="#"></a></li>
<li class="footer-lists-icons-item4"><ahref="#"></a></li>
<li class="footer-lists-icons-item5"><ahref="#"></a></li>
<li class="footer-lists-icons-item6"><ahref="#"></a></li>
</ul>
</div>
</div>
</div>
<!
-- footer end -->
</body>
</html>
<li class="lovelife-list-item<{i}> lovelife-list-col2  sidebarpointer" >

    <div class="lovelife-list-title">
        <h3><{channel_title}> </h3>
        <ul>
            <{channel_link}>
        </ul>
    </div>
    <div class="lovelife-list-content">
        <div class="lovelife-list-content-box">
            <div class="lovelife-list-content-leimg">
                <{main_goods}>
            </div>
            <ul class="lovelife-list-content-riimg">
                <{four_goods}>
                      </ul>
            <ul class="lovelife-list-content-mdimg">
                <{foot_goods}>
            </ul>
        </div>
    </div>
    <div class="lovelife-list-smimg">
        <span class="lovelife-list-smimg-leftarrow">&lt;</span>
        <span class="lovelife-list-smimg-rightarrow">&gt;</span>
        <div class="lovelife-list-smimg-box">
            <ul>
                <{brands}>
            </ul>
        </div>
    </div>


</li>

이로써 smarty와 같은 전 페이지 정적화 작업이 완료되었다

 

반응형