stream_socket_client() 경고에 대한 수정을 하고 싶습니다. 채택완료
아래의 소스는 온라인 문의가 들어왔을 때 관리자에게 문자를 보내는 코드중 일부입니다.
php 5인 서버를 사용할 때는 에러메세지가 나오지 않았는데
php 7인 서버를 사용중인 지금은 에러메시지가 나옵니다. (이전 서버와 현서버의 차이가 php 버전뿐이라 이렇게 짐작하고 있습니다.)
이 코드를 사용하면 아래의 소스중 빨간 색 라인에서 에러가 나오는데 어떻게 수정해야할지
고수님들에게 도움을 요청드립니다.
참고로 에러메세지는 나오는데 문자메세지의 발송은 잘 되고 있습니다.
Warning: stream_socket_client(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /home/cunet/public_html/bbs/online_update.php on line 115
Warning: stream_socket_client(): unable to connect to ssl://www.k-db.kr:20443 (php_network_getaddresses: getaddrinfo failed: Name or service not known) in /home/cunet/public_html/bbs/online_update.php on line 115
Warning: fwrite() expects parameter 1 to be resource, bool given in /home/cunet/public_html/bbs/online_update.php on line 116
Warning: fread() expects parameter 1 to be resource, bool given in /home/cunet/public_html/bbs/online_update.php on line 118
Warning: fclose() expects parameter 1 to be resource, bool given in /home/cunet/public_html/bbs/online_update.php on line 122
--- 에러가 나는 부분 ---
$h=stream_socket_client($host_url);
fwrite($h,$post);
for($a=0,$r='';!$a;) {
$b=fread($h,8192);
$r.=$b;
$a=(($b=='')?1:0);
}
fclose($h);
return $r;
전체소스---
</p>
<p> function post($host,$query,$method='POST') {
$ref_url = ($_SERVER["HTTPS"])?"<a href="https://":"http://";" target="_blank" rel="noopener noreferrer">https://":"http://";</a>
$ref_url .= $_SERVER['HTTP_HOST'];
//echo $host;
$url = parse_url($host);
if(!$url['scheme']) {
$host = "<a href="http://$host";" target="_blank" rel="noopener noreferrer">http://$host";</a>
$url = parse_url($host);
}
if($url['scheme']=="https") $host_url = "ssl://$url[host]";
else $host_url = "tcp://$url[host]";
if($url['port']) $host_url .= ":$url[port]";
elseif($url['scheme']=="https") $host_url .= ":443";
else $host_url .= ":80";
if($url['query']==NULL) $path = $url['path'];
else $path = "$url[path]?$url[query]";
$post="$method $path HTTP/1.1\r\nHost: $url[host]\r\nReferer: $ref_url\r\nContent-type: application/x-www-form-urlencoded\r\n${others}User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";</p>
<p> <strong><span style="color:#e74c3c;">$h=stream_socket_client($host_url);
fwrite($h,$post);</span></strong>
for($a=0,$r='';!$a;) {
<strong><span style="color:#e74c3c;">$b=fread($h,8192);</span></strong>
$r.=$b;
$a=(($b=='')?1:0);
}
<span style="color:#e74c3c;"><strong>fclose($h);</strong></span>
return $r;
}</p>
<p>
미리 감사드립니다. (^^)(__)
답변 3개
PHP 7에서는 stream_socket_client() 사용 시
도메인 이름 확인 및 네트워크 주소 변환 문제로 인해
php_network_getaddresses: getaddrinfo failed 오류가 발생할 수 있음.
- 네트워크 문제,
- 도메인 네임 서버(DNS) 해석 문제,
- stream_socket_client()의 오류 처리 부족 등의 문제일 가능성이 있음.
※ 수정 방안 :
*에러 핸들링 추가: stream_socket_client()의 반환값이 false일 경우 예외를 던지도록 수정.
*타임아웃 설정: stream_socket_client() 호출 시 timeout 값을 명시하여
네트워크 문제를 줄임.
*에러 출력: stream_socket_client()의 error_message를 받아 로깅.
*DNS 확인: gethostbyname()을 사용하여 호스트 주소를 직접 확인하고,
IP가 반환되지 않으면 오류를 출력.
※ 코드에서 stream_socket_client() 호출 전 도메인 주소가 올바르게 변환되었는지 확인하고,
실패할 경우 적절한 오류 메시지를 반환하도록 개선 함.
function post($host, $query, $method = 'POST') {
$ref_url = ($_SERVER["HTTPS"]) ? "https://" : "http://";
$ref_url .= $_SERVER['HTTP_HOST'];
$url = parse_url($host);
if (!$url['scheme']) {
$host = "http://$host";
$url = parse_url($host);
}
if ($url['scheme'] == "https") {
$host_url = "ssl://$url[host]";
$port = isset($url['port']) ? $url['port'] : 443;
} else {
$host_url = "tcp://$url[host]";
$port = isset($url['port']) ? $url['port'] : 80;
}
$host_url .= ":$port";
if (empty($url['query'])) {
$path = $url['path'];
} else {
$path = "$url[path]?$url[query]";
}
$post = "$method $path HTTP/1.1\r\n"
. "Host: $url[host]\r\n"
. "Referer: $ref_url\r\n"
. "Content-type: application/x-www-form-urlencoded\r\n"
. "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36\r\n"
. "Content-length: " . strlen($query) . "\r\n"
. "Connection: close\r\n\r\n"
. $query;
// 호스트의 IP 변환 및 확인
$ip = gethostbyname($url['host']);
if ($ip == $url['host']) {
return "Error: Could not resolve host: " . $url['host'];
}
// 타임아웃 및 에러 핸들링 추가
$errstr = "";
$errno = 0;
$h = @stream_socket_client($host_url, $errno, $errstr, 10); // 10초 타임아웃 설정
if (!$h) {
return "Error: stream_socket_client() failed - $errstr ($errno)";
}
fwrite($h, $post);
$r = "";
while (!feof($h)) {
$r .= fread($h, 8192);
}
fclose($h);
return $r;
}
*수정 코드의 주요 개선 사항 :
- stream_socket_client() 호출 전에 gethostbyname($url['host'])를 사용하여
도메인 해석이 가능한지 확인.
- 도메인 해석이 실패할 경우 오류 메시지를 반환하여 추가적인 문제를 방지.
- stream_socket_client()의 timeout을 10초로 설정하여,
응답이 지연될 경우 무한 대기하지 않도록 개선.
- stream_socket_client() 호출 시 발생하는 errno, errstr을 받아서 에러 메시지를 출력.
- @ 연산자를 사용하여 경고를 억제하고, 대신 직접 if (!$h) 조건으로 에러 메시지를 처리.
- 기존 코드에서 $b == ''을 검사하는 대신, 더 안정적인 feof($h)로 루프를 종료하도록 수정.
답변에 대한 댓글 2개
^^ 행복하세요!
댓글을 작성하려면 로그인이 필요합니다.
stream_socket_client 부분을 수정해보세요.
</p>
<p> $context = stream_context_create([</p>
<p> 'ssl' => [</p>
<p> 'verify_peer' => false,</p>
<p> 'verify_peer_name' => false,</p>
<p> ]</p>
<p> ]);</p>
<p> $h = stream_socket_client($host_url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);</p>
<p>
답변에 대한 댓글 1개
코드를 그대로 붙여보았는데
똑같은 줄 똑같은 경고 메시지가 나옵니다.
댓글을 작성하려면 로그인이 필요합니다.
답변에 대한 댓글 1개
근본적인 수정법을 알고 싶긴한데 당장 에러메시지가 안나오니 다행이긴 합니다.
감사합니다.
댓글을 작성하려면 로그인이 필요합니다.
답변을 작성하려면 로그인이 필요합니다.
로그인
답변주신대로 수정하니 경고가 사라지고 문자메시지도 잘 들어 옵니다!!
복 많이 받으세요!