Muitas linguagens oferecem suporte a Sockets, e com PHP não é diferente, porém a falta de orientação a objetos nas funções do PHP pode ser um inconveniente para algumas pessoas. E como eu me incluo entre essas pessoas, quando precisei utilizar sockets em PHP acabei criando um classe para englobar essas funções soltas e fornecer tratamento a erros.
/** * Copyright 2010 http://rogeriolino.com * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//** * Socket * * @author rogeriolino */classSocket{private$port=3000;private$address="localhost";private$blocking=true;private$buffer=2048;private$backlog=5;private$type=SOCK_STREAM;private$family=AF_INET;private$protocol=SOL_TCP;private$resource;/** * Socket constructor * @param $resource */publicfunction__construct($resource=null){if($resource==null){$this->resource=socket_create($this->family,$this->type,$this->protocol);}else{$this->resource=$resource;}}/** * Returns the socket port * @return int */publicfunctiongetPort(){return$this->port;}/** * Define the socket port * @param int $port */publicfunctionsetPort($port){$this->port=$port;}/** * * @return string */publicfunctiongetAddress(){return$this->address;}publicfunctionsetAddress($address){$this->address=$address;}/** * Returns if the socket is blocking mode * @return boolean */publicfunctionisBlocking(){return$this->blocking;}/** * Defines whether the socket is blocking or nonblocking mode * @param boolean $block */publicfunctionsetBlocking($blocking){$this->blocking=($blocking==true);$this->updateBlockingMode();}/** * Returns the socket communication type * @return int */publicfunctiongetType(){return$this->type;}/** * Define the socket communication type * @param int $type */publicfunctionsetType($type){if($type==SOCK_STREAM||$type==SOCK_DGRAM||$type==SOCK_SEQPACKET||$type==SOCK_RAW||$type==SOCK_RDM){$this->type=$type;}else{thrownewSocketException("Invalid socket communication type");}}/** * Returns the socket protocol family * @return int */publicfunctiongetFamily(){return$this->family;}/** * Define the socket protocol family * @param int $family */publicfunctionsetFamily($family){if($family==AF_INET||$family==AF_INET6||$family==AF_UNIX){$this->family=$family;}else{thrownewSocketException("Invalid socket protocol family");}}/** * Returns the socket protocol * @return int */publicfunctiongetProtocol(){return$this->protocol;}/** * Define the socket protocol, must be compatible whit the protocol family * @param int $protocol */publicfunctionsetProtocol($protocol){if($protocol==SOL_TCP||$protocol==SOL_UDP||$protocol==SOL_SOCKET){$this->protocol=$protocol;}else{thrownewSocketException("Invalid socket protocol");}}/** * Binds to a socket * @throws SocketException */publicfunctionbind(){if(socket_bind($this->resource,$this->address,$this->port)===false){thrownewSocketException("Socket bind failed: ".$this->error());}}/** * Listens for a connection on a socket * @throws SocketException */publicfunctionlisten(){if(socket_listen($this->resource,$this->backlog)===false){thrownewSocketException("Socket listen failed: ".$this->error());}}/** * Accepts a connection * @throws SocketException * @return Socket */publicfunctionaccept(){$sock=socket_accept($this->resource);if($sock===false){thrownewSocketException("Socket accept failed: ".$this->error());}returnnewSocket($sock);}/** * Reads data from the connected socket * @return string */publicfunctionread(){$data="";while(($m=socket_read($this->resource,$this->buffer))!=""){$data.=$m;}return$data;}/** * Write the data to connected socket * @param string $message */publicfunctionwrite($data){socket_write($this->resource,$data,strlen($data));}/** * Initiates a connection on a socket * @throws SocketException * @return boolean */publicfunctionconnect(){try{returnsocket_connect($this->resource,$this->address,$this->port);}catch(SocketException$e){returnfalse;}}/** * Close the socket connection */publicfunctionclose(){socket_close($this->resource);}privatefunctionupdateBlockingMode(){if($this->blocking){socket_set_block($this->resource);}else{socket_set_nonblock($this->resource);}}privatefunctionerror(){returnsocket_strerror(socket_last_error($this->resource));}}
Classe para as exceções:
1234567891011121314151617181920212223242526272829
/** * Copyright 2010 http://rogeriolino.com * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//** * SocketException * * @author rogeriolino */classSocketExceptionextendsException{publicfunction__construct($message,$code=0,$previous=null){$this->message=$message;$this->code=$code;$this->message=$previous;}}