2024 PHP Conference Japan

copy

(PHP 4, PHP 5, PHP 7, PHP 8)

copy複製檔案

說明

copy(字串 $from, 字串 $to, ?資源 $context = null): 布林值

將檔案 from 複製到 to

如果您想要移動檔案,請使用 rename() 函式。

參數

from

來源檔案的路徑。

to

目標路徑。如果 to 是一個 URL,當 wrapper 不支援覆寫現有檔案時,複製操作可能會失敗。

警告

如果目標檔案已經存在,它將會被覆寫。

context

使用 stream_context_create() 建立的有效上下文資源。

回傳值

成功時回傳 true,失敗時回傳 false

範例

範例 #1 copy() 範例

<?php
$file
= 'example.txt';
$newfile = 'example.txt.bak';

if (!
copy($file, $newfile)) {
echo
"複製 $file 失敗...\n";
}
?>

參見

新增註解

使用者貢獻的註解 13 則註解

231
simonr_at_orangutan_dot_co_dot_uk
20 年前
花了好幾個小時追蹤一個 copy() 錯誤:權限被拒絕(並適當地擔心在 winXP 上的 chmod),值得指出的是,「目標」需要包含實際的檔案名稱!--- 不僅僅是您想要複製到的資料夾的路徑.......
真是的!
希望這可以為其他人節省數小時徒勞的除錯時間
128
cooper at asu dot ntu-kpi dot kiev dot ua
18 年前
我花了很多時間才找出 copy() 出錯的問題所在。它「不會」建立任何目錄。它只會複製到現有的路徑。所以在複製前請先建立目錄。希望我能幫上忙。
60
steve a h
16 年前
別忘了;您可以對遠端檔案使用 copy,而不是使用繁瑣的 fopen 方法。例如:

<?php
if(!@copy('http://someserver.com/somefile.zip','./somefile.zip'))
{
$errors= error_get_last();
echo
"COPY ERROR: ".$errors['type'];
echo
"<br />\n".$errors['message'];
} else {
echo
"File copied from remote!";
}
?>
28
promaty at gmail dot com
13 年前
這是一個我用來移除和複製非空目錄的簡單腳本。當您不確定檔案類型時,這非常有用。

我使用這些來管理我的網站插件的資料夾和 zip 壓縮檔。

<?php

// 移除檔案和非空目錄
function rrmdir($dir) {
if (
is_dir($dir)) {
$files = scandir($dir);
foreach (
$files as $file)
if (
$file != "." && $file != "..") rrmdir("$dir/$file");
rmdir($dir);
}
else if (
file_exists($dir)) unlink($dir);
}

// 複製檔案和非空目錄
function rcopy($src, $dst) {
if (
file_exists($dst)) rrmdir($dst);
if (
is_dir($src)) {
mkdir($dst);
$files = scandir($src);
foreach (
$files as $file)
if (
$file != "." && $file != "..") rcopy("$src/$file", "$dst/$file");
}
else if (
file_exists($src)) copy($src, $dst);
}
?>

敬上!
29
absorbentshoulderman at gmail dot com
11 年前
如果您需要先確定資料夾存在,這是一個簡單的小技巧

<?php

$srcfile
='C:\File\Whatever\Path\Joe.txt';
$dstfile='G:\Shared\Reports\Joe.txt';
mkdir(dirname($dstfile), 0777, true);
copy($srcfile, $dstfile);

?>

就這麼簡單。
5
terrasim.com 的某人
3 年前
在 Windows 上,php-7.4.19-Win32-vc15-x64 - copy() 損壞了一個 6GB 的 zip 檔案。我們唯一的 recours是寫

function file_win_copy( $src, $dst ) {
shell_exec( 'COPY "'.$src.'" "'.$dst.'"');
return file_exists($dest);
}
10
r.je 的 tom
16 年前
值得注意的是,copy() 會設定目標檔案的最後修改時間/日期。
10
Anamera.net 的 ASchmidt
10 年前
以下是一個程式碼片段,用於將檔案從網路伺服器下載到本機檔案。

它示範了請求的有用客製化(例如設定 User-Agent 和 Referrer,網站通常需要這些),以及如何僅在網站上的副本比本機副本更新時才下載檔案。

它進一步示範了如何處理回應標頭(如果伺服器設定)以確定時間戳記和檔案名稱。會檢查檔案類型,因為某些伺服器會返回 200 OK 返回碼和文字「找不到」頁面,而不是正確的 404 返回碼。

<?php
// $fURI: URL to a file located on a web server
// $target_file: Path to a local file

if ( file_exists( $target_file ) ) {
$ifmodhdr = 'If-Modified-Since: '.date( "r", filemtime( $target_file ) )."\r\n";
}
else {
$ifmodhdr = '';
}

// set request header for GET with referrer for modified files, that follows redirects
$arrRequestHeaders = array(
'http'=>array(
'method' =>'GET',
'protocol_version' =>1.1,
'follow_location' =>1,
'header'=> "User-Agent: Anamera-Feed/1.0\r\n" .
"Referer: $source\r\n" .
$ifmodhdr
)
);
$rc = copy( $fURI, $target_file, stream_context_create($arrRequestHeaders) );

