나이스 공공API를 사용하여 학교 급식 및 시간표를 불러오기 (PHP)

이 글은 TISTORY에서 발행되어 이전된 글 입니다.

이번에 STUZM을 개발하며 기능 중 하나로 급식 및 시간표를 보여주는 기능을 넣게 되어, 해당 기능을 어떻게 개발했는지 한번 적어보려 합니다 :) 제가 사용한 API는 나이스에서 제공하는 공공 API이며 나이스 교육정보 개방포털에서 API 키를 발급 받아 누구나 손쉽게 사용 가능합니다.

학교 코드 불러오기

$xmlfile = 'https://open.neis.go.kr/hub/schoolInfo?ATPT_OFCDC_SC_CODE=K10&SCHUL_NM='.$member['school'];
$sch_api_load = simplexml_load_file($xmlfile) or die("급식 정보를 불러오지 못했습니다!");
        
$serial = 1;
foreach ($sch_api_load as $sch_api):
	$sch_code  =  $sch_api->SD_SCHUL_CODE;     
	$serial++;
endforeach;

급식과 시간표 정보를 받아오기 전 학교 코드부터 불러오는 것이 먼저이겠죠.

XML 방식을 사용해 나이스 학교기본정보 API를 사용했습니다. $xmlfile 변수의 $member[“school”] 부분은 DB에서 사용자 계정에 저장된 school 값을 불러오는 부분으로, 원래는 학교 이름이 들어가는 부분입니다.

또한 URL 중 ATPT_OFCDC_SC_CODE 부분 값이 K10인데요. 이 부분은 도교육청 코드가 들어가야하는 부분이며, 강원도교육청 코드가 K10이므로 K10을 넣었습니다.

급식 불러오기

$date = $resultDate;

$xmlfile = 'https://open.neis.go.kr/hub/mealServiceDietInfo?ATPT_OFCDC_SC_CODE=K10&SD_SCHUL_CODE='.$sch_code.'&MLSV_YMD='.$date.'&KEY=비밀';
$food_api = simplexml_load_file($xmlfile) or die("급식 정보를 불러오지 못했습니다!");
$serial = 1;
$found = false;

foreach ($food_api as $food):
	$date_api  =  $food->MLSV_YMD;
	$menu  =  $food->DDISH_NM;
	$cal  =  $food->CAL_INFO;
	if($date == $date_api) {
		echo $menu;
		$found = true; 
		echo '<div style="margin-top: 10px;font-size:12px;color:gray;">'.$cal.'</div>';
	}
	$serial++;
endforeach;

if (!$found) {
	echo "급식이 없는 날입니다.";
}

나이스 급식식단정보 API를 사용하여 급식 식단을 불러오게 해두었습니다. $date 변수에 원하는 날짜를 넣고, $sch_code 변수에 학교 코드를 넣어 사용하면 됩니다. 기본적으로 메뉴와 칼로리를 같이 불러오는데요, API 상에서 더 많은 정보가 있지만 딱 필요한 정보들(메뉴, 칼로리)만 골라서 가져왔습니다.

시간표 불러오기

<?php
foreach ($sch_api_load as $sch_api):
    $sch_code = $sch_api->SD_SCHUL_CODE;
endforeach;

$date = $resultDate;
$xmlfile = 'https://open.neis.go.kr/hub/hisTimetable?ATPT_OFCDC_SC_CODE=K10&SD_SCHUL_CODE=' . $sch_code . '&GRADE=' . $grade . '&CLASS_NM=' . $room . '&ALL_TI_YMD=' . $date . '&KEY=비밀';
$schedule_api = simplexml_load_file($xmlfile) or die("시간표를 불러오지 못했습니다");

$serial = 1;
$found = false;
$judge = $schedule_api->MESSAGE;

if (!$judge) {
    $ymd = date('m월d일');
    echo '<div id="schedule">';

    foreach ($schedule_api as $schedule):
        $date_api = $schedule->ALL_TI_YMD;
        $period = $schedule->PERIO;
        $subject = $schedule->ITRT_CNTNT;

        if ($date == $date_api) {
            echo '
            <div class="d_flex sche">
                <div class="period">' . $period . '교시</div>
                <div class="subject">' . $subject . '</div>
            </div>';
            $found = true;
        }
        $serial++;
    endforeach;

    echo "</div>";
} else if (!$judge) {
    echo '
    <br>
    <center>불러온 시간표가 없어요.</center>
    ';
}
?>

사실 시간표를 불러오는 과정도 급식 불러오는 과정과 크게 다르지 않습니다. 그냥 불러오는 링크를 나이스 고등학교 시간표 API로 바꾸면 되기 때문입니다. 참, 쉽죠?

여담

사실 이 방식을 막상 적용하고 한번에 5개를 표시하려 하니까 속도가 2~3초 가량 걸렸습니다. 속도를 개선하려고 XML 캐시 같은 것도 사용해봤는데 여전히 느리더라구요. 고민하다가 로딩페이지를 넣었는데 아닌거 같아서 빼고, 요일을 선택하게 해서 1개씩 표시하는 방법으로 바꿨습니다. 그래도 1개 표시하는건 그렇게 느리지 않더라구요 😅