PHP 7.2 CURLFile 给出 "Invalid Filename" 警告
PHP 7.2 CURLFile Gives "Invalid Filename" Warning
我在使用 CURLFile 对象 (curl_file_create
) 时遇到问题。我尝试了多种方法,但无论我尝试什么,我最终都会在日志文件中收到 PHP 警告,并且我的 cURL 调用中省略了该文件。
首先,一些信息:
- PHP 7.2
- 已确认文件存在并且PHP/Apache
可读
- php-curl 和相关 php 库是最新的
- 这是一个对象中的片段,因此是对
$this
的引用。所有变量都正确加载。
- 这是我开始的另一个问题的延续,当缩小范围时,它似乎与主要的原始主题 (mailgun) 无关。如果您愿意,可以在 URL 中引用它,但我打算很快结束这个问题。 Mailgun Attachments with PHP cURL - No SDK
- 注意在代码块中我已经注释掉了尝试添加文件的其他几种变体——它们都创建了相同的 warning/result
代码块
$curl = curl_init();
$curlOpts = array(
CURLOPT_POST => 1,
CURLOPT_URL => $postUrl,
CURLOPT_TIMEOUT => 20,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => 'api:' . $this->apiKey
);
$postFields = array(
'from' => $email->from,
'to' => $email->to,
'subject' => $email->subject
);
if (strlen($email->cc) > 0) {
$postFields['cc'] = $email->cc;
}
if (strlen($email->bcc) > 0) {
$postFields['bcc'] = $email->bcc;
}
if (strlen($email->html) > 0) {
$postFields['html'] = $email->html;
} else {
$postFields['text'] = $email->text;
}
if (count($email->attachments) > 0) {
// Curl attachments for < PHP5.5 not supported
if (function_exists('curl_file_create')) {
$curlOpts[CURLOPT_SAFE_UPLOAD] = 1; // for < PHP 7
//$curlOpts[CURLOPT_HTTPHEADER] = array('Content-Type: multipart/form-data');
//$postFields['attachment'] = curl_file_create($email->attachments[0]);
for ($i = 1; $i <= count($email->attachments); $i++) {
$postFields['attachment[' . $i . ']'] = curl_file_create($email->attachments[$i - 1], 'text/csv', basename($email->attachments[$i - 1]));
//$postFields['attachment[' . $i . ']'] = curl_file_create('/var/www/sites/domain/contact.csv', 'text/csv', 'contact.csv');
//$postFields['attachment[' . $i . ']'] = curl_file_create('test.txt', 'text/plain', 'test.txt');
//$postFields['attachment[' . $i . ']'] = curl_file_create(realpath('test.txt'), 'text/plain', 'test.txt');
//$postFields['attachment[' . $i . ']'] = new \CURLFile($email->attachments[$i - 1]);
}
} else {
\D3DevelForms\Models\Error::CreateAndSaveSystemError(
$plugin,
\D3DevelForms\Common::ERROR_WARNING,
'PHP 5.5 or newer required for Mailgun Attachments',
\D3DevelForms\Models\Error::ERROR_CODE_API_MAILGUN_LOCAL_ERROR,
'You are using an outdated version of PHP. Email attachments via Mailgun will be ignored.');
}
}
$curlOpts[CURLOPT_POSTFIELDS] = $postFields;
$log->UpdateDebugLog('Mailgun API Options', $curlOpts);
curl_setopt_array($curl, $curlOpts);
$curl_response = curl_exec($curl);
$info = curl_getinfo($curl);
卷曲选项 ($curlOpts
)
Array
(
[47] => 1
[10002] => https://api.mailgun.net/v3/devtester.devtest.com/messages
[13] => 20
[19913] => 1
[107] => 1
[10005] => api:APIKEY
[-1] => 1
[10015] => Array
(
[from] => Dev Tester <devtester@devtest.com>
[to] => devemail@gmail.com
[subject] => Form Summary
[text] => My Text Content
[attachment[1]] => CURLFile Object
(
[name] => /var/www/path_to/my_file.csv
[mime] => text/csv
[postname] => my_file.csv
)
)
)
返回卷曲信息 ($info
)
Array
(
[url] => https://api.mailgun.net/v3/devtester.devtest.com/messages
[content_type] => application/json
[http_code] => 200
[header_size] => 388
[request_size] => 312
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.503718
[namelookup_time] => 0.004273
[connect_time] => 0.0932
[pretransfer_time] => 0.279756
[size_upload] => 1021
[size_download] => 105
[speed_download] => 208
[speed_upload] => 2026
[download_content_length] => 105
[upload_content_length] => 1021
[starttransfer_time] => 0.368725
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => Y.Y.Y.Y
[certinfo] => Array
(
)
[primary_port] => 443
[local_ip] => X.X.X.X
[local_port] => 38636
)
更新:当从命令行使用 cURL 进行测试时,它确实按预期工作,包括当我 运行 它作为 apache
进程时。
sudo -u apache curl -s --user 'api:APIKEY' \
https://api.mailgun.net/v3/devtester.devtest.com/messages \
-F from='Dev Tester <devtest@devtester.devtest.com>' \
-F to='devtester@gmail.com' \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!' \
-F attachment=@/var/www/path_to/my_file.csv
{
"id": "<AA.BB.CC@devtester.devtest.com>",
"message": "Queued. Thank you."
}
我在 Apache 日志中收到 PHP 警告,显示如下:
"PHP Warning: curl_setopt_array(): Invalid filename for key attachment[1]"
这很棘手,因为我已经确认了以下内容:
- 文件存在
- Apache 可以读取该文件
- 文件路径不包含字母、数字、斜杠和连字符以外的任何字符
- 因为文件是在同一个线程中生成的,我试过引用一个静态文件,但是结果是一样的。
尤里卡。问题是使用 curl_setopt_array
。我能够像这样更正问题:
//$curlOpts[CURLOPT_POSTFIELDS] = $postFields;
$log->UpdateDebugLog('Mailgun API Options', $curlOpts);
curl_setopt_array($curl, $curlOpts);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
我没有看到任何关于 curl_setopt_array
限制的文档,所以我不确定这是我的不当使用还是未知错误。
我在使用 CURLFile 对象 (curl_file_create
) 时遇到问题。我尝试了多种方法,但无论我尝试什么,我最终都会在日志文件中收到 PHP 警告,并且我的 cURL 调用中省略了该文件。
首先,一些信息:
- PHP 7.2
- 已确认文件存在并且PHP/Apache 可读
- php-curl 和相关 php 库是最新的
- 这是一个对象中的片段,因此是对
$this
的引用。所有变量都正确加载。 - 这是我开始的另一个问题的延续,当缩小范围时,它似乎与主要的原始主题 (mailgun) 无关。如果您愿意,可以在 URL 中引用它,但我打算很快结束这个问题。 Mailgun Attachments with PHP cURL - No SDK
- 注意在代码块中我已经注释掉了尝试添加文件的其他几种变体——它们都创建了相同的 warning/result
代码块
$curl = curl_init();
$curlOpts = array(
CURLOPT_POST => 1,
CURLOPT_URL => $postUrl,
CURLOPT_TIMEOUT => 20,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => 'api:' . $this->apiKey
);
$postFields = array(
'from' => $email->from,
'to' => $email->to,
'subject' => $email->subject
);
if (strlen($email->cc) > 0) {
$postFields['cc'] = $email->cc;
}
if (strlen($email->bcc) > 0) {
$postFields['bcc'] = $email->bcc;
}
if (strlen($email->html) > 0) {
$postFields['html'] = $email->html;
} else {
$postFields['text'] = $email->text;
}
if (count($email->attachments) > 0) {
// Curl attachments for < PHP5.5 not supported
if (function_exists('curl_file_create')) {
$curlOpts[CURLOPT_SAFE_UPLOAD] = 1; // for < PHP 7
//$curlOpts[CURLOPT_HTTPHEADER] = array('Content-Type: multipart/form-data');
//$postFields['attachment'] = curl_file_create($email->attachments[0]);
for ($i = 1; $i <= count($email->attachments); $i++) {
$postFields['attachment[' . $i . ']'] = curl_file_create($email->attachments[$i - 1], 'text/csv', basename($email->attachments[$i - 1]));
//$postFields['attachment[' . $i . ']'] = curl_file_create('/var/www/sites/domain/contact.csv', 'text/csv', 'contact.csv');
//$postFields['attachment[' . $i . ']'] = curl_file_create('test.txt', 'text/plain', 'test.txt');
//$postFields['attachment[' . $i . ']'] = curl_file_create(realpath('test.txt'), 'text/plain', 'test.txt');
//$postFields['attachment[' . $i . ']'] = new \CURLFile($email->attachments[$i - 1]);
}
} else {
\D3DevelForms\Models\Error::CreateAndSaveSystemError(
$plugin,
\D3DevelForms\Common::ERROR_WARNING,
'PHP 5.5 or newer required for Mailgun Attachments',
\D3DevelForms\Models\Error::ERROR_CODE_API_MAILGUN_LOCAL_ERROR,
'You are using an outdated version of PHP. Email attachments via Mailgun will be ignored.');
}
}
$curlOpts[CURLOPT_POSTFIELDS] = $postFields;
$log->UpdateDebugLog('Mailgun API Options', $curlOpts);
curl_setopt_array($curl, $curlOpts);
$curl_response = curl_exec($curl);
$info = curl_getinfo($curl);
卷曲选项 ($curlOpts
)
Array
(
[47] => 1
[10002] => https://api.mailgun.net/v3/devtester.devtest.com/messages
[13] => 20
[19913] => 1
[107] => 1
[10005] => api:APIKEY
[-1] => 1
[10015] => Array
(
[from] => Dev Tester <devtester@devtest.com>
[to] => devemail@gmail.com
[subject] => Form Summary
[text] => My Text Content
[attachment[1]] => CURLFile Object
(
[name] => /var/www/path_to/my_file.csv
[mime] => text/csv
[postname] => my_file.csv
)
)
)
返回卷曲信息 ($info
)
Array
(
[url] => https://api.mailgun.net/v3/devtester.devtest.com/messages
[content_type] => application/json
[http_code] => 200
[header_size] => 388
[request_size] => 312
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.503718
[namelookup_time] => 0.004273
[connect_time] => 0.0932
[pretransfer_time] => 0.279756
[size_upload] => 1021
[size_download] => 105
[speed_download] => 208
[speed_upload] => 2026
[download_content_length] => 105
[upload_content_length] => 1021
[starttransfer_time] => 0.368725
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => Y.Y.Y.Y
[certinfo] => Array
(
)
[primary_port] => 443
[local_ip] => X.X.X.X
[local_port] => 38636
)
更新:当从命令行使用 cURL 进行测试时,它确实按预期工作,包括当我 运行 它作为 apache
进程时。
sudo -u apache curl -s --user 'api:APIKEY' \
https://api.mailgun.net/v3/devtester.devtest.com/messages \
-F from='Dev Tester <devtest@devtester.devtest.com>' \
-F to='devtester@gmail.com' \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!' \
-F attachment=@/var/www/path_to/my_file.csv
{
"id": "<AA.BB.CC@devtester.devtest.com>",
"message": "Queued. Thank you."
}
我在 Apache 日志中收到 PHP 警告,显示如下:
"PHP Warning: curl_setopt_array(): Invalid filename for key attachment[1]"
这很棘手,因为我已经确认了以下内容:
- 文件存在
- Apache 可以读取该文件
- 文件路径不包含字母、数字、斜杠和连字符以外的任何字符
- 因为文件是在同一个线程中生成的,我试过引用一个静态文件,但是结果是一样的。
尤里卡。问题是使用 curl_setopt_array
。我能够像这样更正问题:
//$curlOpts[CURLOPT_POSTFIELDS] = $postFields;
$log->UpdateDebugLog('Mailgun API Options', $curlOpts);
curl_setopt_array($curl, $curlOpts);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
我没有看到任何关于 curl_setopt_array
限制的文档,所以我不确定这是我的不当使用还是未知错误。