/** * 書き込み中の不完全なファイル内容が読み取られることのないように、一時ファイルに書き込んでからリネームする * ※ただし、Windowsの場合は、上書きrenameが不完全となるので直接書き込むこととする * * @static * @access public * @param string $tmp_dir 一時保存ディレクトリ * @return boolean 実行成否 (成功時に書き込みバイト数を返す意味ってほとんどない気がする) */ function filePutRename($file, $cont, $tmp_dir = null) { if (strlen($file) == 0) { trigger_error(__CLASS__ . '::' . __FUNCTION__ . '(), file is null', E_USER_WARNING); return false; } $win = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? true : false; // 一時ファイルパスを決める $prefix = 'rename_'; // 一時ディレクトリの明示指定がある場合 if ($tmp_dir) { // strlen($tmp_dir) > 0 とすべきところだが、むしろ"0"もなしということにしてみる if (!is_dir($tmp_dir)) { trigger_error(__FUNCTION__ . "() -> is_dir({$tmp_dir}) failed.", E_USER_WARNING); return false; } } else { if (isset($GLOBALS['_conf']['tmp_dir'])) { $tmp_dir = $GLOBALS['_conf']['tmp_dir']; if (!is_dir($tmp_dir)) { FileCtl::mkdirR($tmp_dir); } } else { // 2006/10/05 php_get_tmpdir() は might be only in CVS if (function_exists('php_get_tmpdir')) { $tmp_dir = php_get_tmpdir(); } else { // これで動作はするが、null指定でも大丈夫かな。2007/01/22 WinではNG?未確認 $tmp_dir = null; } } } $write_file = $win ? $file : tempnam($tmp_dir, $prefix); if (false === ($r = file_put_contents($write_file, $cont, LOCK_EX))) { return false; } if (!$win) { if (!rename($write_file, $file)) { return false; } } return true; }
/** * ファイルをダウンロード保存する * * @access public * @param $options array('disp_error' => true, 'use_tmp_file' => false, 'modified' = null) * @return WapResponse|false */ function fileDownload($url, $localfile, $options = array()) { global $_conf; $me = __CLASS__ . '::' . __FUNCTION__ . '()'; $disp_error = isset($options['disp_error']) ? $options['disp_error'] : true; $use_tmp_file = isset($options['use_tmp_file']) ? $options['use_tmp_file'] : false; $modified = isset($options['modified']) ? $options['modified'] : null; if (strlen($localfile) == 0) { trigger_error("{$me}, localfile is null", E_USER_WARNING); return false; } $perm = isset($_conf['dl_perm']) ? $_conf['dl_perm'] : 0606; // {{{ modifiedの指定 // 指定なし(null)なら、ファイルの更新時間 if (is_null($modified) && file_exists($localfile)) { $modified = gmdate("D, d M Y H:i:s", filemtime($localfile)) . " GMT"; // UNIX TIME } elseif (is_numeric($modified)) { $modified = gmdate("D, d M Y H:i:s", $modified) . " GMT"; // 日付時間文字列 } elseif (is_string($modified)) { // $modified はそのまま } else { // modified ヘッダはなし $modified = false; } // }}} // DL require_once P2_LIB_DIR . '/wap.class.php'; $wap_ua = new WapUserAgent(); $wap_ua->setTimeout($_conf['fsockopen_time_limit']); $wap_req = new WapRequest(); $wap_req->setUrl($url); $modified and $wap_req->setModified($modified); if ($_conf['proxy_use']) { $wap_req->setProxy($_conf['proxy_host'], $_conf['proxy_port']); } $wap_res = $wap_ua->request($wap_req); if (!$wap_res or !$wap_res->is_success() && $disp_error) { $url_t = P2Util::throughIme($wap_req->url); $atag = P2View::tagA($url_t, hs($wap_req->url), array('target' => $_conf['ext_win_target'])); $msgHtml = sprintf('<div>Error: %s %s<br>p2 info - %s に接続できませんでした。</div>', hs($wap_res->code), hs($wap_res->message), $atag); P2Util::pushInfoHtml($msgHtml); } // 更新されていたらファイルに保存 if ($wap_res->is_success() && $wap_res->code != '304') { if ($use_tmp_file) { if (!is_dir($_conf['tmp_dir'])) { if (!FileCtl::mkdirR($_conf['tmp_dir'])) { die("Error: {$me}, cannot mkdir."); return false; } } if (false === FileCtl::filePutRename($localfile, $wap_res->content)) { trigger_error("{$me}, FileCtl::filePutRename() return false. " . $localfile, E_USER_WARNING); die("Error: {$me}, cannot write file."); return false; } } else { if (false === file_put_contents($localfile, $wap_res->content, LOCK_EX)) { die("Error: {$me}, cannot write file."); return false; } } chmod($localfile, $perm); } return $wap_res; }