如何用PHP从OneDrive文件夹获取200条以上文件并筛选MP4?
OneDrive API 获取MP4文件的问题解答
1. 增加返回文件数量的方法
OneDrive API默认单次最多返回200条数据,你可以通过添加$top参数提升单次请求的返回上限(最大支持1000条)。如果目标文件夹文件总数超过1000,需要处理分页逻辑:API会在返回结果中包含@odata.nextLink字段,存储下一页数据的请求地址,循环请求直到该字段不存在即可获取全部文件。
修改后的请求URL及分页处理代码:
$folder = 'https://1drv.ms/u/s!xxxx?e=5xprOy'; // 单次请求最多获取1000条,添加$top参数 $url = 'https://api.onedrive.com/v1.0/shares/u!'.base64_encode($folder).'/root?expand=children&$top=1000'; $videos = []; $nextUrl = $url; do { $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $nextUrl); $result = curl_exec($ch); curl_close($ch); $arrayFolder = json_decode($result, true); // 修正变量名拼写错误:原脚本中$arrayFolder和$arrayFolders不一致 foreach ($arrayFolder['children'] as $file) { // 建议匹配带点的.mp4,避免误判类似"mp4test"的文件名 if (str_contains($file['name'], '.mp4')) { $videos[] = ['link' => $file['@content.downloadUrl']]; } } // 获取下一页请求地址,没有则终止循环 $nextUrl = $arrayFolder['@odata.nextLink'] ?? null; } while ($nextUrl);
2. 直接筛选MP4文件
可以通过API的$filter参数直接筛选文件名以.mp4结尾的文件,无需本地循环判断,减少无效数据传输。
修改后的请求URL:
$folder = 'https://1drv.ms/u/s!xxxx?e=5xprOy'; // 结合$top和$filter,仅返回MP4文件 $url = "https://api.onedrive.com/v1.0/shares/u!".base64_encode($folder)."/root?expand=children&$top=1000&$filter=endswith(name, '.mp4')";
请求返回的children数组将仅包含MP4文件,直接提取下载链接即可,无需额外筛选步骤。
3. 其他实现方式
使用Microsoft Graph API
OneDrive官方推荐迁移至Microsoft Graph API,其功能更全面,分页、筛选逻辑更统一。请求格式示例:
$folder = 'https://1drv.ms/u/s!xxxx?e=5xprOy'; // 按Graph API要求编码共享链接 $encodedFolder = urlencode(base64_encode('u!'.$folder)); $url = "https://graph.microsoft.com/v1.0/shares/$encodedFolder/root/children?$top=1000&$filter=endswith(name, '.mp4')";
注意:使用Graph API需获取对应访问令牌,匿名共享链接访问需额外配置,但长期维护性更强。
使用OneDrive PHP SDK
微软官方提供的Microsoft Graph PHP SDK封装了请求、分页、认证等逻辑,无需手动编写CURL代码,实现更简洁:
use Microsoft\Graph\Graph; use Microsoft\Graph\Model\DriveItem; $graph = new Graph(); // 配置访问令牌(共享链接场景可使用匿名认证或生成专用令牌) $graph->setAccessToken('your_access_token'); $encodedFolder = urlencode(base64_encode('u!'.$folder)); // 自动处理分页,直接获取MP4文件列表 $files = $graph->createRequest("GET", "/shares/$encodedFolder/root/children?$filter=endswith(name, '.mp4')") ->setReturnType(DriveItem::class) ->execute(); $videos = []; foreach ($files as $file) { $videos[] = ['link' => $file->getAdditionalData()['@content.downloadUrl']]; }
内容的提问来源于stack exchange,提问作者Paul Godard
相关产品推荐
相关产品推荐

