In the specialized class should I use self or parent to access the variables?

4

I have two classes, an abstract ( Connector ) and a specialized class ( ConnectorWmi ) that extends Connector .

My question is, considering the code below, in the specialized class I should instead call self :: $ connection , call parent :: $ connection and ** parent :: $ error message?

Abstract class:

abstract class Conector
{
    /**
     * Recurso de conexão externa
     * 
     * @var object
     */
    protected static $conexao;

    /**
     * Mensagem de erro
     * 
     * @var string
     */
    protected static $mensagemErro;

    /**
     * Realiza conexão com o host alvo
     * 
     * @param   string  $host
     * @param   string  $usuario
     * @param   string  $senha
     * @param   int     $porta
     * @param   int     $timeout
     * @return  void
     */
    abstract public static function conectar($host, $usuario = null, $senha = null, $porta = 135, $timeout = 10);

    /**
     * Consulta o status da conexão
     * 
     * @return bool
     */
    public static function status()
    {
        return (self::$conexao !== NULL) ? TRUE : FALSE;
    }

    /**
     * Retorna mensagem de erro gerada durante a tentativa de conexão 
     * ou erro gerado na chamada do método "executar"
     * 
     * @return string
     */
    public static function mensagemErro()
    {
        return self::$mensagemErro;
    }

    /**
     * Executa a instrução remotamente
     * 
     * @param   string $instrucao
     * @return  object
     */
    abstract public static function executar($instrucao);
}

Main class:

class ConectorWmi extends Conector
{    
    /**
     * Estabelece conexão com máquinas Windows via chamada COM
     * 
     * @param   string  $host
     * @param   string  $usuario
     * @param   string  $senha
     * @param   int     $porta
     * @param   int     $timeout
     * @return  void
     */
    public static function conectar($host, $usuario = null, $senha = null, $porta = 135, $timeout = 10)
    {
        try
        {
            /**
             * Testa conectividade com host alvo
             * 
             * @param string $host
             * @param string $porta
             * @param int    $errno   valor de sistema
             * @param string $errstr  mensagem de sistema
             * @param int    $timeout tempo máximo a esperar
             */    
            if (!$socket = @fsockopen($host, $porta, $errno, $errstr, $timeout))
            {
                // @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
                $dic = [
                            10056 => "Já existe uma conexão socket aberta para o host <b>{$host}</b>!",
                            10057 => "Não foi possível conectar ao socket na chamada do host <b>{$host}</b>!",
                            10060 => "Time Out na chamada do host <b>{$host}</b>!",
                            10061 => "O host <b>{$host}</b> recusou a conexão!",
                        ];

                $mensagem = (array_key_exists($errno, $dic)) ? strtr($errno, $dic) : $errstr;          

                throw new RuntimeException("Erro ({$errno}): {$mensagem}");
            }

            fclose($socket); // Fecha o socket aberto anteriormente

            $WbemLocator = new COM("WbemScripting.SWbemLocator");
            // @see https://msdn.microsoft.com/en-us/library/aa393720(v=vs.85).aspx
            self::$conexao = $WbemLocator->ConnectServer($host, 'root\cimv2', $usuario, $senha, 'MS_416');
            self::$conexao->Security_->ImpersonationLevel = 3;
        }
        catch (com_exception $e) {
            self::$mensagemErro = utf8_encode($e->getMessage());
        }
        catch (RuntimeException $e) {
            self::$mensagemErro = $e->getMessage();
        }
        catch (Exception $e) {
            self::$mensagemErro =  $e->getMessage();
        }
    }

    /**
     * Executa a instrução remotamente
     * 
     * @param   string $instrucao
     * @return  object
     */
    public static function executar($instrucao)
    {
        try
        {
            if (!self::$conexao)
            {
                throw new RuntimeException("Erro: É necessário abrir uma conexão antes de tentar executar qualquer comando!");
            }
             // @see http://php.net/manual/en/ref.com.php
            return self::$conexao->ExecQuery($instrucao);
        }
        catch (RuntimeException $e) {
            return $e->getMessage();
        }
    }
}

And in the specialized class, would it be important or recommended to give a return in status method and error message?

public static function status()
{
    return parent::status();
}

public static function mensagemErro()
{
    return parent::mensagemErro();
}
    
asked by anonymous 19.11.2016 / 21:13

1 answer

4

For some tests I've done it is relevant to use parent:: if in the abstract class and in the one that extends it there is a method with the same name and you want to call the method of the parent class (abstract), eg

<?php
abstract class hey {
    protected function hello() {
        echo 'hello from hey';
    }
}
class lol extends hey {
    protected function hello() {
        echo 'hello from lol';
    }
    public function do_hello() {
        self::hello();
        parent::hello();
    }
}
$lol = new lol();
$lol->do_hello();

DEMONSTRATION

But if there is not (you are sure that there is no method with the same name), you can restrict itself to self:: that it goes looking for the method in the class where it is called and if it does not find it goes looking in the parent (abstract) class, eg:

<?php
abstract class hey {
    protected function hello() {
        echo 'hello from hey';
    }
}
class lol extends hey {
    protected function adeus() {
        echo 'hello from lol';
    }
    public function do_hello() {
        self::hello();
        parent::hello();
    }
}
$lol = new lol();
$lol->do_hello();

DEMONSTRATION

As you can see, both executed the method of the abstract class hey , not lol , because lol has no hello() method.

BUT, in the case of PHP, for the sake of readability and if your intention is to call the method / variable of the parent class even if you have re-implemented it on the daughter I would do parent::$conexao

However, I find it unnecessary to create methods to access these variables of the parent class, with only parent::$status and parent::$mensagemErro where necessary.

    
19.11.2016 / 21:39