Req #72733 [Opn]: It would be nice to have something like getaddrinfo.
| From: | email at davekok dot nl | Date: | Wed, 10 Aug 2016 11:35:27 +0000 |
| Subject: | Req #72733 [Opn]: It would be nice to have something like getaddrinfo. | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-203150@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72733&edit=1
ID: 72733
User updated by: email at davekok dot nl
Reported by: email at davekok dot nl
Summary: It would be nice to have something like getaddrinfo.
Status: Open
Type: Feature/Change Request
Package: Sockets related
Operating System: Any
PHP Version: 7.0.9
Block user comment: N
Private report: N
New Comment:
I think it would be useful if the socket api remains as much as possible similar to how it is known
in other languages. So the second where socket_bind and socket_listen are used to receive a addrinfo
resource would be my preference.
Is there any reason to add a socket_addrinfo_close function. Can this not be garbage collected?
Previous Comments:
------------------------------------------------------------------------
[2016-08-10 03:11:58] dave at mudsite dot com
After playing around a bit I think the resource means is preferable. I'm sure discussions on
the merits of both will be raised though RFC process[1]. I feel the resource method is superior
because it's the actual sockaddr structure behind it. So if you do a
getaddrinfo("127.0.0.1", "ssh", NULL), the sockaddr structure already has into
it the correct port to use. Whereas the addrinfo structure doesn't contain the port
you're looking for. Your example uses
$this->address["ai_addr"],
however, ai_addr isn't a port number like you're using it. It's the sockaddr
structure. So I envision the typical array-return to look weird like this:
<?php
$infos = socket_getaddrinfo('127.0.0.1', 'ssh', array(
'ai_family' => AF_INET,
'ai_socktype' => SOCK_STREAM
));
$info = reset($infos);
$sock = socket_create(
$address["ai_family"],
$address["ai_socktype"],
$address["ai_protocol"]
);
socket_bind($sock, 22);
Whereas a resource based implementation could be:<?php
$infos = socket_getaddrinfo('127.0.0.1', 'ssh', array(
'ai_family' => AF_INET,
'ai_socktype' => SOCK_STREAM
));
$info = reset($infos);
$sock = socket_addrinfo_bind($info);
But I digress.
[1] - Draft RFC: https://wiki.php.net/rfc/socket_getaddrinfo
------------------------------------------------------------------------
[2016-08-08 15:41:09] email at davekok dot nl
I would indeed prefer an array to be returned rather then a resource with a additional functions.
Otherwise great work!!
------------------------------------------------------------------------
[2016-08-07 19:41:00] dave at mudsite dot com
I took a stab at
this(https://github.com/bp1222/php-src/commit/785284cdbc8a46d7c1b07567bb0d06d348112684).
implementing a
array socket_getaddrinfo(string $node, mixed $service[, array $hints])
This attempt returns an array of resources, each resource being a C addrinfo struct. To use, I just
made a socket_addrinfo_connect and socket_addrinfo_bind to accept the resource to connect/bind.
Although in your desired example, you'd want to just have an array of info from addrinfo
returned, and you call create&connect/bind with returned variables.
Not sure if one would be preferable over the other, I would assume implementing your use would be
better as it wouldn't require resources & would be a couple less functions declared.
------------------------------------------------------------------------
[2016-08-07 07:19:16] email at davekok dot nl
Oh perhaps it would have been a better example if the socket type hint would also by in the
constructor.
------------------------------------------------------------------------
[2016-08-07 07:02:27] email at davekok dot nl
That is indeed the point. Mostly I only have a hostname, not an IP address and knowing whether a
hostname supports or requires IPv6 is hard to find out. It requires you to do your own DNS queries.
There is no gethostbyname for IPv6 in PHP.
A simple socket wrapper could look something like this with getaddrinfo.
<?php
class Socket {
private $address;
private $socket;
public function __construct(string $host, string $service) {
$addresses = socket_addrinfo($host, $service, [
"ai_family"=>PF_UNSPEC,
"ai_socktype"=>SOCK_STREAM
]);
if ($addresses === false) throw new Exception("host not found");
$this->address = reset($addresses);
$this->socket = socket_create(
$address["ai_family"],
$address["ai_socktype"],
$address["ai_protocol"]
);
if (!$this->socket) throw new Exception("error creating socket");
}
public function bind() {
socket_bind($this->socket, $this->address["ai_addr"]);
}
public function listen(int $backlog = 0) {
socket_listen($this->socket, $backlog);
}
public function connect() {
socket_connect($this->socket, $this->address["ai_addr"]);
}
// other socket stuff
}
As an additional benefit you don't even need to know the port number you can just use the
service name.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=72733
--
Edit this bug report at https://bugs.php.net/bug.php?id=72733&edit=1