Discussion about new Curl URL API and ext/curl improvements

  117958
June 16, 2022 07:10 pierrick@php.net (Pierrick Charron)
Hi internals,

Since its version 6.62.0 [1], libcurl features a brand new URL API [2] that
can be used to parse and generate URLs, using libcurl’s own parser. One of
the goals of this API is to tighten a problematic vulnerable area for
applications where the URL parser library would believe one thing and
libcurl another. This could and has sometimes led to security problems [3].
The new API is handled base and composed of 5 new functions [4] (and one
more since 7.80.0 to get more verbose information upon error).

I started to work on an implementation [5] to expose this API to PHP
userland in the curl extension so that PHP users can benefit from it. My
first reflex was to stay consistent on how the extension is currently
working and do a one to one mapping of the new curl functions. I got
feedback from both Ilija and Christoph saying that the API is, I quote, "a
bit clunky" which I can't disagree with.

For a long time, ext/curl worked with handles as "curl resources" and
functions mapped to the libcurl functions, but since PHP8.0 "curl
resources" were converted to opaque classes with no methods. So my main
goal here is to come up with a solution for the new Curl URL API, but maybe
also to be consistent, make some changes to existing curl classes like
`CurlHandle` to add methods and improve the current state of the extension.

Here is the solution I would propose :
- First of course keep all the current ext/curl functions as is not to
break any compatibility (Seems obvious but just to be sure everybody is on
the same page).
- For consistency expose the new Curl URL API as functions mapped one to
one to libcurl functions :

function curl_url(?string $url = null): CurlUrl|false {}
function curl_url_set(CurlUrl $url, int $part, string $content, int $flags
= 0): bool {}
function curl_url_get(CurlUrl $url, int $part, int $flags = 0):
string|false {}
function curl_url_errno(CurlUrl $url): int {}
function curl_url_strerror(int $error_code): ?string {}

- Add methods to the CurlUrl object to make it less opaque and expose an
object oriented style API. I would keep it minimal and let userlanAd API
provide higher level APIs as guzzle for example. (You can see the current
implementation [5])

final class CurlUrl implements Stringable
{
    public function __construct(?string $url = null) {}
    public function get(int $part, int $flags = 0): string {}
    public function set(int $part, string $content, int $flags = 0): void {}
    public function getErrno(): int {}
    public function __toString(): string {}
    public function __clone() {}
}

- It would also be nice to add this object oriented API for existing
CurlHandle, CurlMultiHandle and CurlShareHandle classes. For example the
CurlHandle class would look like that (First implementation [6])

final class CurlHandle
{
    public function __construct(?string $url = null) {}
    public function setOpt(int $option, mixed $value): bool {}
    public function getInfo(?int $option = null): mixed {}
    public function exec(): string|bool {}
    public function escape(string $string): string|false {}
    public function unescape(string $string): string|false {}
    public function pause(int $flags): int {}
    public function getErrno(): int {}
    public function reset(): void;
    public function setOptArray(array $options): bool {}
    public function upkeep(): bool {}
    public function __clone() {}
}

As of right now I still have some unanswered questions like how should we
handle errors on the new CurlUrl API ?
- Throw `CurlUrlException` on both the procedural and object oriented style
API (that's how current implementation works [5])
- Throw `CurlUrlException` with the oriented style API, but return for
example boolean/null on errors when user uses the procedural API ?
- Always return null/booleans using both object oriented API and
procedural API ?

The same question applies if we add a new object oriented style API on
existing classes. Current functions MUST stay unchanged but should we throw
`CurlException` when the user uses the object oriented style API ? (That's
what I would do) Or should we return the same result from OO and procedural
API ? Should we make the new CurlApi consistent with that ?

What are your thoughts about all this ? Any feedback on any of those
subjects are more than welcome.

Pierrick

[1]
https://daniel.haxhttps://github.com/adoy/php-src/tree/curl-object-apix.se/blog/2018/10/31/curl-7-62-0-moar-stuff/
<https://daniel.haxx.se/blog/2018/10/31/curl-7-62-0-moar-stuff/>
[2] https://daniel.haxx.se/blog/2018/09/09/libcurl-gets-a-url-api/
[3]
https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf
[4] https://github.com/curl/curl/blob/master/include/curl/urlapi.h
[5] https://github.com/php/php-src/pull/8770
[6] https://github.com/adoy/php-src/tree/curl-object-api
  117959
June 16, 2022 07:42 deleugyn@gmail.com (Deleu)
On Thu, Jun 16, 2022, 9:10 AM Pierrick Charron <pierrick@php.net> wrote:

> Hi internals, > > Since its version 6.62.0 [1], libcurl features a brand new URL API [2] that > can be used to parse and generate URLs, using libcurl’s own parser. One of > the goals of this API is to tighten a problematic vulnerable area for > applications where the URL parser library would believe one thing and > libcurl another. This could and has sometimes led to security problems [3]. > The new API is handled base and composed of 5 new functions [4] (and one > more since 7.80.0 to get more verbose information upon error). > > I started to work on an implementation [5] to expose this API to PHP > userland in the curl extension so that PHP users can benefit from it. My > first reflex was to stay consistent on how the extension is currently > working and do a one to one mapping of the new curl functions. I got > feedback from both Ilija and Christoph saying that the API is, I quote, "a > bit clunky" which I can't disagree with. > > For a long time, ext/curl worked with handles as "curl resources" and > functions mapped to the libcurl functions, but since PHP8.0 "curl > resources" were converted to opaque classes with no methods. So my main > goal here is to come up with a solution for the new Curl URL API, but maybe > also to be consistent, make some changes to existing curl classes like > `CurlHandle` to add methods and improve the current state of the extension. > > Here is the solution I would propose : > - First of course keep all the current ext/curl functions as is not to > break any compatibility (Seems obvious but just to be sure everybody is on > the same page). > - For consistency expose the new Curl URL API as functions mapped one to > one to libcurl functions : > > function curl_url(?string $url = null): CurlUrl|false {} > function curl_url_set(CurlUrl $url, int $part, string $content, int $flags > = 0): bool {} > function curl_url_get(CurlUrl $url, int $part, int $flags = 0): > string|false {} > function curl_url_errno(CurlUrl $url): int {} > function curl_url_strerror(int $error_code): ?string {} > > - Add methods to the CurlUrl object to make it less opaque and expose an > object oriented style API. I would keep it minimal and let userlanAd API > provide higher level APIs as guzzle for example. (You can see the current > implementation [5]) > > final class CurlUrl implements Stringable > { > public function __construct(?string $url = null) {} > public function get(int $part, int $flags = 0): string {} > public function set(int $part, string $content, int $flags = 0): void > {} > public function getErrno(): int {} > public function __toString(): string {} > public function __clone() {} > } > > - It would also be nice to add this object oriented API for existing > CurlHandle, CurlMultiHandle and CurlShareHandle classes. For example the > CurlHandle class would look like that (First implementation [6]) > > final class CurlHandle > { > public function __construct(?string $url = null) {} > public function setOpt(int $option, mixed $value): bool {} > public function getInfo(?int $option = null): mixed {} > public function exec(): string|bool {} > public function escape(string $string): string|false {} > public function unescape(string $string): string|false {} > public function pause(int $flags): int {} > public function getErrno(): int {} > public function reset(): void; > public function setOptArray(array $options): bool {} > public function upkeep(): bool {} > public function __clone() {} > } > > As of right now I still have some unanswered questions like how should we > handle errors on the new CurlUrl API ? > - Throw `CurlUrlException` on both the procedural and object oriented style > API (that's how current implementation works [5]) > - Throw `CurlUrlException` with the oriented style API, but return for > example boolean/null on errors when user uses the procedural API ? > - Always return null/booleans using both object oriented API and > procedural API ? > > The same question applies if we add a new object oriented style API on > existing classes. Current functions MUST stay unchanged but should we throw > `CurlException` when the user uses the object oriented style API ? (That's > what I would do) Or should we return the same result from OO and procedural > API ? Should we make the new CurlApi consistent with that ? > > What are your thoughts about all this ? Any feedback on any of those > subjects are more than welcome. > > Pierrick > > [1] > https://daniel.haxhttps:// > github.com/adoy/php-src/tree/curl-object-apix.se/blog/2018/10/31/curl-7-62-0-moar-stuff/ > <https://daniel.haxx.se/blog/2018/10/31/curl-7-62-0-moar-stuff/> > [2] https://daniel.haxx.se/blog/2018/09/09/libcurl-gets-a-url-api/ > [3] > > https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf > [4] https://github.com/curl/curl/blob/master/include/curl/urlapi.h > [5] https://github.com/php/php-src/pull/8770 > [6] https://github.com/adoy/php-src/tree/curl-object-api
I understand why breaking changes would definitely be a no go here, but if someone is adapting their code from procedural to OOP I would say they can catch exceptions instead of comparing against false. To me it would even be desirable. Any new code that didn't exist before show prefer throwing over returning false, imo.
> >
  117961
June 16, 2022 08:41 mel@dafert.at (Mel Dafert)
On 16 June 2022 09:10:08 CEST, Pierrick Charron <pierrick@php.net> wrote:
> [...] >- For consistency expose the new Curl URL API as functions mapped one to >one to libcurl functions : > >function curl_url(?string $url = null): CurlUrl|false {} >function curl_url_set(CurlUrl $url, int $part, string $content, int $flags >= 0): bool {} >function curl_url_get(CurlUrl $url, int $part, int $flags = 0): >string|false {} >function curl_url_errno(CurlUrl $url): int {} >function curl_url_strerror(int $error_code): ?string {} > >- Add methods to the CurlUrl object to make it less opaque and expose an >object oriented style API. I would keep it minimal and let userlanAd API >provide higher level APIs as guzzle for example. (You can see the current >implementation [5]) > >final class CurlUrl implements Stringable >{ > public function __construct(?string $url = null) {} > public function get(int $part, int $flags = 0): string {} > public function set(int $part, string $content, int $flags = 0): void {} > public function getErrno(): int {} > public function __toString(): string {} > public function __clone() {} >}
Hello, When IntlDatePatternGenerator was implemented, I initially also supplied both a procedural and OO-style API, but was told that this duplication was historical and not necessary for new APIs. See the thread following this message: [1] I would argue that this also applies to curl, and that it might make sense to only supply the OO-style API here as well. (With `curl_url_strerror` being exposed as either a static method on `CurlUrl` or as `getErrorMessage`, I suppose.)
>- It would also be nice to add this object oriented API for existing >CurlHandle, CurlMultiHandle and CurlShareHandle classes. For example the >CurlHandle class would look like that (First implementation [6])
I think this would be a good idea either way. Regards, Mel [1] https://externals.io/message/114473#114658
  117964
June 16, 2022 12:57 tim@bastelstu.be (=?UTF-8?Q?Tim_D=c3=bcsterhus?=)
Hi

On 6/16/22 09:10, Pierrick Charron wrote:
> As of right now I still have some unanswered questions like how should we > handle errors on the new CurlUrl API ? > - Throw `CurlUrlException` on both the procedural and object oriented style > API (that's how current implementation works [5]) > - Throw `CurlUrlException` with the oriented style API, but return for > example boolean/null on errors when user uses the procedural API ? > - Always return null/booleans using both object oriented API and > procedural API ?
Definitely not this one. I want Exceptions for an OO API. I don't particularly care about the prodecural API, as it is not likely that I would use it, given that it is more clunky.
> The same question applies if we add a new object oriented style API on > existing classes. Current functions MUST stay unchanged but should we throw > `CurlException` when the user uses the object oriented style API ? (That's > what I would do) Or should we return the same result from OO and procedural > API ? Should we make the new CurlApi consistent with that ?
Same here: Exceptions for OO, please.
> What are your thoughts about all this ? Any feedback on any of those > subjects are more than welcome. >
Something else you didn't mention: Would it be possible to make the `int $part` parameter an enum? Best regards Tim Düsterhus
  117965
June 16, 2022 13:07 tekiela246@gmail.com (Kamil Tekiela)
First of all, thank you for working on this. I wanted OO API for Curl for a
long time.

Exceptions all the way. Code that's not using exceptions is usually more
clunky and error-prone. The new OO API shouldn't have the possibility to
return null/false on error. This is considered a thing of the past nowadays
and the majority of developers prefer exceptions on error.

Please do not add any more procedural APIs. The existing ones should be
deprecated and removed at some point in the future.

Regards
Kamil
  117967
June 16, 2022 14:26 landers.robert@gmail.com (Robert Landers)
On Thu, Jun 16, 2022 at 3:07 PM Kamil Tekiela <tekiela246@gmail.com> wrote:
> > First of all, thank you for working on this. I wanted OO API for Curl for a > long time. > > Exceptions all the way. Code that's not using exceptions is usually more > clunky and error-prone. The new OO API shouldn't have the possibility to > return null/false on error. This is considered a thing of the past nowadays > and the majority of developers prefer exceptions on error. > > Please do not add any more procedural APIs. The existing ones should be > deprecated and removed at some point in the future. > > Regards > Kamil
> This is considered a thing of the past nowadays and the majority of developers prefer exceptions on error.
This is certainly not true. A nice thing about errors in returns vs. an exception is that you don't need to react to the error immediately or abandon the current flow of the code by jumping out of it. I feel like I see a lot of devs using exceptions for flow control instead of actually exceptional behavior. A bad URL is probably exceptional -- if it's actually malformed vs. something the parser just doesn't understand yet, such as a new scheme -- while a failed connection is almost certainly not, that's just TCP doing its thing and should be expected in most circumstances. -- Rob
  117968
June 16, 2022 15:43 jeff@systasis.co (Jeffrey Chimene)
On 6/16/22 07:26, Robert Landers wrote:
> On Thu, Jun 16, 2022 at 3:07 PM Kamil Tekiela <tekiela246@gmail.com> wrote: >> First of all, thank you for working on this. I wanted OO API for Curl for a >> long time. >> >> Exceptions all the way. Code that's not using exceptions is usually more >> clunky and error-prone. The new OO API shouldn't have the possibility to >> return null/false on error. This is considered a thing of the past nowadays >> and the majority of developers prefer exceptions on error. >> >> Please do not add any more procedural APIs. The existing ones should be >> deprecated and removed at some point in the future. >> >> Regards >> Kamil >> This is considered a thing of the past nowadays > and the majority of developers prefer exceptions on error. > > This is certainly not true. A nice thing about errors in returns vs. > an exception is that you don't need to react to the error immediately > or abandon the current flow of the code by jumping out of it. I feel > like I see a lot of devs using exceptions for flow control instead of > actually exceptional behavior. A bad URL is probably exceptional -- if > it's actually malformed vs. something the parser just doesn't > understand yet, such as a new scheme -- while a failed connection is > almost certainly not, that's just TCP doing its thing and should be > expected in most circumstances. > > -- Rob > IMNSHO, php is far more similar to basic than c. php longs to be c, but
because it's an interpreter, it can never be c. This discussion is interesting in that it reflects the collision of interpreted code and objects. 1. ON ERROR GOTO was as reprehensible in basic as longjmp in c. That's why local error handling was gradually adopted in basic, and so should it be for php. 2. The days of returning null or false on constructor error are long behind us. Such implementation reflects php's interpreter aspect. In the OO world, constructors shouldn't return a nugatory object on failure. They should resignal the failure, and the coder should handle the error locally to ease the technical debt. Branch on value rather than branch on exception should be in the rear view mirror. 3. re: "...using exceptions for flow control instead of actually exceptional behavior..." It's not the language's responsibility to be a nanny. That's why we use IDEs instead of EDT Thanks for reading, jec
  117969
June 16, 2022 19:47 larry@garfieldtech.com ("Larry Garfield")
On Thu, Jun 16, 2022, at 2:10 AM, Pierrick Charron wrote:
> Hi internals, > > Since its version 6.62.0 [1], libcurl features a brand new URL API [2] that > can be used to parse and generate URLs, using libcurl’s own parser. One of > the goals of this API is to tighten a problematic vulnerable area for > applications where the URL parser library would believe one thing and > libcurl another. This could and has sometimes led to security problems [3]. > The new API is handled base and composed of 5 new functions [4] (and one > more since 7.80.0 to get more verbose information upon error). > > I started to work on an implementation [5] to expose this API to PHP > userland in the curl extension so that PHP users can benefit from it. My > first reflex was to stay consistent on how the extension is currently > working and do a one to one mapping of the new curl functions. I got > feedback from both Ilija and Christoph saying that the API is, I quote, "a > bit clunky" which I can't disagree with. > > For a long time, ext/curl worked with handles as "curl resources" and > functions mapped to the libcurl functions, but since PHP8.0 "curl > resources" were converted to opaque classes with no methods. So my main > goal here is to come up with a solution for the new Curl URL API, but maybe > also to be consistent, make some changes to existing curl classes like > `CurlHandle` to add methods and improve the current state of the extension. > > Here is the solution I would propose : > - First of course keep all the current ext/curl functions as is not to > break any compatibility (Seems obvious but just to be sure everybody is on > the same page). > - For consistency expose the new Curl URL API as functions mapped one to > one to libcurl functions : > > function curl_url(?string $url = null): CurlUrl|false {} > function curl_url_set(CurlUrl $url, int $part, string $content, int $flags > = 0): bool {} > function curl_url_get(CurlUrl $url, int $part, int $flags = 0): > string|false {} > function curl_url_errno(CurlUrl $url): int {} > function curl_url_strerror(int $error_code): ?string {} > > - Add methods to the CurlUrl object to make it less opaque and expose an > object oriented style API. I would keep it minimal and let userlanAd API > provide higher level APIs as guzzle for example. (You can see the current > implementation [5]) > > final class CurlUrl implements Stringable > { > public function __construct(?string $url = null) {} > public function get(int $part, int $flags = 0): string {} > public function set(int $part, string $content, int $flags = 0): void {} > public function getErrno(): int {} > public function __toString(): string {} > public function __clone() {} > } > > - It would also be nice to add this object oriented API for existing > CurlHandle, CurlMultiHandle and CurlShareHandle classes. For example the > CurlHandle class would look like that (First implementation [6]) > > final class CurlHandle > { > public function __construct(?string $url = null) {} > public function setOpt(int $option, mixed $value): bool {} > public function getInfo(?int $option = null): mixed {} > public function exec(): string|bool {} > public function escape(string $string): string|false {} > public function unescape(string $string): string|false {} > public function pause(int $flags): int {} > public function getErrno(): int {} > public function reset(): void; > public function setOptArray(array $options): bool {} > public function upkeep(): bool {} > public function __clone() {} > } > > As of right now I still have some unanswered questions like how should we > handle errors on the new CurlUrl API ? > - Throw `CurlUrlException` on both the procedural and object oriented style > API (that's how current implementation works [5]) > - Throw `CurlUrlException` with the oriented style API, but return for > example boolean/null on errors when user uses the procedural API ? > - Always return null/booleans using both object oriented API and > procedural API ? > > The same question applies if we add a new object oriented style API on > existing classes. Current functions MUST stay unchanged but should we throw > `CurlException` when the user uses the object oriented style API ? (That's > what I would do) Or should we return the same result from OO and procedural > API ? Should we make the new CurlApi consistent with that ? > > What are your thoughts about all this ? Any feedback on any of those > subjects are more than welcome. > > Pierrick
Like most of the responders so far, I would say skip the procedural API, just go OOP and be done with it. However, I would go a step further and say it should be a *good* OOP API, not just the Curl procedural API with funny syntax. For example: public function get(int $part, int $flags = 0): string {} Absolutely not. :-) It should be public function getHost(), public function getScheme(), etc. The `int $part` bit is frankly bad design even by procedural standards, and has no place in a modern library. I don't even know what the $flags are or could be, which means that's also a bad design. They should either be omitted, handled via separate methods, or replaced with named arguments with reasonable defaults. (We can do that now, yay!) Translating those into Curl's nutty flag API is something that should be done once, in the wrapping extension/object, and no PHP user space developer should have to think about it. Similarly, getErrno() should be replaced. If a URL cannot even be parsed at all, that's an exception. Not every error should be an exception (I recently wrote extensively on the subject here: https://peakd.com/hive-168588/@crell/much-ado-about-null), but in this case "I don't know WTF to do with this string you gave my constructor" is an exception. If instead of a constructor it had a static factory method (or multiple), then we could discuss those returning some other sentinel value instead to indicate failure, but "there was an error, go call this other thing to find out what it was" is a fundamentally flawed API design that should not be replicated. In short, don't put a wrapper on the existing Curl API that happens to use ->. Design a good, usable, PHP-developer-friendly API, and put Curl behind it. Trying to just expose a crappy API and make it slightly less crappy is not a good use of time. --Larry Garfield
  117970
June 16, 2022 21:43 pierrick@php.net (Pierrick Charron)
Thanks for taking the time to answer and give feedback, that's really
appreciated.

Firstly, about the procedural API, if everyone agrees that we should not
create it (and it looks like it) I will definitely not go against it. This
was just to make it consistent with the current ext/curl api. Reading the
thread about IntlDatePatternGenerator (thanks Mel), it's clear that the
procedural API for the new API will be discarded.

About making a "Good OOP API", of course the goal is to make a *Good* OOP
API. But there are things to take into consideration. The proposal here is
yes to expose the new Curl URL API which is quite small, but also to modify
the existing curl API to make it a little bit more digest for developers.
Good or bad the existing ext/curl is here and will continue to exist for
quite some time. It was designed (maybe on purpose or not) to be a low
level API with tons [1] of low level features, and it was clearly designed
as a thin wrapper/bridge over libcurl. I mean the fact is currently each
constant is the exact same one as in libcurl, and each function is a
wrapper over the exact same function in libcurl. Is it OK to have one part
that is a thin wrapper and another part that is a "remodeling" of the API ?
(This is not a rhetorical question, I really ask myself the question).

Yes we could create a completely new high level API using curl underneath
but I think that if this is what we want, we should create a brand new
extension and start from scratch and design it as a nice High level API
from the start. But that's clearly not what I'm pretending to do.

We could also keep the existing API as is and not improve it living only
with the procedural API, but I think that with minimal effort, we could get
some small (but still) benefits. Yes, CurlHandle for example would just be
a wrapper on the procedural API that happens to use `->` and throw
exceptions instead of returning null/false,  but one of the gains would be
to help developers with autocomplete to find methods they can call on the
handle.

I'm sorry if the fact that this proposal includes two different subjects is
confusing but I think that how we want to deal with the current API will
have an effect on how we want to implement the new one and keep the thing
consistent.

You only talked about the new CurlUrl API in your previous mail, but I'm
curious what you would do with the existing API ?

Pierrick

[1] https://github.com/php/php-src/blob/master/ext/curl/interface.c#L382

Le jeu. 16 juin 2022, à 15 h 48, Larry Garfield <larry@garfieldtech.com> a
écrit :

> On Thu, Jun 16, 2022, at 2:10 AM, Pierrick Charron wrote: > > Hi internals, > > > > Since its version 6.62.0 [1], libcurl features a brand new URL API [2] > that > > can be used to parse and generate URLs, using libcurl’s own parser. One > of > > the goals of this API is to tighten a problematic vulnerable area for > > applications where the URL parser library would believe one thing and > > libcurl another. This could and has sometimes led to security problems > [3]. > > The new API is handled base and composed of 5 new functions [4] (and one > > more since 7.80.0 to get more verbose information upon error). > > > > I started to work on an implementation [5] to expose this API to PHP > > userland in the curl extension so that PHP users can benefit from it. My > > first reflex was to stay consistent on how the extension is currently > > working and do a one to one mapping of the new curl functions. I got > > feedback from both Ilija and Christoph saying that the API is, I quote, > "a > > bit clunky" which I can't disagree with. > > > > For a long time, ext/curl worked with handles as "curl resources" and > > functions mapped to the libcurl functions, but since PHP8.0 "curl > > resources" were converted to opaque classes with no methods. So my main > > goal here is to come up with a solution for the new Curl URL API, but > maybe > > also to be consistent, make some changes to existing curl classes like > > `CurlHandle` to add methods and improve the current state of the > extension. > > > > Here is the solution I would propose : > > - First of course keep all the current ext/curl functions as is not to > > break any compatibility (Seems obvious but just to be sure everybody is > on > > the same page). > > - For consistency expose the new Curl URL API as functions mapped one to > > one to libcurl functions : > > > > function curl_url(?string $url = null): CurlUrl|false {} > > function curl_url_set(CurlUrl $url, int $part, string $content, int > $flags > > = 0): bool {} > > function curl_url_get(CurlUrl $url, int $part, int $flags = 0): > > string|false {} > > function curl_url_errno(CurlUrl $url): int {} > > function curl_url_strerror(int $error_code): ?string {} > > > > - Add methods to the CurlUrl object to make it less opaque and expose an > > object oriented style API. I would keep it minimal and let userlanAd API > > provide higher level APIs as guzzle for example. (You can see the current > > implementation [5]) > > > > final class CurlUrl implements Stringable > > { > > public function __construct(?string $url = null) {} > > public function get(int $part, int $flags = 0): string {} > > public function set(int $part, string $content, int $flags = 0): > void {} > > public function getErrno(): int {} > > public function __toString(): string {} > > public function __clone() {} > > } > > > > - It would also be nice to add this object oriented API for existing > > CurlHandle, CurlMultiHandle and CurlShareHandle classes. For example the > > CurlHandle class would look like that (First implementation [6]) > > > > final class CurlHandle > > { > > public function __construct(?string $url = null) {} > > public function setOpt(int $option, mixed $value): bool {} > > public function getInfo(?int $option = null): mixed {} > > public function exec(): string|bool {} > > public function escape(string $string): string|false {} > > public function unescape(string $string): string|false {} > > public function pause(int $flags): int {} > > public function getErrno(): int {} > > public function reset(): void; > > public function setOptArray(array $options): bool {} > > public function upkeep(): bool {} > > public function __clone() {} > > } > > > > As of right now I still have some unanswered questions like how should we > > handle errors on the new CurlUrl API ? > > - Throw `CurlUrlException` on both the procedural and object oriented > style > > API (that's how current implementation works [5]) > > - Throw `CurlUrlException` with the oriented style API, but return for > > example boolean/null on errors when user uses the procedural API ? > > - Always return null/booleans using both object oriented API and > > procedural API ? > > > > The same question applies if we add a new object oriented style API on > > existing classes. Current functions MUST stay unchanged but should we > throw > > `CurlException` when the user uses the object oriented style API ? > (That's > > what I would do) Or should we return the same result from OO and > procedural > > API ? Should we make the new CurlApi consistent with that ? > > > > What are your thoughts about all this ? Any feedback on any of those > > subjects are more than welcome. > > > > Pierrick > > > Like most of the responders so far, I would say skip the procedural API, > just go OOP and be done with it. However, I would go a step further and > say it should be a *good* OOP API, not just the Curl procedural API with > funny syntax. > > For example: > > public function get(int $part, int $flags = 0): string {} > > Absolutely not. :-) It should be public function getHost(), public > function getScheme(), etc. The `int $part` bit is frankly bad design even > by procedural standards, and has no place in a modern library. I don't > even know what the $flags are or could be, which means that's also a bad > design. They should either be omitted, handled via separate methods, or > replaced with named arguments with reasonable defaults. (We can do that > now, yay!) Translating those into Curl's nutty flag API is something that > should be done once, in the wrapping extension/object, and no PHP user > space developer should have to think about it. > > Similarly, getErrno() should be replaced. If a URL cannot even be parsed > at all, that's an exception. Not every error should be an exception (I > recently wrote extensively on the subject here: > https://peakd.com/hive-168588/@crell/much-ado-about-null), but in this > case "I don't know WTF to do with this string you gave my constructor" is > an exception. If instead of a constructor it had a static factory method > (or multiple), then we could discuss those returning some other sentinel > value instead to indicate failure, but "there was an error, go call this > other thing to find out what it was" is a fundamentally flawed API design > that should not be replicated. > > In short, don't put a wrapper on the existing Curl API that happens to use > ->. Design a good, usable, PHP-developer-friendly API, and put Curl behind > it. Trying to just expose a crappy API and make it slightly less crappy is > not a good use of time. > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  117972
June 17, 2022 08:27 kjarli@gmail.com (Lynn)
Good timezone!

On Thu, Jun 16, 2022 at 11:44 PM Pierrick Charron <pierrick@php.net> wrote:

> About making a "Good OOP API", of course the goal is to make a *Good* OOP > API. But there are things to take into consideration. The proposal here is > yes to expose the new Curl URL API which is quite small, but also to modify > the existing curl API to make it a little bit more digest for developers. > Good or bad the existing ext/curl is here and will continue to exist for > quite some time. It was designed (maybe on purpose or not) to be a low > level API with tons [1] of low level features, and it was clearly designed > as a thin wrapper/bridge over libcurl. I mean the fact is currently each > constant is the exact same one as in libcurl, and each function is a > wrapper over the exact same function in libcurl. Is it OK to have one part > that is a thin wrapper and another part that is a "remodeling" of the API ? > (This is not a rhetorical question, I really ask myself the question). >
I'm not a C developer, and the only other place I've ever used cURL is on the command line. I honestly care very little for it resembling whatever the C library is, as C is a different language with no OOP. The procedural API for cURL is really annoying to deal with, and I think it would be worth designing an OOP counterpart. I think most of this would go into a new design for setting options among things, as a list of constants with possible values is one of the worst ways to have to configure something in my opinion. I know that both the Symfony Http Client and Guzzle are popular libraries, perhaps design wise they could serve as an inspiration? I'm personally not too experienced with cURL nor the level of details that go into http libraries, but I do see this as an opportunity to make a really good implementation from scratch. In my opinion it's worth spending some time on this. Larry said: Like most of the responders so far, I would say skip the procedural API,
> just go OOP and be done with it. >
I'm okay implementing one last feature in the procedural API if it's really desired to have this functionality, especially if this is beneficial for security and reduces bugs. The reason being is that even if we have the best possible OOP library for cURL, every single procedural API would benefit from this change without having to completely rewrite their implementation, which will be a problem if the OOP interface isn't just a 1:1 copy into object form. That said, we should avoid having: cURL procedural + cURL procedural in objects + cURL OOP. Having 2 different object based libraries to do the same thing PHP is confusing and will just end up in way too many Stack Overflow questions. Perhaps it is best to split this into 2 separate RFCs? Regards, Lynn
  117973
June 17, 2022 10:18 craig@craigfrancis.co.uk (Craig Francis)
On 17 Jun 2022, at 09:27, Lynn <kjarli@gmail.com> wrote:
> ... That said, we should avoid having: cURL procedural + cURL procedural in objects + cURL OOP. Having 2 different object based libraries to do the same thing PHP is confusing and will just end up in way too many Stack Overflow questions. > > Perhaps it is best to split this into 2 separate RFCs?
tbh, I'd worry the OOP version would need a fair amount of discussion, and experimentation... e.g. what the methods/parameters should be, deciding how errors/oddities are handled (where exceptions should be used, can NULL be returned (aka the 9.0 grenade), or other fancy approaches like monads?), and how `curl_multi_*` functionality would work. Could the OOP work be done separately, maybe starting in userland, so those decisions could be made... and in the mean time, ext/curl gets a quick update to expose this new URL API in the procedural style (keeping consistency, and keeping it as a thin wrapper for now)? Craig
  117974
June 17, 2022 12:17 pierrick@php.net (Pierrick Charron)
Hi Lynn,

You have to be careful, even though most developers associate curl with an
http client and only use this feature, it's only part of what it is. It's
a multiprotocol file transfer library that supports DICT, FILE, FTP, FTPS,
GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S,
RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP.

Again I'm not against a new extension that deals nicely with HTTP and has a
super nice intuitive OOP API. But for me that's just not the curl
extension. That would be a different project like ext/http.

Pierrick

Le ven. 17 juin 2022, à 04 h 27, Lynn <kjarli@gmail.com> a écrit :

> Good timezone! > > On Thu, Jun 16, 2022 at 11:44 PM Pierrick Charron <pierrick@php.net> > wrote: > >> About making a "Good OOP API", of course the goal is to make a *Good* OOP >> API. But there are things to take into consideration. The proposal here is >> yes to expose the new Curl URL API which is quite small, but also to >> modify >> the existing curl API to make it a little bit more digest for developers.. >> Good or bad the existing ext/curl is here and will continue to exist for >> quite some time. It was designed (maybe on purpose or not) to be a low >> level API with tons [1] of low level features, and it was clearly designed >> as a thin wrapper/bridge over libcurl. I mean the fact is currently each >> constant is the exact same one as in libcurl, and each function is a >> wrapper over the exact same function in libcurl. Is it OK to have one part >> that is a thin wrapper and another part that is a "remodeling" of the API >> ? >> (This is not a rhetorical question, I really ask myself the question). >> > > I'm not a C developer, and the only other place I've ever used cURL is on > the command line. I honestly care very little for it resembling whatever > the C library is, as C is a different language with no OOP. The procedural > API for cURL is really annoying to deal with, and I think it would be worth > designing an OOP counterpart. I think most of this would go into a new > design for setting options among things, as a list of constants with > possible values is one of the worst ways to have to configure something in > my opinion. I know that both the Symfony Http Client and Guzzle are popular > libraries, perhaps design wise they could serve as an inspiration? > > I'm personally not too experienced with cURL nor the level of details that > go into http libraries, but I do see this as an opportunity to make a > really good implementation from scratch. In my opinion it's worth spending > some time on this. > > Larry said: > > Like most of the responders so far, I would say skip the procedural API, >> just go OOP and be done with it. >> > > I'm okay implementing one last feature in the procedural API if it's > really desired to have this functionality, especially if this is beneficial > for security and reduces bugs. The reason being is that even if we have the > best possible OOP library for cURL, every single procedural API would > benefit from this change without having to completely rewrite their > implementation, which will be a problem if the OOP interface isn't just a > 1:1 copy into object form. That said, we should avoid having: cURL > procedural + cURL procedural in objects + cURL OOP. Having 2 different > object based libraries to do the same thing PHP is confusing and will just > end up in way too many Stack Overflow questions. > > Perhaps it is best to split this into 2 separate RFCs? > > Regards, > Lynn >
  117977
June 17, 2022 13:55 rowan.collins@gmail.com (Rowan Tommins)
Hi Pierrick,


On Thu, 16 Jun 2022 at 22:44, Pierrick Charron <pierrick@php.net> wrote:

> Is it OK to have one part > that is a thin wrapper and another part that is a "remodeling" of the API ? > (This is not a rhetorical question, I really ask myself the question). >
I agree with others that the new API should be exposed via a new, well-designed object, with no procedural version or low-level equivalence to libcurl. Something that nobody's brought up yet is that the curl extension actually already has a facility designed this way: CurlFile and CurlStringFile are high-level PHP objects which allow users to interact with file uploads, without any knowledge of what libcurl's API for them looks like. I think it's perfectly reasonable for CurlUrl to be designed the same way, regardless of what else we do with the extension.
> We could also keep the existing API as is and not improve it living only > with the procedural API, but I think that with minimal effort, we could get > some small (but still) benefits. Yes, CurlHandle for example would just be > a wrapper on the procedural API that happens to use `->` and throw > exceptions instead of returning null/false, but one of the gains would be > to help developers with autocomplete to find methods they can call on the > handle. >
This feels like a very small gain, since users can already type "curl_" and get a list of all curl functions. It also has real costs: users may be confused why there are two ways of writing the same thing; and it sets the precedent that methods on CurlHandle should mirror curl_* functions, even though we know those have terrible usability. I think if we do add methods to the CurlHandle class, they should be higher-level methods for common tasks that are currently unnecessarily awkward. I don't think we'd need to add everything at once, just establish some general design principles. (I'm honestly surprised that CURLOPT_RETURNTRANSFER, and curl_setopt in general, doesn't make it onto more lists of the worst parts of PHP.) Regards, -- Rowan Tommins [IMSoP]
  117999
June 19, 2022 02:39 pierrick@php.net (Pierrick Charron)
Hi Rowan, all,

Thanks for your responses and comments.


> I think it's perfectly reasonable for CurlUrl to be designed the same way, > regardless of what else we do with the extension. >
As suggested by most of you, I created a new version of the proposed new URL API with a friendlier interface [1]. A quick descriptions of the changes I made : - The curl_url_* procedural API was removed - The CurlUrl::set() and ::get() methods with the CURLUPART_ constants were replaced by more explicit setters and getters (ex: setHost() and getHost()). - All the CURLU_* constants are now CurlUrl class constants (ex: CURLU_GUESS_SCHEME => CurlUrl::GUESS_SCHEME) - All the CURLUE_* constants are now CurlUrlException class constants (ex: CURLUE_MALFORMED_INPUT => CurlUrlException::MALFORMED_INPUT) Does it look more like what you were expecting ? Any other improvements that should be made ? This feels like a very small gain, since users can already type "curl_" and
> get a list of all curl functions. It also has real costs: users may be > confused why there are two ways of writing the same thing; and it sets the > precedent that methods on CurlHandle should mirror curl_* functions, even > though we know those have terrible usability. >
This is not the only change that I would like to introduce with a new OO API. One other change that I would like to introduce is a better type checking of `CurlHandle::setOpt()` when declaring strict_types to 1 (I know Sara once opened a PR about this [2]). The current signature of the procedural API is `curl_setopt(CurlHandle $handle, int $option, mixed $value): bool`. The 3rd argument being mixed never throws any TypeError, and adding this to the current procedural API would be a breaking change. If we add a new OOP API this kind of change is possible and we can improve the error message like : "Argument 2 passed to CurlHandle::setOpt() for option CURLOPT_BUFFERSIZE must be of type int, string given" However, knowing that the feature freeze for 8.2 is in a month, I will put more emphasis on the Curl URL API than on a new OO API for existing Curl API. Thanks again for your feedback Pierrick [1] https://github.com/adoy/php-src/pull/1/files [2] https://github.com/php/php-src/pull/2495
  117984
June 17, 2022 16:14 pollita@php.net (Sara Golemon)
On Thu, Jun 16, 2022 at 2:10 AM Pierrick Charron <pierrick@php.net> wrote:

> For a long time, ext/curl worked with handles as "curl resources" and > functions mapped to the libcurl functions, but since PHP8.0 "curl > resources" were converted to opaque classes with no methods. So my main > goal here is to come up with a solution for the new Curl URL API, but maybe > also to be consistent, make some changes to existing curl classes like > `CurlHandle` to add methods and improve the current state of the extension. > > This is so bizarre, I *know* I wrote an OOPified cURL extension some years
ago (called it curli), and now I can't find it anywhere. What universe am I even in? Anyway, +1 on making a whole new OOPified cURL implementation. $ch = (new CurlHandle($uri))->setOpt(Curl::OPT_METHOD, 'post')->perform(); Let it throw exceptions, do proper type checks, all the goodness. Let the procedural APIs behave differently than the object methods and that's okay. cURL is a foundational extension in PHP and I respect the choices that were made in its API design, but it's 2022, and we deserve a better ext/curl. -Sara
  117998
June 17, 2022 21:00 landers.robert@gmail.com (Robert Landers)
On Fri, Jun 17, 2022 at 6:14 PM Sara Golemon <pollita@php.net> wrote:
> > On Thu, Jun 16, 2022 at 2:10 AM Pierrick Charron <pierrick@php.net> wrote: > > > For a long time, ext/curl worked with handles as "curl resources" and > > functions mapped to the libcurl functions, but since PHP8.0 "curl > > resources" were converted to opaque classes with no methods. So my main > > goal here is to come up with a solution for the new Curl URL API, but maybe > > also to be consistent, make some changes to existing curl classes like > > `CurlHandle` to add methods and improve the current state of the extension. > > > > > This is so bizarre, I *know* I wrote an OOPified cURL extension some years > ago (called it curli), and now I can't find it anywhere. What universe am > I even in? > > Anyway, +1 on making a whole new OOPified cURL implementation. $ch = > (new CurlHandle($uri))->setOpt(Curl::OPT_METHOD, 'post')->perform(); > Let it throw exceptions, do proper type checks, all the goodness. Let the > procedural APIs behave differently than the object methods and that's okay. > > cURL is a foundational extension in PHP and I respect the choices that were > made in its API design, but it's 2022, and we deserve a better ext/curl. > > -Sara
Also, would it be unreasonable to ask it to take advantage of the Fiber constructs if in a Fiber context? That would be simply amazing if this high-level OOP implementation were async-ish by default. If anything should get native Fiber superpowers, it should be this extension, IMHO. Also, IMHO, this is an unreasonable request, but perhaps a separate RFC once this original proposal is accepted and figured out?
  118000
June 19, 2022 02:53 pierrick@php.net (Pierrick Charron)
Hi Sara


> This is so bizarre, I *know* I wrote an OOPified cURL extension some years > ago (called it curli), and now I can't find it anywhere. What universe am > I even in? >
I don't know but if you pass through the parallel universe where Curli is, I'm interested.
> > Anyway, +1 on making a whole new OOPified cURL implementation. $ch = > (new CurlHandle($uri))->setOpt(Curl::OPT_METHOD, 'post')->perform(); > Let it throw exceptions, do proper type checks, all the goodness. Let the > procedural APIs behave differently than the object methods and that's okay. > > cURL is a foundational extension in PHP and I respect the choices that > were made in its API design, but it's 2022, and we deserve a better > ext/curl. >
I hope you don't mind, I took some of your code from your "Enable strict_types checking for curl_setopt()" pull request [1] to do some test on introducing this but only on the OOP API. It's working very well [2]. Can I know why this PR was closed ? Any issues ? Or was it more because it was too much of a change for the procedural API ? Thanks Pierrick [1] https://github.com/php/php-src/pull/2495 [2] https://github.com/adoy/php-src/pull/2
  118001
June 19, 2022 13:54 rowan.collins@gmail.com (Rowan Tommins)
On 19 June 2022 03:53:17 BST, Pierrick Charron <pierrick@php.net> wrote:
> >I hope you don't mind, I took some of your code from your "Enable >strict_types checking for curl_setopt()" pull request [1] to do some test >on introducing this but only on the OOP API. It's working very well [2]. >Can I know why this PR was closed ? Any issues ? Or was it more because it >was too much of a change for the procedural API ?
While a few type errors there might be useful, it still feels a bit like polishing a turd. I count about 180 different options that can be passed to curl_setopt. Some of them are used by nearly every user of PHP, and some are for very obscure niche uses. Many of them are useless on their own, and exist only to tweak the behaviour of some other option, or need to be used in groups like usernames and passwords. Others have unintuitive and unhelpful defaults, that need to be overridden with a different option. The manual page has long topped the league table for user comments, currently standing at 102. It is simply not a practical design for what most users of PHP need. I think one way out of this mess is to start grouping options together, and providing specific methods to set them, with named, type-safe parameters. For instance, CurlHandle::setProxyOptions(string $url, ?string $authUserName, ?string $authPassword, ...) and so on. If the long lists of parameters still feel a bit messy, we could go a step further and make objects for building sets of options, with methods taking short lists of genuinely dependent options, e.g. CurlProxyOptions::setAuth(string $userName, string $password) and CurlProxyOptions::disableAuth() Some of the options should be rethought in the process to make more sense to PHP's common usage, rather than libcurl's. As just one example, enabling CURLOPT_VERBOSE sends some debug information to stderr, but on a web server that is normally a log file where it will be mixed in with other information. To capture it instead you need to also set CURLOPT_STDERR, which requires an open file handle. What most users *actually* want is for that information to be available to them as a string after the request is executed. Another thing that might be useful is some new factory methods that set sensible defaults, like CurlHandle::createForHttp(string|CurlUrl $url, string $method) If we can build these things on top of the existing CurlHandle, we can release a few things first, and progressively add features. Rather than having to decide which extension to use, users will still have access to curl_setopt for things there isn't a nicer interface for yet. We can even leave it in place as something like CurlHandle::setRawOption for when users want fine control of the library, or some really obscure setting. Regards, -- Rowan Tommins [IMSoP]
  118007
June 20, 2022 13:13 pierrick@php.net (Pierrick Charron)
Rowan, all,

Thanks again for your comments. PHP8.2 is going to be feature freeze in
exactly one month now and as the currently proposed improvements have not
received any interest (and that's OK), I will put those aside for the
moment and come back with a new approach that I hope will be better for the
future release (8.3 ?)

However, about the new Curl URL API, I think it's still time to finalize
the discussions and include it in the 8.2 release as it allows us to solve
some potential security issues.

What do you think ? Do you see any interest in adding the new CurlUrl class
in PHP8.2 ? Again currently proposed implementation can be found here [1]
and is waiting for your new comments.

Pierrick

[1]
https://github.com/adoy/php-src/pull/1/files#diff-5bd329a70f563b5b6eded3b710514a4fac605329087a7bd118e40f80b9fc8ee3


Le dim. 19 juin 2022, à 09 h 55, Rowan Tommins collins@gmail.com> a
écrit :

> On 19 June 2022 03:53:17 BST, Pierrick Charron <pierrick@php.net> wrote: > > > >I hope you don't mind, I took some of your code from your "Enable > >strict_types checking for curl_setopt()" pull request [1] to do some test > >on introducing this but only on the OOP API. It's working very well [2]. > >Can I know why this PR was closed ? Any issues ? Or was it more because it > >was too much of a change for the procedural API ? > > While a few type errors there might be useful, it still feels a bit like > polishing a turd. > > I count about 180 different options that can be passed to curl_setopt. > Some of them are used by nearly every user of PHP, and some are for very > obscure niche uses. Many of them are useless on their own, and exist only > to tweak the behaviour of some other option, or need to be used in groups > like usernames and passwords. Others have unintuitive and unhelpful > defaults, that need to be overridden with a different option. The manual > page has long topped the league table for user comments, currently standing > at 102. It is simply not a practical design for what most users of PHP need. > > I think one way out of this mess is to start grouping options together, > and providing specific methods to set them, with named, type-safe > parameters. For instance, CurlHandle::setProxyOptions(string $url, ?string > $authUserName, ?string $authPassword, ...) and so on. > > If the long lists of parameters still feel a bit messy, we could go a step > further and make objects for building sets of options, with methods taking > short lists of genuinely dependent options, e.g. > CurlProxyOptions::setAuth(string $userName, string $password) and > CurlProxyOptions::disableAuth() > > Some of the options should be rethought in the process to make more sense > to PHP's common usage, rather than libcurl's. As just one example, enabling > CURLOPT_VERBOSE sends some debug information to stderr, but on a web server > that is normally a log file where it will be mixed in with other > information. To capture it instead you need to also set CURLOPT_STDERR, > which requires an open file handle. What most users *actually* want is for > that information to be available to them as a string after the request is > executed. > > Another thing that might be useful is some new factory methods that set > sensible defaults, like CurlHandle::createForHttp(string|CurlUrl $url, > string $method) > > If we can build these things on top of the existing CurlHandle, we can > release a few things first, and progressively add features. Rather than > having to decide which extension to use, users will still have access to > curl_setopt for things there isn't a nicer interface for yet. We can even > leave it in place as something like CurlHandle::setRawOption for when users > want fine control of the library, or some really obscure setting. > > Regards, > > -- > Rowan Tommins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  118009
June 20, 2022 13:44 cmbecker69@gmx.de ("Christoph M. Becker")
On 20.06.2022 at 15:13, Pierrick Charron wrote:

> Thanks again for your comments. PHP8.2 is going to be feature freeze in > exactly one month now and as the currently proposed improvements have not > received any interest (and that's OK), I will put those aside for the > moment and come back with a new approach that I hope will be better for the > future release (8.3 ?) > > However, about the new Curl URL API, I think it's still time to finalize > the discussions and include it in the 8.2 release as it allows us to solve > some potential security issues. > > What do you think ? Do you see any interest in adding the new CurlUrl class > in PHP8.2 ? Again currently proposed implementation can be found here [1] > and is waiting for your new comments. > > Pierrick > > [1] > https://github.com/adoy/php-src/pull/1/files#diff-5bd329a70f563b5b6eded3b710514a4fac605329087a7bd118e40f80b9fc8ee3
Given that designing a new OO API obviously isn't uncontroversial, and that there are only four weeks left till feature freeze, it might be best to go with a simple procedural API for PHP 8.2 only. This can be marked as being experimental, and can still be deprecated in one of the next minors. That's not nice for early adopters, but still seems better than to not introduce the CURL URL API in PHP 8.2, and certainly is better than to rush some OO API. Christoph
  118017
June 20, 2022 15:32 craig@craigfrancis.co.uk (Craig Francis)
On 20 Jun 2022, at 14:44, Christoph M. Becker <cmbecker69@gmx.de> wrote:
> On 20.06.2022 at 15:13, Pierrick Charron wrote: >> about the new Curl URL API, I think it's still time to finalize the discussions and include it in the 8.2 release as it allows us to solve some potential security issues. > > Given that designing a new OO API obviously isn't uncontroversial, and that there are only four weeks left till feature freeze, it might be best to go with a simple procedural API for PHP 8.2 only.
+1... while I'd also like an OO API, it will be a much bigger project, and would need a fair amount of thought/discussion. As to the URL API, it solves the problem of developers making their own URL parsers that often work differently to the cURL parser (those differences can cause security issues); and considering it's possible for cURL 7.62.0 (Oct 2018) to do that parsing, and it's a fairly simple API, that would work in a similar way to the existing cURL functionality in PHP, it would be good for PHP developers to use that in PHP 8.2. Craig
  118022
June 20, 2022 16:17 rowan.collins@gmail.com (Rowan Tommins)
On 20/06/2022 14:44, Christoph M. Becker wrote:
> Given that designing a new OO API obviously isn't uncontroversial, and > that there are only four weeks left till feature freeze, it might be > best to go with a simple procedural API for PHP 8.2 only.
I haven't read back through the thread, but my impression was that *for the curl URL facility specifically* the opposite was the case: a simple object with no procedural equivalent would be everyone's preference. CurlFile provides enough of a precedent for adding that IMO. Either way, we have to agree on some naming details, so I've left some comments on the PR. (By the way, the PR you linked is to merge into your own fork's master, not the actual central php-src repo. Not sure if that was deliberate.) Regards, -- Rowan Tommins [IMSoP]
  118026
June 20, 2022 21:59 pierrick@php.net (Pierrick Charron)
> > > I haven't read back through the thread, but my impression was that *for > the curl URL facility specifically* the opposite was the case: a simple > object with no procedural equivalent would be everyone's preference. > CurlFile provides enough of a precedent for adding that IMO. >
+1
> > Either way, we have to agree on some naming details, so I've left some > comments on the PR. > > Your suggested names were good, so I used them except for
`NON_SUPPORT_SCHEME` that I replaced with `ALLOW_UNSUPPORTED_SCHEME`.
> (By the way, the PR you linked is to merge into your own fork's master, > not the actual central php-src repo. Not sure if that was deliberate.) >
I didn't do it intentionally. Sorry about that. Regards Pierrick
  118024
June 20, 2022 20:39 pollita@php.net (Sara Golemon)
On Sat, Jun 18, 2022 at 9:53 PM Pierrick Charron <pierrick@php.net> wrote:

> I hope you don't mind, I took some of your code from your "Enable > strict_types checking for curl_setopt()" pull request [1] to do some test > on introducing this but only on the OOP API. It's working very well [2]. > Can I know why this PR was closed ? Any issues ? Or was it more because it > was too much of a change for the procedural API ? >
Don't mind in the slightest. :) Fair to assume I dropped it due to ADHD. I have a habit of SQUIRREL!!!!!!! -Sara