{"id":378,"date":"2021-10-29T15:32:13","date_gmt":"2021-10-29T06:32:13","guid":{"rendered":"https:\/\/blog.mydepot.kr\/?p=378"},"modified":"2021-10-29T15:33:12","modified_gmt":"2021-10-29T06:33:12","slug":"php-%ed%8c%8c%ec%9d%bc-%eb%8b%a4%ec%9a%b4%eb%a1%9c%eb%93%9c-%ec%8a%a4%ed%81%ac%eb%a6%bd%ed%8a%b8-%ec%9d%b4%ec%96%b4%eb%b0%9b%ea%b8%b0-%ec%86%8d%eb%8f%84%ec%a0%9c%ed%95%9c","status":"publish","type":"post","link":"https:\/\/blog.mydepot.kr\/?p=378","title":{"rendered":"[PHP] \ud30c\uc77c \ub2e4\uc6b4\ub85c\ub4dc \uc2a4\ud06c\ub9bd\ud2b8 (\uc774\uc5b4\ubc1b\uae30, \uc18d\ub3c4\uc81c\ud55c)"},"content":{"rendered":"<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nif(send_attachment(&#039;\uc800\uc7a5\ud30c\uc77c\uc774\ub984&#039;, &quot;\ud30c\uc77c\uacbd\ub85c&quot;, 60 * 60 * 24, 10000) === true){\n      exit;\n}else{\n      echo &quot;download failed&quot;;\n}\n\n\/\/ \ucd9c\ucc98: https:\/\/gist.github.com\/ssut\/a3d97c7a35e5458687ed\nfunction send_attachment($filename, $server_filename, $expires = 0, $speed_limit = 0){\n      $remote = false;\n\n      \/\/ check filename\n      if (strpos($server_filename, &#039;http&#039;) === false) {\n            if (!file_exists($server_filename) || !is_readable($server_filename)) {\n                  return false;\n            }\n            if (($filesize = filesize($server_filename)) == 0) {\n                  return false;\n            }\n            if (($fp = @fopen($server_filename, &#039;rb&#039;)) === false) {\n                  return false;\n            }\n      } else {\n            $remote = true;\n            $handle = curl_init($server_filename);\n            curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);\n            curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true);\n            curl_setopt($handle, CURLOPT_HEADER, true);\n            curl_setopt($handle, CURLOPT_NOBODY, true);\n\n            $response = curl_exec($handle);\n\n            $http_code = curl_getinfo($handle, CURLINFO_HTTP_CODE);\n            if ($http_code == 404) {\n                  return false;\n            }\n\n            $filesize = curl_getinfo($handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD);\n            curl_close($handle);\n\n            $ch = curl_init($server_filename);\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);\n            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);\n      }\n\n      $pass_remote = function ($ch, $chunk) {\n            echo $chunk;\n            flush();\n            return strlen($chunk);\n      };\n\n      \/\/ replace special characters\n      $illegal = array(&#039;\\\\&#039;, &#039;\/&#039;, &#039;&lt;&#039;, &#039;&gt;&#039;, &#039;{&#039;, &#039;}&#039;, &#039;:&#039;, &#039;;&#039;, &#039;|&#039;, &#039;&quot;&#039;, &#039;~&#039;, &#039;`&#039;, &#039;@&#039;, &#039;#&#039;, &#039;$&#039;, &#039;%&#039;, &#039;^&#039;, &#039;&amp;&#039;, &#039;*&#039;, &#039;?&#039;);\n      $replace = array(&#039;&#039;, &#039;&#039;, &#039;(&#039;, &#039;)&#039;, &#039;(&#039;, &#039;)&#039;, &#039;_&#039;, &#039;,&#039;, &#039;_&#039;, &#039;&#039;, &#039;_&#039;, &#039;\\&#039;&#039;, &#039;_&#039;, &#039;_&#039;, &#039;_&#039;, &#039;_&#039;, &#039;_&#039;, &#039;_&#039;, &#039;&#039;, &#039;&#039;);\n      $filename = str_replace($illegal, $replace, $filename);\n      $filename = preg_replace(&#039;\/(&#x5B;\\\\x00-\\\\x1f\\\\x7f\\\\xff]+)\/&#039;, &#039;&#039;, $filename);\n\n      \/\/ replace special spaces to normal spaces(0x20).\n      $filename = trim(preg_replace(&#039;\/&#x5B;\\\\pZ\\\\pC]+\/u&#039;, &#039; &#039;, $filename));\n\n      \/\/ remove duplicates or dots.\n      $filename = trim($filename, &#039; .-_&#039;);\n      $filename = preg_replace(&#039;\/__+\/&#039;, &#039;_&#039;, $filename);\n      if ($filename === &#039;&#039;) {\n            return false;\n      }\n\n      \/\/ get User-Agent from browser\n      $ua = isset($_SERVER&#x5B;&#039;HTTP_USER_AGENT&#039;]) ? $_SERVER&#x5B;&#039;HTTP_USER_AGENT&#039;] : &#039;&#039;;\n      $old_ie = (bool)preg_match(&#039;#MSIE &#x5B;3-8]\\.#&#039;, $ua);\n\n      \/\/ add filename to header when filename only includes normal characters.\n      if (preg_match(&#039;\/^&#x5B;a-zA-Z0-9_.-]+$\/&#039;, $filename)) {\n            $header = &#039;filename=&quot;&#039; . $filename . &#039;&quot;&#039;;\n      }\n      \/\/ &lt; IE 9 or &lt; FF 5\n      elseif ($old_ie || preg_match(&#039;#Firefox\/(\\d+)\\.#&#039;, $ua, $matches) &amp;&amp; $matches&#x5B;1] &lt; 5) {\n            $header = &#039;filename=&quot;&#039; . rawurlencode($filename) . &#039;&quot;&#039;;\n      }\n      \/\/ &lt; Chrome 11\n      elseif (preg_match(&#039;#Chrome\/(\\d+)\\.#&#039;, $ua, $matches) &amp;&amp; $matches&#x5B;1] &lt; 11) {\n            $header = &#039;filename=&#039; . $filename;\n      }\n      \/\/ &lt; Safari 6\n      elseif (preg_match(&#039;#Safari\/(\\d+)\\.#&#039;, $ua, $matches) &amp;&amp; $matches&#x5B;1] &lt; 6) {\n            $header = &#039;filename=&#039; . $filename;\n      }\n      \/\/ Android\n      elseif (preg_match(&#039;#Android #&#039;, $ua, $matches)) {\n            $header = &#039;filename=&quot;&#039; . $filename . &#039;&quot;&#039;;\n      }\n      \/\/ other browsers assume that validate RFC\/2231\/5987 standards\n      \/\/ but, add old style filename information for special circumstances\n      else {\n            $header = &quot;filename*=UTF-8&#039;&#039;&quot; . rawurlencode($filename) . &#039;; filename=&quot;&#039; . rawurlencode($filename) . &#039;&quot;&#039;;\n      }\n\n      \/\/ cache is disallowed by client\n      if (!$expires) {\n            \/\/ Cannot use no-cache and pragma header when use old IE versions(&lt;= 8) and SSL.\n            if ($old_ie) {\n                  header(&#039;Cache-Control: private, must-revalidate, post-check=0, pre-check=0&#039;);\n                  header(&#039;Expires: Sat, 01 Jan 2000 00:00:00 GMT&#039;);\n            } else {\n                  header(&#039;Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0&#039;);\n                  header(&#039;Expires: Sat, 01 Jan 2000 00:00:00 GMT&#039;);\n            }\n      }\n      \/\/ cache is allowed by client\n      else {\n            header(&#039;Cache-Control: max-age=&#039; . (int)$expires);\n            header(&#039;Expires: &#039; . gmdate(&#039;D, d M Y H:i:s&#039;, time() + (int)$expires) . &#039; GMT&#039;);\n      }\n\n      \/\/ process range header for resume download\n      if (isset($_SERVER&#x5B;&#039;HTTP_RANGE&#039;]) &amp;&amp; preg_match(&#039;\/^bytes=(\\d+)-\/&#039;, $_SERVER&#x5B;&#039;HTTP_RANGE&#039;], $matches)) {\n            $range_start = $matches&#x5B;1];\n            if ($range_start &lt; 0 || $range_start &gt; $filesize) {\n                  header(&#039;HTTP\/1.1 416 Requested Range Not Satisfiable&#039;);\n                  return false;\n            }\n            header(&#039;HTTP\/1.1 206 Partial Content&#039;);\n            header(&#039;Content-Range: bytes &#039; . $range_start . &#039;-&#039; . ($filesize - 1) . &#039;\/&#039; . $filesize);\n            header(&#039;Content-Length: &#039; . ($filesize - $range_start));\n            if ($remote) {\n                  curl_setopt($ch, CURLOPT_WRITEFUNCTION, $pass_remote);\n                  curl_setopt($ch, CURLOPT_RANGE, $range_start . &#039;-&#039; . ($filesize - 1));\n            }\n      } else {\n            $range_start = 0;\n            header(&#039;Content-Length: &#039; . $filesize);\n\n            if ($remote) {\n                  curl_setopt($ch, CURLOPT_WRITEFUNCTION, $pass_remote);\n                  curl_setopt($ch, CURLOPT_RANGE, &#039;0-&#039; . $filesize);\n            }\n      }\n\n      \/\/ send other headers.\n      header(&#039;Accept-Ranges: bytes&#039;);\n      header(&#039;Content-Type: application\/octet-stream&#039;);\n      header(&#039;Content-Disposition: attachment; &#039; . $header);\n\n      \/\/ clear output buffer.\n      \/\/ (blocks file broken and decrease memory usage)\n      while (ob_get_level()) {\n            ob_end_clean();\n      }\n\n      \/\/ send a file each 64KB and clear output buffer.\n      \/\/ sometimes occurs memory leak when use readfile() function.\n      $block_size = 16 * 1024;\n      $speed_sleep = $speed_limit &gt; 0 ? round(($block_size \/ $speed_limit \/ 1024) * 1000000) : 0;\n\n      $buffer = &#039;&#039;;\n      if ($range_start &gt; 0 &amp;&amp; !$remote) {\n            fseek($fp, $range_start);\n            $alignment = (ceil($range_start \/ $block_size) * $block_size) - $range_start;\n            if ($alignment &gt; 0) {\n                  $buffer = fread($fp, $alignment);\n                  echo $buffer;\n                  unset($buffer);\n                  flush();\n            }\n      }\n      while (!feof($fp) &amp;&amp; !$remote) {\n            $buffer = fread($fp, $block_size);\n            echo $buffer;\n            unset($buffer);\n            flush();\n            usleep($speed_sleep);\n      }\n\n      if ($remote &amp;&amp; $ch) {\n            curl_exec($ch);\n      }\n\n      if (!$remote) {\n            fclose($fp);\n      } else {\n            curl_close($ch);\n      }\n\n      \/\/ true when successfully sent.\n      return true;\n}\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"no","_lmt_disable":"","footnotes":""},"categories":[8],"tags":[165,168,169],"class_list":["post-378","post","type-post","status-publish","format-standard","hentry","category-php","tag-165","tag-168","tag-169"],"modified_by":"\ucc38\ube5b\ubc14\ub2e4","_links":{"self":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts\/378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=378"}],"version-history":[{"count":2,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts\/378\/revisions"}],"predecessor-version":[{"id":380,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts\/378\/revisions\/380"}],"wp:attachment":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}