目次
PHP の異なるバージョン間の cURL の違い
环境判断:小心魔法数字!
建议明确指定的退化选项
cURL选项设置的顺序
名前空間
ホームページ バックエンド開発 PHPチュートリアル PHP 5.0~5.6の各種バージョンのcURLファイルアップロードについて考える - 辛口情報 [だまされた]

PHP 5.0~5.6の各種バージョンのcURLファイルアップロードについて考える - 辛口情報 [だまされた]

Jun 13, 2016 pm 12:23 PM
curl php

PHP 5.0~5.6 の各バージョンの互換性を考慮した cURL ファイルのアップロード - 役立つ情報 [騙されました]

PHP の中国語公式ドキュメントは読まないでください!バージョンが追いつかないと死んでしまいます!

PHP の異なるバージョン間の cURL の違い

PHP の cURL は、(文字列の代わりに) 連想配列を CURL_POSTFIELDS に渡すことによって、multipart/form-data に対する POST リクエストの生成をサポートします。

従来、PHP の cURL は、cURL が読み取りおよびアップロードするための配列データの「@ フル ファイル パス」構文を使用したファイルの添付をサポートしていました。これは、コマンドラインから cURL プログラムを直接呼び出すための構文と一致しています:

<code style="font-family: Consolas, Menlo, Monaco, 'Courier New', monospace; padding: 0px; color: inherit; border-radius: 0px; white-space: inherit; background-color: transparent;">curl_setopt(ch, CURLOPT_POSTFIELDS, <span class="hljs-keyword" style="color: #859900;">array</span>(    <span class="hljs-string" style="color: #2aa198;">'file'</span> => <span class="hljs-string" style="color: #2aa198;">'@'</span>.realpath(<span class="hljs-string" style="color: #2aa198;">'image.png'</span>), )); equals$ curl -F <span class="hljs-string" style="color: #2aa198;">"file=@/absolute/path/to/image.png"</span> <url></code>
ログイン後にコピー

ただし、PHP では、ファイルを指すための新しい CURLFile クラスが 5.5 から導入されました。 CURLFile クラスは、マルチパート/フォームデータ データに表示される MIME タイプ、ファイル名などの追加情報を詳細に定義することもできます。 PHP では、CURLFile を使用して古い @ 構文を置き換えることをお勧めします。

<code style="font-family: Consolas, Menlo, Monaco, 'Courier New', monospace; padding: 0px; color: inherit; border-radius: 0px; white-space: inherit; background-color: transparent;">curl_setopt(ch, CURLOPT_POSTFIELDS, [    <span class="hljs-string" style="color: #2aa198;">'file'</span> => <span class="hljs-keyword" style="color: #859900;">new</span> CURLFile(realpath(<span class="hljs-string" style="color: #2aa198;">'image.png'</span>)), ]); </code>
ログイン後にコピー

PHP 5.5 では、PHP の cURL モジュールが古い CURL_SAFE_UPLOAD 構文を拒否し、CURLFile のみを受け入れるように強制できる @ オプションも導入しています。 -スタイルのドキュメント。デフォルト値は、5.5 の場合は false、5.6 の場合は true です。

しかし、落とし穴は次のとおりです。@ 構文は 5.5 で非推奨になり、5.6 で直接削除されました (ElorException が生成されます: ファイルのアップロードのための?@filename?API の使用は非推奨です。)代わりに CURLFile クラスを使用してください)。

对于PHP 5.6+而言,手动设置CURL_SAFE_UPLOAD为false是毫无意义的。根本不是字面意义理解的“设置成false,就能开启旧的unsafe的方式”——旧的方式已经作为废弃语法彻底不存在了。PHP 5.6+ == CURLFile only,不要有任何的幻想。

我的部署环境是5.4(仅@语法),但开发环境是5.6(仅CURLFile)。都没有压在5.5这个两者都支持过渡版本上,结果就是必须写出带有环境判断的两套代码。

现在问题来了……(挖掘机滚远点!)

环境判断:小心魔法数字!

我见过这种环境判断的代码:

<code style="font-family: Consolas, Menlo, Monaco, 'Courier New', monospace; padding: 0px; color: inherit; border-radius: 0px; white-space: inherit; background-color: transparent;"><span class="hljs-keyword" style="color: #859900;">if</span> (version_compare(phpversion(), <span class="hljs-string" style="color: #2aa198;">'5.4.0'</span>) >= <span class="hljs-number" style="color: #2aa198;">0</span>)</code>
ログイン後にコピー

我对这种代码的评价只有一个字:

这个判断掉入了典型的魔法数字陷阱。版本号莫名其妙的出现在代码之中,不查半天PHP手册和更新历史,很难明白作者被卡在了哪个功能的变更上。

代码应该回归本源。我们的实际需求其实是:有CURLFile就优先采用,没有再退化到传统@语法。那么代码就来了:

<code style="font-family: Consolas, Menlo, Monaco, 'Courier New', monospace; padding: 0px; color: inherit; border-radius: 0px; white-space: inherit; background-color: transparent;"><span class="hljs-keyword" style="color: #859900;">if</span> (class_exists(<span class="hljs-string" style="color: #2aa198;">'\CURLFile'</span>)) {    <span class="hljs-variable" style="color: #b58900;">$field</span> = <span class="hljs-keyword" style="color: #859900;">array</span>(<span class="hljs-string" style="color: #2aa198;">'fieldname'</span> => <span class="hljs-keyword" style="color: #859900;">new</span> \CURLFile(realpath(<span class="hljs-variable" style="color: #b58900;">$filepath</span>)));} <span class="hljs-keyword" style="color: #859900;">else</span> {    <span class="hljs-variable" style="color: #b58900;">$field</span> = <span class="hljs-keyword" style="color: #859900;">array</span>(<span class="hljs-string" style="color: #2aa198;">'fieldname'</span> => <span class="hljs-string" style="color: #2aa198;">'@'</span> . realpath(<span class="hljs-variable" style="color: #b58900;">$filepath</span>));}</code>
ログイン後にコピー

建议明确指定的退化选项

从可靠的角度,推荐指定CURL_SAFE_UPLOAD的值,明确告知php是容忍还是禁止旧的@语法。注意在低版本PHP中CURLOPT_SAFE_UPLOAD常量本身可能不存在,需要判断:

<code style="font-family: Consolas, Menlo, Monaco, 'Courier New', monospace; padding: 0px; color: inherit; border-radius: 0px; white-space: inherit; background-color: transparent;"><span class="hljs-keyword" style="color: #859900;">if</span> (class_exists(<span class="hljs-string" style="color: #2aa198;">'\CURLFile'</span>)) {    curl_<span class="hljs-built_in" style="color: #268bd2;">setopt</span>(<span class="hljs-variable" style="color: #b58900;">$ch</span>, CURLOPT_SAFE_UPLOAD, <span class="hljs-literal" >true</span>);} <span class="hljs-keyword" style="color: #859900;">else</span> {    <span class="hljs-keyword" style="color: #859900;">if</span> (defined(<span class="hljs-string" style="color: #2aa198;">'CURLOPT_SAFE_UPLOAD'</span>)) {        curl_<span class="hljs-built_in" style="color: #268bd2;">setopt</span>(<span class="hljs-variable" style="color: #b58900;">$ch</span>, CURLOPT_SAFE_UPLOAD, <span class="hljs-literal" >false</span>);    }}</code>
ログイン後にコピー

cURL选项设置的顺序

不管是curl_setopt()单发还是curl_setopt_array()批量,cURL的选项总是设置一个生效一个,而设置好的选项立刻就会影响cURL在设置后续选项时的行为。

例如CURLOPT_SAFE_UPLOAD就和CURLOPT_POSTFIELDS的行为有关。如果先设置CURLOPT_POSTFIELDS再设置CURLOPT_SAFE_UPLOAD,那么后者的约束作用就不会生效。因为设置前者时cURL就已经把数据实际的识读处理完毕了!

cURL有那么几个选项存在这种坑,务必小心。还好这种存在“依赖关系”的选项不多,机制也不复杂,简单处理即可。我的方法是先批量设置所有的选项,然后直到curl_exec()的前一刻才用curl_setopt()单发设置CURLOPT_POSTFIELDS

实际上在curl_setopt_array()用的数组中,保证CURLOPT_POSTFIELDS的位置在后边也是可靠的。PHP的关联数组是有顺序保障的,我们也可以假设curl_setopt_array()内部的执行顺序一定是从头到尾按顺序[注A],所以尽可放心。

我的做法只是在代码表现上加个多余的保险,突出强调顺序的重要性防以后手贱。

名前空間

PHP バージョン 5.2 以前には名前空間がありません。コード内でスペース区切り文字 が使用されている場合、パーサー エラーが発生します。 PHP 5.2 を扱うのは実際には簡単で、名前空間を放棄するだけです。

注意すべき点は、PHP 5.3 には名前空間があることです。 CURLFile を呼び出す場合でも、CURLFile の存在を確認するために class_exists() を使用する場合でも、名前空間でラップされるときにコードがクラッシュするのを防ぐために、トップレベルのスペースを明確に指定するために CURLFile を記述することをお勧めします。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

CakePHP プロジェクトの構成 CakePHP プロジェクトの構成 Sep 10, 2024 pm 05:25 PM

この章では、CakePHP の環境変数、一般設定、データベース設定、電子メール設定について理解します。

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

CakePHP の日付と時刻 CakePHP の日付と時刻 Sep 10, 2024 pm 05:27 PM

Cakephp4 で日付と時刻を操作するには、利用可能な FrozenTime クラスを利用します。

CakePHP ファイルのアップロード CakePHP ファイルのアップロード Sep 10, 2024 pm 05:27 PM

ファイルのアップロードを行うには、フォーム ヘルパーを使用します。ここではファイルアップロードの例を示します。

CakePHP ルーティング CakePHP ルーティング Sep 10, 2024 pm 05:25 PM

この章では、ルーティングに関連する次のトピックを学習します。

CakePHP について話し合う CakePHP について話し合う Sep 10, 2024 pm 05:28 PM

CakePHP は、PHP 用のオープンソース フレームワークです。これは、アプリケーションの開発、展開、保守をより簡単にすることを目的としています。 CakePHP は、強力かつ理解しやすい MVC のようなアーキテクチャに基づいています。モデル、ビュー、コントローラー

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

CakePHP バリデータの作成 CakePHP バリデータの作成 Sep 10, 2024 pm 05:26 PM

Validator は、コントローラーに次の 2 行を追加することで作成できます。

See all articles