Maison  >  Article  >  développement back-end  >  Analyse du problème de différence de version du fichier de téléchargement Curl

Analyse du problème de différence de version du fichier de téléchargement Curl

小云云
小云云original
2018-03-05 10:22:341497parcourir

=Une fois que le formulaire de publication frontal a téléchargé le fichier, le back-end transmet la publication au serveur d'images après avoir reçu le fichier. J'ai donc utilisé curl pour télécharger et téléchargé en utilisant '@file path'

Le code est le suivant

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }

La version PHP de la machine de test est 5.2. problème pour casser le code, mais en mettant sur la ligne, la variable $_FILES ne reçoit pas de valeur. Alors observez attentivement, j'ai reçu $_POST['video']='@/tmp/phps12d63'; dans $_POST La première réaction est que le Content-Type n'est pas transmis normalement, et le Content-Type. du fichier téléchargé doit être « multipart/form-data », dans ce cas, il doit être « application/x-www-form-urlencoded ». Imprimez ensuite la variable $_SERVER['HTTP_CONTENT_TYPE'] sur le serveur d'images et constatez qu'il s'agit de « multipart/form-data ».
En regardant le manuel, j'ai découvert que si le paramètre transmis de CURLOPT_POSTFIELDS est un tableau, l'en-tête Content-Type sera défini sur multipart/form-data.
Ensuite, il y a un paramètre magique CURLOPT_SAFE_UPLOAD, ajouté dans php5.5.0, la valeur par défaut est false, 5.6.0 est par défaut true,

CURLOPT_SAFE_UPLOAD
TRUE désactive l'envoi de fichiers avec le préfixe @ dans CURLOPT_POSTFIELDS. Cela signifie que @ peut être utilisé en toute sécurité dans les champs. Disponible
CURLFile en remplacement du téléchargement.

Et description du paramètre CURLOPT_POSTFIELDS

CURLOPT_POSTFIELDS
Toutes les données sont envoyées à l'aide de l'opération "POST" dans le protocole HTTP. Pour envoyer un fichier, préfixez le nom du fichier avec @ et utilisez le chemin complet. Le type de fichier peut être spécifié au format « ;type=mimetype » après le nom du fichier. Ce paramètre peut être une chaîne codée en urlen, similaire à 'para1=val1¶2=val2&...', ou vous pouvez utiliser un tableau avec le nom du champ comme clé et les données du champ comme valeur. Si value est un tableau, l’en-tête Content-Type sera défini sur multipart/form-data. À partir de PHP 5.2.0, lors du passage de fichiers en utilisant le préfixe @, la valeur doit être un tableau. À partir de PHP 5.5.0, le préfixe @ est obsolète et les fichiers peuvent être envoyés via CURLFile. Définissez CURLOPT_SAFE_UPLOAD sur TRUE pour désactiver l'envoi de fichiers avec le préfixe @ pour plus de sécurité.

En regardant la version, il s'avère que l'environnement de test est php5.3 et que l'environnement de test en ligne est 5.6, ce qui signifie que CURLOPT_SAFE_UPLOAD est par défaut true, @upload est désactivé et @ est une chaîne ordinaire. À partir de la version 5.5, le préfixe @ pour le téléchargement de fichiers a été abandonné. Les versions supérieures à 5.5 doivent être téléchargées à l'aide de CURLFile. La solution finale compatible utilise le préfixe @ s'il est inférieur à 5.5, et utilise CURLFile s'il est supérieur à 5.5, utilisez @ pour télécharger et vous pouvez ajouter des paramètres supplémentaires ; tapez

<?php
//curl_file_create是函数的别名CURLFile::__construct() if (!function_exists('curl_file_create')) {
    function curl_file_create($filename, $mimetype = '', $postname = '') {
        return "@$filename;filename="
            . ($postname ?: basename($filename))
            . ($mimetype ? ";type=$mimetype" : '');
    }
}

Code final Pour résumer

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);        $data['video']=curl_file_create($_FILES['video']['tmp_name'],'video/mp4',$_FILES['video']['name']);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }

, lorsque vous rencontrez un problème, vous devez d'abord l'analyser calmement, puis lire attentivement le manuel.

