Heim  >  Artikel  >  Backend-Entwicklung  >  Analyse des Problems mit den Versionsunterschieden der Curl-Upload-Datei

Analyse des Problems mit den Versionsunterschieden der Curl-Upload-Datei

小云云
小云云Original
2018-03-05 10:22:341501Durchsuche

=Nachdem das Front-End-Postformular die Datei hochgeladen hat, leitet das Back-End den Post nach Erhalt der Datei an den Bildserver weiter. Also habe ich Curl zum Hochladen verwendet und mit „@file path“ hochgeladen.

Der Code lautet wie folgt

<?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);

   }

Die PHP-Version der Testmaschine ist 5.2. Es gibt keine Problem beim Brechen des Codes, aber beim Einfügen in die Zeile erhält die Variable $_FILES keinen Wert. Dann beobachte ich genau, ich habe $_POST['video']='@/tmp/phps12d63'; in $_POST erhalten. Die erste Reaktion ist, dass der Inhaltstyp nicht normal übertragen wird der hochgeladenen Datei sollte „Multipart/form-data“ lauten, in diesem Fall sollte sie „application/x-www-form-urlencoded“ lauten. Drucken Sie dann die Variable $_SERVER[‘HTTP_CONTENT_TYPE’] auf dem Bildserver aus und stellen Sie fest, dass es sich um „multipart/form-data“ handelt.
Bei einem Blick in das Handbuch habe ich festgestellt, dass der Content-Type-Header auf multipart/form-data gesetzt wird, wenn der übergebene Parameter von CURLOPT_POSTFIELDS ein Array ist.
Dann gibt es einen magischen Parameter CURLOPT_SAFE_UPLOAD, der in php5.5.0 hinzugefügt wurde. Der Standardwert ist false, 5.6.0 ist standardmäßig true,

CURLOPT_SAFE_UPLOAD
TRUE deaktiviert das Senden von Dateien mit dem @-Präfix in CURLOPT_POSTFIELDS. Dies bedeutet, dass @ sicher in Feldern verwendet werden kann. Verfügbar
CURLFile als Ersatz für das Hochladen.

Und CURLOPT_POSTFIELDS Parameterbeschreibung

CURLOPT_POSTFIELDS
Alle Daten werden über die Operation „POST“ im HTTP-Protokoll gesendet. Um eine Datei zu senden, stellen Sie dem Dateinamen ein @ voran und verwenden Sie den vollständigen Pfad. Der Dateityp kann im Format „;type=mimetype“ hinter dem Dateinamen angegeben werden. Dieser Parameter kann eine URL-codierte Zeichenfolge sein, ähnlich wie „para1=val1¶2=val2&...“, oder Sie können ein Array mit dem Feldnamen als Schlüssel und den Felddaten als Wert verwenden. Wenn value ein Array ist, wird der Content-Type-Header auf multipart/form-data gesetzt. Ab PHP 5.2.0 muss der Wert beim Übergeben von Dateien mit dem @-Präfix ein Array sein. Ab PHP 5.5.0 ist das @-Präfix veraltet und Dateien können über CURLFile gesendet werden. Setzen Sie CURLOPT_SAFE_UPLOAD auf TRUE, um das Senden von Dateien mit dem @-Präfix für zusätzliche Sicherheit zu deaktivieren.

Bei der Überprüfung der Version stellt sich heraus, dass die Testumgebung PHP5.3 und die Online-Testumgebung 5.6 ist, was bedeutet, dass CURLOPT_SAFE_UPLOAD standardmäßig auf true eingestellt ist, @-Upload deaktiviert ist und @ ein ist gewöhnliche Saite. Ab 5.5 wurde das @-Präfix zum Hochladen von Dateien abgeschafft. Versionen größer als 5.5 müssen mit CURLFile hochgeladen werden. Die endgültige kompatible Lösung verwendet das Präfix @, wenn es kleiner als 5.5 ist, und CURLFile, wenn es größer als 5.5 ist. Verwenden Sie zum Hochladen @, und Sie können zusätzliche Parameter hinzufügen Geben Sie

<?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" : '');
    }
}

Endcode ein. Zusammenfassend lässt sich sagen:

<?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);

   }

: Wenn Sie auf ein Problem stoßen, sollten Sie es zunächst ruhig analysieren und dann das Handbuch sorgfältig lesen.

Am Freitag ist ein Problem aufgetreten. Nachdem das Front-End-Postformular eine Datei hochgeladen hatte, leitete das Back-End den Post nach Erhalt der Datei an den Bildserver weiter. Also habe ich Curl zum Hochladen verwendet und mit „@file path“ hochgeladen.
Der Code lautet wie folgt

<?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);

   }

Die PHP-Version der Testmaschine ist 5.2. Es gibt kein Problem, den Code zu knacken. aber wenn es online gestellt wird, $_FILES Die Variable kann keinen Wert empfangen. Dann beobachten Sie genau, dass ich $_POST['video']='@/tmp/phps12d63'; in $_POST erhalten habe. Die erste Reaktion ist, dass der Inhaltstyp nicht normal übertragen wird der hochgeladenen Datei sollte „Multipart/form-data“ lauten, in diesem Fall sollte sie „application/x-www-form-urlencoded“ lauten. Drucken Sie dann die Variable $_SERVER[‘HTTP_CONTENT_TYPE’] auf dem Bildserver aus und stellen Sie fest, dass es sich um „multipart/form-data“ handelt.
Beim Durchsehen des Handbuchs habe ich festgestellt, dass der Content-Type-Header auf multipart/form-data gesetzt wird, wenn der übergebene Parameter von CURLOPT_POSTFIELDS ein Array ist.
Dann gibt es einen magischen Parameter CURLOPT_SAFE_UPLOAD, der in php5.5.0 hinzugefügt wurde. Der Standardwert ist false, 5.6.0 ist standardmäßig true,

CURLOPT_SAFE_UPLOAD
TRUE deaktiviert das Senden von Dateien mit dem @-Präfix in CURLOPT_POSTFIELDS. Dies bedeutet, dass @ sicher in Feldern verwendet werden kann. Verfügbar
CURLFile als Ersatz für das Hochladen.

Und CURLOPT_POSTFIELDS Parameterbeschreibung

CURLOPT_POSTFIELDS
Alle Daten werden über die Operation „POST“ im HTTP-Protokoll gesendet. Um eine Datei zu senden, stellen Sie dem Dateinamen ein @ voran und geben Sie den vollständigen Pfad an. Der Dateityp kann im Format „;type=mimetype“ hinter dem Dateinamen angegeben werden. Dieser Parameter kann eine URL-codierte Zeichenfolge sein, ähnlich wie „para1=val1¶2=val2&...“, oder Sie können ein Array mit dem Feldnamen als Schlüssel und den Felddaten als Wert verwenden. Wenn value ein Array ist, wird der Content-Type-Header auf multipart/form-data gesetzt. Ab PHP 5.2.0 muss der Wert ein Array sein, wenn Dateien mit dem @-Präfix übergeben werden. Ab PHP 5.5.0 ist das @-Präfix veraltet und Dateien können über CURLFile gesendet werden. Setzen Sie CURLOPT_SAFE_UPLOAD auf TRUE, um das Senden von Dateien mit dem @-Präfix für zusätzliche Sicherheit zu deaktivieren.

查看版本,果然测试环境是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值

Das obige ist der detaillierte Inhalt vonAnalyse des Problems mit den Versionsunterschieden der Curl-Upload-Datei. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn