function subscribe($topics)
    {
        // This will fail, if socket is not connected
        if(!$this->socket) {
            $this->debugMessage("Subscribe failed, because socket is not connected");
            return false;
        }

        //
        $cnt = 2;

        // Create payload starting with packet ID
        $payload = chr($this->packet >> 8) . chr($this->packet & 0xff);

        // If for some reason topic is provided as string, convert it to array
        // If $topics is neither array nor string, refuse to continue
        if( !is_array($topics) && is_string($topics) ) {
            $topics = [ $topics => [ 'qos' => 1 ] ];
        } elseif( !is_array($topics) ) {
            return false;
        }

        //
        $numOfTopics = 0;
        foreach($topics as $topic=>$data) {
            // Topic data in wrong format?
            if( !is_array($data) || !isset($data['qos']) ) {
                continue;
            }

            //
            $payload.=$this->convertString($topic, $cnt);
            $payload.=chr($data['qos']); $cnt++;

            $this->topics[$topic]=$data;
            $numOfTopics++;
        }

        // If number of subscribed topics is 0, don't send the request
        if($numOfTopics == 0) {
            return false;
        }

        // Send SUBSCRIBE header & payload
        $header = chr(0x82).chr($cnt);
        fwrite($this->socket, $header, 2);
        fwrite($this->socket, $payload, $cnt);

        // Wait for SUBACK packet
        $resp_head = $this->readBytes(2, false);
        if( strlen($resp_head) != 2 || ord($resp_head{0}) != 0x90 ) {
            $this->debugMessage("Invalid SUBACK packet received (stage 1)");
            return false;
        }

        // Read remainder of the response
        $bytes = ord($resp_head{1});
        $resp_body = $this->readBytes($bytes, false);
        if( strlen($resp_body) < 2 ) {
            $this->debugMessage("Invalid SUBACK packet received (stage 2)");
            return false;
        }

        $package_id = ( ord($resp_body{0}) << 8 ) + ord($resp_body{1});
        if( $this->packet != $package_id ) {
            $this->debugMessage("SUBACK packet received for wrong message");
            return false;
        }

        // FIXME: Process the rest of the SUBACK payload

        //
        $this->packet++;
        return true;
    }