J'ai rencontré un problème vendredi. Après que le formulaire de publication frontal ait téléchargé un fichier, après que le back-end ait reçu le fichier, il a transmis la publication au serveur d'images. J'ai donc utilisé curl pour télécharger et téléchargé en utilisant '@file path'
Le code est le suivant

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }

La version PHP de la machine de test est 5.2. Il n'y a aucun problème à casser le code, mais lors de sa mise en ligne, $_FILES La variable ne peut pas recevoir de valeur. Alors observez attentivement, j'ai reçu $_POST['video']='@/tmp/phps12d63'; dans $_POST La première réaction est que le Content-Type n'est pas transmis normalement, et le Content-Type. du fichier téléchargé doit être « multipart/form-data », dans ce cas, il doit être « application/x-www-form-urlencoded ». Imprimez ensuite la variable $_SERVER['HTTP_CONTENT_TYPE'] sur le serveur d'images et constatez qu'il s'agit de « multipart/form-data ».
En regardant le manuel, j'ai découvert que si le paramètre transmis de CURLOPT_POSTFIELDS est un tableau, l'en-tête Content-Type sera défini sur multipart/form-data.
Ensuite, il y a un paramètre magique CURLOPT_SAFE_UPLOAD, ajouté dans php5.5.0, la valeur par défaut est false, 5.6.0 est par défaut true,

CURLOPT_SAFE_UPLOAD
TRUE désactive l'envoi de fichiers avec le préfixe @ dans CURLOPT_POSTFIELDS. Cela signifie que @ peut être utilisé en toute sécurité dans les champs. Disponible
CURLFile en remplacement du téléchargement.

Et description du paramètre CURLOPT_POSTFIELDS

CURLOPT_POSTFIELDS
Toutes les données sont envoyées à l'aide de l'opération "POST" dans le protocole HTTP. Pour envoyer un fichier, préfixez le nom du fichier avec @ et utilisez le chemin complet. Le type de fichier peut être spécifié au format « ;type=mimetype » après le nom du fichier. Ce paramètre peut être une chaîne codée en urlen, similaire à 'para1=val1¶2=val2&...', ou vous pouvez utiliser un tableau avec le nom du champ comme clé et les données du champ comme valeur. Si value est un tableau, l’en-tête Content-Type sera défini sur multipart/form-data. À partir de PHP 5.2.0, lors du passage de fichiers en utilisant le préfixe @, la valeur doit être un tableau. À partir de PHP 5.5.0, le préfixe @ est obsolète et les fichiers peuvent être envoyés via CURLFile. Définissez CURLOPT_SAFE_UPLOAD sur TRUE pour désactiver l'envoi de fichiers avec le préfixe @ pour plus de sécurité.

查看版本,果然测试环境是php5.3,而线上测试环境是5.6,也是就是说CURLOPT_SAFE_UPLOAD默认为true,禁用了@ 上传,@就是普通字符串了。而从5.5开始@前缀上传文件已经被废弃。大于5.5版本需使用CURLFile 上传。最后兼容方案小于5.5使用@前缀,大于5.5使用CURLFile,在小于5.5的版本是用@上传还可以添加额外的参数;filename=文件名;type=mime类型

<?php
//curl_file_create是函数的别名CURLFile::__construct() if (!function_exists('curl_file_create')) {
    function curl_file_create($filename, $mimetype = '', $postname = '') {
        return "@$filename;filename="
            . ($postname ?: basename($filename))
            . ($mimetype ? ";type=$mimetype" : '');
    }
}

最后代码为

<?php
    if($_FILES[&#39;video&#39;][&#39;size&#39;]>0){        $data = array('video'=>$_FILES['video']['tmp_name']);         $ch = curl_init();         $url="test.php";
        // 设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);
        //启用时会将头文件的信息作为数据流输出。 
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //将curl_exec()获取的信息以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);        $data['video']=curl_file_create($_FILES['video']['tmp_name'],'video/mp4',$_FILES['video']['name']);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);         $res = curl_exec($ch);
        // 抓取URL并把它传递给浏览器
        curl_exec($ch);
        // 关闭cURL资源,并且释放系统资源
        curl_close($ch);

   }

相关推荐:

php通过CURL上传文件

php curl上传文件的简单例子

post - php curl上传文件如何像表单一样指定其name值

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn