Posted By

iroybot on 09/30/09


Tagged

curl php read external fallback fileread fsock


Versions (?)

Who likes this?

2 people have marked this snippet as a favorite

iroybot
nerdfiles


Reading external files - the safe way


 / Published in: PHP
 

this comes from YAPB plugin for WordPress. kudos to the author. (there are some functions that are deprecated in PHP 5.2+ - you'll need to replace eregi with the mb_ version). This should be quite failsafe, regardless if curl is installed or the settings in your php.ini (allowurlfopen), etc.

  1. <?php
  2. /**
  3.  * sicheres einlesen externer Dateien
  4.  */
  5. private function URLreadFsock($host, $file, &$errstr, $successonly=true, $port=80, $timeout=10) {
  6. if (!function_exists('fsockopen')) {
  7. $errstr = 'fsockopen() unavailable';
  8. return false;
  9. }
  10. if ($fp = @fsockopen($host, 80, $errno, $errstr, $timeout)) {
  11. $out = 'GET '.$file.' HTTP/1.0'."
  12. ";
  13. $out .= 'Host: '.$host."
  14. ";
  15. $out .= 'Connection: Close'."
  16.  
  17. ";
  18. fwrite($fp, $out);
  19.  
  20. $isHeader = true;
  21. $Data_header = '';
  22. $Data_body = '';
  23. $header_newlocation = '';
  24. while (!feof($fp)) {
  25. $line = fgets($fp, 1024);
  26. if ($isHeader) {
  27. $Data_header .= $line;
  28. } else {
  29. $Data_body .= $line;
  30. }
  31. if (eregi('^HTTP/[\\.0-9]+ ([0-9]+) (.+)$', rtrim($line), $matches)) {
  32. list($dummy, $errno, $errstr) = $matches;
  33. $errno = intval($errno);
  34. } elseif (eregi('^Location: (.*)$', rtrim($line), $matches)) {
  35. $header_newlocation = $matches[1];
  36. }
  37. if ($isHeader && ($line == "
  38. ")) {
  39. $isHeader = false;
  40. if ($successonly) {
  41. switch ($errno) {
  42. case 200:
  43. // great, continue
  44. break;
  45.  
  46. default:
  47. $errstr = $errno.' '.$errstr.($header_newlocation ? '; Location: '.$header_newlocation : '');
  48. fclose($fp);
  49. return false;
  50. break;
  51. }
  52. }
  53. }
  54. }
  55. fclose($fp);
  56. return $Data_body;
  57. }
  58. return null;
  59. }
  60.  
  61.  
  62. private function ParseURLbetter($url) {
  63. $parsedURL = @parse_url($url);
  64. if (!@$parsedURL['port']) {
  65. switch (strtolower(@$parsedURL['scheme'])) {
  66. case 'ftp':
  67. $parsedURL['port'] = 21;
  68. break;
  69. case 'https':
  70. $parsedURL['port'] = 443;
  71. break;
  72. case 'http':
  73. $parsedURL['port'] = 80;
  74. break;
  75. }
  76. }
  77. return $parsedURL;
  78. }
  79.  
  80. private function _getVersionFile($url, &$error, $timeout=10, $followredirects=true) {
  81. $error = '';
  82.  
  83. $parsed_url = $this->ParseURLbetter($url);
  84. $alreadyLookedAtURLs[trim($url)] = true;
  85.  
  86. while (true) {
  87. $tryagain = false;
  88. $rawData = $this->URLreadFsock(@$parsed_url['host'], @$parsed_url['path'].'?'.@$parsed_url['query'], $errstr, true, (@$parsed_url['port'] ? @$parsed_url['port'] : 80), $timeout);
  89. if (eregi('302 [a-z ]+; Location\\: (http.*)', $errstr, $matches)) {
  90. $matches[1] = trim(@$matches[1]);
  91. if (!@$alreadyLookedAtURLs[$matches[1]]) {
  92. // loop through and examine new URL
  93. $error .= 'URL "'.$url.'" redirected to "'.$matches[1].'"';
  94.  
  95. $tryagain = true;
  96. $alreadyLookedAtURLs[$matches[1]] = true;
  97. $parsed_url = $this->ParseURLbetter($matches[1]);
  98. }
  99. }
  100. if (!$tryagain) {
  101. break;
  102. }
  103. }
  104.  
  105. if ($rawData === false) {
  106. $error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
  107. return false;
  108. } elseif ($rawData === null) {
  109. // fall through
  110. $error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
  111. } else {
  112. return trim($rawData);
  113. }
  114.  
  115. // curl
  116. if (function_exists('curl_version')) {
  117. $ch = curl_init();
  118. curl_setopt($ch, CURLOPT_URL, $url);
  119. curl_setopt($ch, CURLOPT_HEADER, false);
  120. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  121. curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
  122. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  123. $rawData = curl_exec($ch);
  124. curl_close($ch);
  125. if (strlen($rawData) > 0) {
  126. $error .= 'CURL succeeded ('.strlen($rawData).' bytes); ';
  127. return trim($rawData);
  128. }
  129. $error .= 'CURL available but returned no data; ';
  130. } else {
  131. $error .= 'CURL unavailable; ';
  132. }
  133.  
  134. // fopen
  135. $BrokenURLfopenPHPversions = array('4.4.2');
  136. if (in_array(phpversion(), $BrokenURLfopenPHPversions)) {
  137. $error .= 'fopen(URL) broken in PHP v'.phpversion().'; ';
  138. } elseif (@ini_get('allow_url_fopen')) {
  139. $rawData = '';
  140. $error_fopen = '';
  141. if ($fp = fopen($url, 'rb')) {
  142. do {
  143. $buffer = fread($fp, 8192);
  144. $rawData .= $buffer;
  145. } while (strlen($buffer) > 0);
  146. fclose($fp);
  147. } else {
  148. $error_fopen .= trim(strip_tags(ob_get_contents()));
  149. }
  150. $error .= $error_fopen;
  151. if (!$error_fopen) {
  152. $error .= '; "allow_url_fopen" succeeded ('.strlen($rawData).' bytes); ';
  153. return trim($rawData);
  154. }
  155. $error .= '; "allow_url_fopen" enabled but returned no data ('.$error_fopen.'); ';
  156. } else {
  157. $error .= '"allow_url_fopen" disabled; ';
  158. }
  159. return false;
  160. }

Report this snippet  

You need to login to post a comment.