// HTTP request completed, preserve system error, if any
if( $rc ) {
if (
fclose( $rc ) ) {
unset(
$err );
}
else {
$err = error_get_last();
}
}
else {
$err = error_get_last();
}

// Parse HTTP Response Headers for HTTP Status, as well filename, type, date information
// Need to start from rear, to get last set of headers after possible sets of redirection headers
if ( $http_response_header ) {
for (
$i = sizeof($http_response_header) - 1; $i >= 0; $i-- ) {
if (
preg_match('@^http/\S+ (\S{3,}) (.+)$@i', $http_response_header[$i], $http_status) > 0 ) {
// HTTP Status header means we have reached beginning of response headers for last request
break;
}
elseif (
preg_match('@^(\S+):\s*(.+)\s*$@', $http_response_header[$i], $arrHeader) > 0 ) {
switch (
$arrHeader[1] ) {
case
'Last-Modified':
if ( !isset(
$http_content_modtime) ) {
$http_content_modtime = strtotime( $arrHeader[2] );
}
break;
case
'Content-Type':
if ( !isset(
$http_content_image_type) ) {
if (
preg_match('@^image/(\w+)@ims', $arrHeader[2], $arrTokens) > 0 ) {
if (
in_array(strtolower($arrTokens[1]), $arrValidTypes)) {
$http_content_image_type = $arrTokens[1];
break;
}
}
throw new
Exception( "Error accessing file $fURI; invalid content type: $arrHeader[2]", 2);
}
break;
case
'Content-Disposition':
if ( !isset(
$http_content_filename) && preg_match('@filename\\s*=\\s*(?|"([^"]+)"|([\\S]+));?@ims', $arrHeader[2], $arrTokens) > 0 ) {
$http_content_filename = basename($arrTokens[1]);
}
break;
}
}
}
}

if (
$http_status ) {
// Make sure we have good HTTP Status
switch ( $http_status[1] ) {
case
'200':
// SUCCESS: HTTP Status is "200 OK"
break;
case
'304':
throw new
Exception( "Remote file not newer: $fURI", $http_status[1] );
break;
case
'404':
throw new
Exception( "Remote file not found: $fURI", $http_status[1] );
break;
default:
throw new
Exception( "HTTP Error, $http_status[2], accessing $fURI", $http_status[1] );
break;
}
}
elseif (
$err ) {
// Protocol / Communication error
throw new Exception( $err['message']/*."; Remote file: $fURI"*/, $err['type'] );
}
else {
// No HTTP status and no error
throw new customException( "Unknown HTTP response accessing $fURI: $http_response_header[0]", -1 );
}
?>

注意事項
1. 目前 copy() 並未正確處理 304 回應碼。它不會執行複製(可能設定 RC),而是會用零長度檔案覆寫目標檔案。
2. 使用 HTTP 1.1 協定時,存取遠端檔案清單可能會有問題。如果您遇到逾時錯誤,請嘗試使用預設的 1.0 協定版本。
5
gmx.at 的 hugo_2000
9 年前
如果您嘗試將檔案複製到自身(例如,如果目標目錄只是來源目錄的符號連結),copy 將返回 false。就像在命令列上一樣。
4
Vinicio Coletti
8 年前
在 Windows 8.1 下,從一個 NTFS 檔案系統複製大型檔案到另一個 NTFS 檔案系統,只會複製前 4 GiB,其餘檔案會被忽略。

因此,如果您認為檔案大於 4 GiB,不要執行
copy($source,$destination);
最好執行以下操作
exec("xcopy $source $destination");

我會檢查這個問題在 Linux 下是否也有效。
這取決於 PHP 是否以 64 位元模式編譯?
19
gmail.com 的 gimmicklessgpt
15 年前
這是一個簡單的遞迴函數,用於複製整個目錄

請注意,要自行檢查以確保您第一次呼叫它的目錄存在。

<?php
function recurse_copy($src,$dst) {
$dir = opendir($src);
@
mkdir($dst);
while(
false !== ( $file = readdir($dir)) ) {
if ((
$file != '.' ) && ( $file != '..' )) {
if (
is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
?>
8
eng-ayman at aymax dot net
15 年前
有些主機基於安全性考量停用了 copy() 函式

而對於某些情況,複製功能很重要,所以這是一個簡單的函式,可以達到與 copy 函式相同的效果

PHP 真是太好用了,我喜歡 PHP

<?php
function copyemz($file1,$file2){
$contentx =@file_get_contents($file1);
$openedfile = fopen($file2, "w");
fwrite($openedfile, $contentx);
fclose($openedfile);
if (
$contentx === FALSE) {
$status=false;
}else
$status=true;

return
$status;
}
?>
0
greg at hartwig dot com
13 天前
複製檔案並保留檔案時間戳記

<?php
if (copy($from, $to))
touch($to, filemtime($from), fileatime($from));
?>
To Top