我试图通过循环下载mp4文件的大列表,并使用file_put_contents()将其保存到目录中。问题是只有视频列表中的最后一项被下载。
这是我的密码:
<?php
$i = 0;
foreach ($response['videos'] as $row){
$i++;
if($row['status'] != 'failed') {
$videoId= '';
$videoName = '';
$videoId = $row['key'];
$videoName = $row['title'];
$filename = '';
$filename = str_replace(' ','-',$videoName); // remove spaces from filename created by name
// Initialize a file URL to the variable
$url = "";
$url = "http://content.jwplatform.com/videos/{$videoId}.mp4";
// Use file_get_contents() function to get the file
// from url and use file_put_contents() function to
// save the file
if (file_put_contents("Videos/".$filename.$i.".mp4", file_get_contents($url)))
{
echo "File downloaded successfully.";
//sleep(5);
}
else
{
echo "File downloading failed.";
}
}
}
?>
我试着用一个CURL函数来代替file_put_contents(),它成功地将所有文件放到了我的视频目录中,但它们都是空文件。我相信它们是空的,因为这些mp4 URL是安全视频,所以当你在浏览器中打开它们时,它们实际上会将你带到另一个安全URL以查看和下载视频。CURL函数无法成功地获取文件数据,但似乎file_get_contents()确实成功地获取了文件数据(尽管只有最后一项)。
在我上面的代码中,我相信发生的是循环中的变量被一次又一次地重写,直到它到达最后一项,然后执行file_put_contents()函数。如果是这种情况,我如何确保它在每个循环上执行函数,以便下载所有文件?
编辑:以下是var_导出的一些输出($response['videos'))
array ( 0 => array ( 'key' => 'eewww123', 'title' => 'Video Name Example 1', 'description' => NULL, 'date' => 1604004019, 'updated' => 1640011490, 'expires_date' => NULL, 'tags' => NULL, 'link' => NULL, 'author' => NULL, 'size' => '240721720', 'duration' => '229.79', 'md5' => 'f0023423423423423423', 'views' => 0, 'status' => 'ready', 'error' => NULL, 'mediatype' => 'video', 'sourcetype' => 'file', 'sourceurl' => NULL, 'sourceformat' => NULL, 'upload_session_id' => NULL, 'custom' => array ( ), ), 1 => array ( 'key' => 'rr33445', 'title' => 'Another Video Name Example 1', 'description' => '', 'date' => 1594316349, 'updated' => 1640011493, 'expires_date' => NULL, 'tags' => NULL, 'link' => '', 'author' => NULL, 'size' => '525702235', 'duration' => '840.90', 'md5' => '0044455sfsdgsdfs3245', 'views' => 0, 'status' => 'ready', 'error' => NULL, 'mediatype' => 'video', 'sourcetype' => 'file', 'sourceurl' => NULL, 'sourceformat' => NULL, 'upload_session_id' => NULL, 'custom' => array ( ), ), )
没有一行有失败的状态,总共大约有30行,但我还有一些其他的视频列表下载900行。
下面是我使用的CURL函数,它成功下载了所有文件名,但所有文件都是空的:
function multiple_download(array $urls, $save_path = 'Videos') {
$multi_handle = curl_multi_init();
$file_pointers = [];
$curl_handles = [];
// Add curl multi handles, one per file we don't already have
foreach ($urls as $key => $url) {
$file = $save_path . '/' . basename($url);
if(!is_file($file)) {
$curl_handles[$key] = curl_init($url);
$file_pointers[$key] = fopen($file, "w");
curl_setopt($curl_handles[$key], CURLOPT_FILE, $file_pointers[$key]);
curl_setopt($curl_handles[$key], CURLOPT_HEADER, 0);
curl_setopt($curl_handles[$key], CURLOPT_CONNECTTIMEOUT, 60);
curl_multi_add_handle($multi_handle,$curl_handles[$key]);
}
}
// Download the files
do {
curl_multi_exec($multi_handle,$running);
} while ($running > 0);
// Free up objects
foreach ($urls as $key => $url) {
curl_multi_remove_handle($multi_handle, $curl_handles[$key]);
curl_close($curl_handles[$key]);
fclose ($file_pointers[$key]);
}
curl_multi_close($multi_handle);
}
multiple_download($videoURLS);
$video oURLs是我使用上面的第一个PHP函数构建的一个数组,其中包含所有唯一的URL(其他部分注释掉了)。
您必须使用标志附加到文件,而不是覆盖。
见文件https://www.php.net/manual/fr/function.file-put-contents.php标志文件
编辑:如果所有文件都具有相同的名称,则可能会覆盖它们。必须在循环中提供不同的名称。
foreach ($response['videos'] as $key => $row) {
...
if (file_put_contents("Videos/" . $filename .$key ".mp4", file_get_contents($url))) {
...
在文件名中使用循环的$key使其uniq并且不会被覆盖