|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-08-02 13:28 UTC] email at davekok dot nl
Description: ------------ Currently it is rather hard to support both IPv4 and IPv6 in PHP when using sockets. It would be rather nice if getaddrinfo system function would be available to PHP scripts. If have yet to find a alternative for PHP that works just as clean. PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 21:00:01 2025 UTC |
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.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_getaddrinfoI see what you're looking for. I've gone ahead and did a 3rd attempt at this guy with the use of: $addrinfo = socket_getaddrinfo('127.0.0.1', 2000, array( 'ai_family' => AF_INET, 'ai_socktype' => SOCK_STREAM, )); echo "Server: Starting\n"; $info = reset($addrinfo); $sock = socket_create($info['ai_family'], $info['ai_socktype'], $info['ai_protocol']); if ($sock) { socket_bind($sock, $info['ai_addr']) or die("Could not bind"); socket_listen($sock) or die("Could not listen"); $info['ai_addr'] here is a resource of the underlying sockaddr structure. I foresee this implementation a bit more contentious to advocate. Due to the fact that socket_connect, and socket_bind change signatures from socket_(connect/bind) (resource $sock, string $address[, int port]) to being socket_(connect/bind) (resource $sock, mixed $arg[, int port]) where $arg can be string address where 3rd argument is used or where $args is resource of sockaddr and 3rd arg is ignored I'll make sure to document all this for the RFC and see what everyone has to say about it.