Req #72733 [Com]: It would be nice to have something like getaddrinfo.

From: Date: Wed, 10 Aug 2016 03:12:01 +0000
Subject: Req #72733 [Com]: It would be nice to have something like getaddrinfo.
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-203131@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 Comment by: dave at mudsite dot com 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: 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 Previous Comments: ------------------------------------------------------------------------ [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. ------------------------------------------------------------------------ [2016-08-07 04:12:58] kalle@php.net Could you expand your idea with some code examples of what you do now and how you propose a solution to visualize this some more? ------------------------------------------------------------------------ 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

« previous php.bugs (#203131) next »