Skip to content

Commit a07f86f

Browse files
Ayeshnicolas-grekas
authored andcommitted
[PHP 8.1] Add CURLStringFile polyfill
1 parent 734f5cb commit a07f86f

File tree

6 files changed

+123
-0
lines changed

6 files changed

+123
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Polyfills are provided for:
6262
- the `enum_exists` function introduced in PHP 8.1;
6363
- the `MYSQLI_REFRESH_REPLICA` constant introduced in PHP 8.1;
6464
- the `ReturnTypeWillChange` attribute introduced in PHP 8.1;
65+
- the `CURLStringFile` class introduced in PHP 8.1 (but only if PHP >= 7.4 is used);
6566
- the `AllowDynamicProperties` attribute introduced in PHP 8.2;
6667
- the `SensitiveParameter` attribute introduced in PHP 8.2;
6768
- the `SensitiveParameterValue` class introduced in PHP 8.2;

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"src/Intl/MessageFormatter/Resources/stubs",
6565
"src/Intl/Normalizer/Resources/stubs",
6666
"src/Php82/Resources/stubs",
67+
"src/Php81/Resources/stubs",
6768
"src/Php80/Resources/stubs",
6869
"src/Php73/Resources/stubs"
6970
]

src/Php81/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This component provides features added to PHP 8.1 core:
77
- [`enum_exists`](https://php.net/enum-exists)
88
- [`MYSQLI_REFRESH_REPLICA`](https://php.net/mysqli.constants#constantmysqli-refresh-replica) constant
99
- [`ReturnTypeWillChange`](https://wiki.php.net/rfc/internal_method_return_types)
10+
- [`CURLStringFile`](https://php.net/CURLStringFile) (but only if PHP >= 7.4 is used)
1011

1112
More information can be found in the
1213
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
if (\PHP_VERSION_ID >= 70400 && extension_loaded('curl')) {
13+
/**
14+
* @property string $data
15+
*/
16+
class CURLStringFile extends CURLFile
17+
{
18+
private $data;
19+
20+
public function __construct(string $data, string $postname, string $mime = 'application/octet-stream')
21+
{
22+
$this->data = $data;
23+
parent::__construct('data://application/octet-stream;base64,'.base64_encode($data), $mime, $postname);
24+
}
25+
26+
public function __set(string $name, $value): void
27+
{
28+
if ('data' !== $name) {
29+
$this->$name = $value;
30+
31+
return;
32+
}
33+
34+
if (is_object($value) ? !method_exists($value, '__toString') : !is_scalar($value)) {
35+
throw new \TypeError('Cannot assign '.gettype($value).' to property CURLStringFile::$data of type string');
36+
}
37+
38+
$this->name = 'data://application/octet-stream;base64,'.base64_encode($value);
39+
}
40+
41+
public function __isset(string $name): bool
42+
{
43+
return isset($this->$name);
44+
}
45+
46+
public function &__get(string $name)
47+
{
48+
return $this->$name;
49+
}
50+
}
51+
}

tests/Php81/CURLStringFileTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Polyfill\Tests\Php81;
13+
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* @requires extension curl
18+
* @requires PHP 7.4
19+
*/
20+
class CURLStringFileTest extends TestCase
21+
{
22+
private static $server;
23+
24+
public static function setUpBeforeClass(): void
25+
{
26+
$spec = [
27+
1 => ['file', '/dev/null', 'w'],
28+
2 => ['file', '/dev/null', 'w'],
29+
];
30+
if (!self::$server = @proc_open(('\\' === \DIRECTORY_SEPARATOR ? '' : 'exec ').\PHP_BINARY.' -S localhost:8086', $spec, $pipes, __DIR__.'/fixtures')) {
31+
self::markTestSkipped('Unable to start PHP server.');
32+
}
33+
sleep(1);
34+
}
35+
36+
public static function tearDownAfterClass(): void
37+
{
38+
if (self::$server) {
39+
proc_terminate(self::$server);
40+
proc_close(self::$server);
41+
}
42+
}
43+
44+
public function testCurlFileShowsContents(): void
45+
{
46+
$file = new \CURLStringFile('Hello', 'symfony.txt', 'text/plain');
47+
$data = ['test_file' => $file];
48+
49+
$ch = curl_init('http://localhost:8086/curl-echo-server.php');
50+
51+
curl_setopt($ch, CURLOPT_POST,1);
52+
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
53+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
54+
$response = curl_exec($ch);
55+
56+
$this->assertEquals(200, curl_getinfo($ch, CURLINFO_HTTP_CODE));
57+
$this->assertSame('{"test_file":{"name":"symfony.txt","type":"text\/plain","error":0,"size":5}}', $response);
58+
}
59+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
$output = $_FILES;
4+
foreach ($_FILES as $name => $file) {
5+
if (\is_string($file['tmp_name'] ?? null)) {
6+
unset($file['tmp_name'], $file['full_path']);
7+
$output[$name] = $file;
8+
}
9+
}
10+
echo json_encode($output);

0 commit comments

Comments
 (0)