Hello!
I have idea to make possible to send files with CURL from string. 
CURL library has few options to make it as easy as possible: 
CURLFORM_BUFFER, CURLFORM_BUFFERPTR, and CURLFORM_BUFFERLENGTH.
But I got many problems with integration of this feature in current php 
curl file attachment design.
Class CURLFile has one required $filename property, and two optional 
properties $mimetype and $postname. 
In my case we need two required properties $buffer and $postname, and one 
optional $mimetype.
Also we have function curl_file_create, which just like alias function for 
CURLFile constructor with same arguments.
So I tried to implement feature by different ways:
- Create new class CURLFileBuffer by simple copy-paste code from CURLFile. 
 (pull-request https://github.com/php/php-src/pull/1217 - code was removed,
 sorry)
 positive:
- No BC break
- API similar to CURLFile 
 negative:
- A lot of code duplication, hard to support in future.
Thanks to Tony2001 and S.Malyshev for reviewing.
- Integrate new feature to exists CURLFile class. (pull-request 
 https://github.com/php/php-src/pull/1283)
 positive:
- One class for new and old features
- No code duplication
- No BC break (* except some little not obviously cases) 
 negative:
- Not clear behavior if developer will set $filename and $buffer in same 
 time. It require more documentation and not obviously for developers.
- Not clear which values of $filename we must ignore to start use $buffer.
- etc.
Thanks to S.Malyshev for reviewing.
- Like #2, but make CURLFile immutable after instance creation by 
 curl_file_create and curl_file_buffer_create functions (or by little
 modified constructors).
 positive:
- Clear behavior. 
 negative:
- Great BC break: CURLFile has public properties and setters methods.
I like it, I think it will be great to make CURLFile immutable, but I'm 
sure no one want such BC. =(
- Like #1, but move code duplication to common C code, used by two 
 classes.
 It's impossible, because this classes so simple, so 95% of code like that:
/* {{{ proto string CURLFile::getFilename()
Get file name */
ZEND_METHOD(CURLFile, getFilename)
{
curlfile_get_property("name", INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
So both classes required such doc block ({{{ proto ...) and call 
*_property methods.
- Like #1, but move code duplication to abstract class, for example 
 CURLFileAbstract.
So we move $mimetype and $postname to abstract class, $filename to 
CURLFile, $buffer to CURLFileBuffer class. 
They will have own constructors with own arguments requiring.
positive:
- No BC break
- less code duplication 
 negative:
- new abstract class, used ONLY for less code duplication in curl 
 extension, it has no sense for developers.
6+) Your variant, please provide it.
As you can see, so little change, like using few simple options from curl 
library, require so long mail, few pull-requests and too many time from 
internal php people. 
But I believe, we can do it. 
Thank you, and please help me to finish this small feature.
-- 
With regards, Alexander Moskalev 
irker@irker.net 
irker@php.net 
a.moskalev@corp.badoo.com
Sorry for annoying mail, but it's really small and simple feature, which 
can be implemented by few lines of curl options. But with API realisation 
questions. 
Please, help me to choose correct way, and I will create new pull-request 
with code and tests.
On Tue, Jun 21, 2016 at 11:38 AM, Alexander Moskalev irker@irker.net 
wrote:
Sorry for annoying mail, but it's really small and simple feature, which
can be implemented by few lines of curl options. But with API realisation
questions.
Please, help me to choose correct way, and I will create new pull-request
with code and tests.
Hi Alexander,
Thank you for this — I wonder if it's possible to make it so that you can 
pass a filename, or a valid stream (or stream URL) to CURLFile — this would 
solve the issue, as you can use a memory stream, have no extra classes, no 
ambiguity of "is it a filename" vs "is it a string of data".
Thoughts?
- Davey
Thank you!
2016-06-21 23:31 GMT+03:00 Davey Shafik davey@php.net:
you can use a memory stream
I thought about something like that. But if we created memory stream 
(php://memory ?), we have file pointer resource related to this stream. And 
we cannot read or write something in this stream without such file pointer 
provided.
Example code:
$fp = fopen("php://memory", 'r+');
fputs($fp, "foo\n");
rewind($fp);
echo file_get_contents("php://memory"); // <- this doesn't work, and same
will be in curl.
echo stream_get_contents($fp); //<- this will work
Or you mean something else?
-- 
With regards, Alexander Moskalev 
irker@irker.net 
irker@php.net 
a.moskalev@corp.badoo.com
Thank you!
2016-06-21 23:31 GMT+03:00 Davey Shafik davey@php.net:
you can use a memory stream
I thought about something like that. But if we created memory stream
(php://memory ?), we have file pointer resource related to this stream. And
we cannot read or write something in this stream without such file pointer
provided.Example code:
$fp = fopen("php://memory", 'r+');
fputs($fp, "foo\n");
rewind($fp);
echo file_get_contents("php://memory"); // <- this doesn't work, and same
will be in curl.
echo stream_get_contents($fp); //<- this will workOr you mean something else?
In this one case, you would be required to pass in the stream handle in. 
All other cases would work with either the resource URL (e.g. s3://<path>) 
or a stream handle.
- Davey
Ok, thank you! 
Not sure if it the best solution, but it will work. 
So,
- make possible to work with file pointer and stream URL in $filename 
 option.
 positive:
- no code duplicates
- no BC brake 
 negative:
- misleading in property name: getFileName method, $name property etc.
-- 
With regards, Alexander Moskalev 
irker@irker.net 
irker@php.net 
a.moskalev@corp.badoo.com
Last try to highlight this thread
-- 
With regards, Alexander Moskalev 
irker@irker.net 
irker@php.net 
a.moskalev@corp.badoo.com