0
What would be the correct way to structure the code below? For example, is it appropriate to pass an instance of Connectorwmi as a parameter and use it to execute an instruction? Or would you have a more appropriate approach?
Connector:
abstract class Conector
{
/**
* Recurso de conexão externa
*
* @var object
*/
protected $conexao;
/**
* Mensagem de erro
*
* @var string
*/
protected $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 function conectar($host, $usuario = null, $senha = null, $porta = 135, $timeout = 10);
/**
* Consulta o status da conexão
*
* @return bool
*/
public function status()
{
return ($this->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 function mensagemErro()
{
return $this->mensagemErro;
}
/**
* Executa a instrução remotamente
*
* @param string $instrucao
* @return object
*/
abstract public function executar($instrucao);
}
Connectorwmi:
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 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
$this->conexao = $WbemLocator->ConnectServer($host, 'root\cimv2', $usuario, $senha, 'MS_416');
$this->conexao->Security_->ImpersonationLevel = 3;
}
catch (com_exception $e) {
$this->mensagemErro = utf8_encode($e->getMessage());
}
catch (RuntimeException $e) {
$this->mensagemErro = $e->getMessage();
}
catch (Exception $e) {
$this->mensagemErro = $e->getMessage();
}
}
/**
* Executa a instrução remotamente
*
* @param string $instrucao
* @return object|string em caso de erro retorna uma string
*/
public function executar($instrucao)
{
try
{
if (!$this->conexao)
{
throw new RuntimeException("Antes de executar uma instrução é necessário instanciar uma conexão!");
}
// @see http://php.net/manual/en/ref.com.php
if(!$retorno = $this->conexao->ExecQuery($instrucao))
{
throw new RuntimeException("O host remoto não retornou dados!");
}
return $retorno;
}
catch (RuntimeException $e) {
return $e->getMessage();
}
}
}
CPU:
class Cpu
{
/**
* Armazena uma instância de Win32_Processor
*
* @access private
* @var object
*/
private $cpu;
/**
* Captura as informações referentes a CPU
*
* @access public
*/
function __construct(ConectorWmi $wmi)
{
$this->cpu = $wmi->executar("SELECT
Caption,
DeviceID,
LoadPercentage,
CurrentClockSpeed,
Name,
NumberOfCores,
DataWidth,
NumberOfLogicalProcessors
FROM Win32_Processor");
}
/**
* Retorna informações referentes a CPU
*
* @access public
* @return array
*/
public function cpuDetalhes()
{
foreach ($this->cpu as $c)
{
$cpu[$c->DeviceID] = array('nome' => $c->Name,
'arquitetura' => $c->DataWidth,
'mhz' => $c->CurrentClockSpeed,
'nucleos' => $c->NumberOfCores,
'processadoresLogicos' => $c->NumberOfLogicalProcessors,
'cargaDoProcessador' => $c->LoadPercentage);
}
return $cpu;
}
}
Test consulting the CPU:
$wmi = new ConectorWmi;
$wmi->conectar('192.168.54.101', 'Administrador', '1QAZxsw2');
if($wmi->status())
{
$obj = new Cpu($wmi);
echo "<pre>";
print_r($obj->cpuDetalhes());
echo "</pre>";
}
else
{
echo $wmi->mensagemErro();
}
Why did you delete the old question and remake it again? ... Even though I switched from Static to "object," I still believe that the comment I wrote earlier applies to this situation as well, in addition to container coupling, the problem is simply getting out using it because they taught it that way, because I said it was good, the techniques are created to solve problems, so if the class can be simple make it simple, unless you have the vision of a large project where the class will be used, instantiated, inherited, which does not seem to me the case.
– Guilherme Nascimento
The previous question was confused, just as I changed the code and changed the context of the question. Now the question is, what is the best approach to the code published in this question.
– Fábio Jânio
The best approach is to stop reading blogs or tutorials that teach "good practice", simplify the code and use certain things if necessary :)
– Guilherme Nascimento