bool, 'data' => mixed, 'error' => string] */ function callOpenDartAPI($endpoint, $params = [], $apiKey = null, $options = []) { // API Key 로드 if ($apiKey === null) { $apiKeyPath = $_SERVER['DOCUMENT_ROOT'] . '/apikey/opendart.txt'; if (!file_exists($apiKeyPath)) { return [ 'success' => false, 'data' => null, 'error' => 'API Key file not found.' ]; } $apiKey = trim(file_get_contents($apiKeyPath)); } if (empty($apiKey)) { return [ 'success' => false, 'data' => null, 'error' => 'API Key is empty.' ]; } // 기본 옵션 $defaultOptions = [ 'timeout' => 30, 'method' => 'GET', 'return_type' => 'json', // 'json' or 'xml' or 'raw' 'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' ]; $options = array_merge($defaultOptions, $options); // 파라미터에 API 키 추가 $params['crtfc_key'] = $apiKey; // URL 구성 $baseUrl = 'https://opendart.fss.or.kr/api/'; $url = $baseUrl . $endpoint; if ($options['method'] === 'GET' && !empty($params)) { $url .= '?' . http_build_query($params); } // cURL 설정 $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_TIMEOUT, $options['timeout']); curl_setopt($ch, CURLOPT_USERAGENT, $options['user_agent']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // POST 요청 처리 (필요한 경우) if ($options['method'] === 'POST') { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); } // 실행 $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); $effectiveUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); curl_close($ch); // 에러 처리 if ($httpCode !== 200 || !$response) { $errorMsg = 'Failed to fetch data from Open DART.'; if ($curlError) { $errorMsg .= ' cURL Error: ' . $curlError; } if ($httpCode) { $errorMsg .= ' HTTP Code: ' . $httpCode; } // IP 접근 오류 체크 if ($response && (strpos($response, '접근할 수 없는 IP') !== false || strpos($response, 'Inaccessible IP') !== false)) { $xml = @simplexml_load_string($response); if ($xml && isset($xml->message)) { $errorMsg = 'IP 접근 오류: ' . (string)$xml->message; } } return [ 'success' => false, 'data' => null, 'error' => $errorMsg, 'http_code' => $httpCode, 'raw_response' => $response ]; } // 응답 처리 $data = $response; if ($options['return_type'] === 'json') { $decoded = json_decode($response, true); if ($decoded !== null) { $data = $decoded; } } elseif ($options['return_type'] === 'xml') { $xml = @simplexml_load_string($response); if ($xml !== false) { $data = $xml; } } return [ 'success' => true, 'data' => $data, 'error' => null, 'http_code' => $httpCode, 'raw_response' => $response ]; } /** * 서버의 공인 IP 확인 * * @return string 공인 IP 주소 */ function getServerPublicIP() { // Try multiple methods to get public IP $ipServices = [ 'https://api.ipify.org', 'https://checkip.amazonaws.com', 'https://icanhazip.com', 'https://ifconfig.me/ip' ]; foreach ($ipServices as $service) { $ch = curl_init($service); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $ip = trim(curl_exec($ch)); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200 && filter_var($ip, FILTER_VALIDATE_IP)) { return $ip; } } // Fallback: try to get from $_SERVER if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = trim($ips[0]); if (filter_var($ip, FILTER_VALIDATE_IP)) { return $ip; } } if (!empty($_SERVER['REMOTE_ADDR'])) { return $_SERVER['REMOTE_ADDR']; } return 'Unknown'; } ?>