Solução do post 413553
Hoje eu vi esse post, mas ele já estava encerrado e acredito que outras pessoas possam estar com essa dúvida ainda.
Neste caso o que estava incorreto não era a versão do interpretador no VSCode, etc.
Problema
O problema se trata de um erro de sintaxe como o próprio erro descreve.
A criação de uma classe com propriedades para instanciar objetos necessita de um método __construct
para receber os parâmetros na sua inicialização.
Mesmo que a IDE não apontasse o erro (como a minha no caso), na hora de fazer qualquer chamada de função ou valor de atributo dessa classe o php iria apontar um erro.
código com erro de sintaxe:
<?php
class Conta
{
public string $cpftitular;
public string $nometitular;
public float $saldo;
public function sacar($valorSacar): void
{
if ($valorSacar > $this->saldo) {
echo "Saldo indisponível!";
} else {
$this->saldo -= $valorSacar;
}
}
}
$conta = new Conta(
'',
'',
100
);
$conta->sacar(90);
var_dump($conta);
erro de execução:
PHP Fatal error: Uncaught Error: Typed property Conta::$saldo must not be accessed before initialization in <DIR>\conta.php:11
Este erro fala justamente que não ouve acesso a propriedade "Conta::$saldo" depois da inicialização do objeto, mesmo o "atributo" estando público.
Solução
Para resolver esse problema você deve inicializar os atributos dentro do método contrutor:
Código corrigido:
class Conta
{
public string $cpf;
public string $nome;
public string $saldo;
/** Metodo construtor */
public function __construct
(
string $cpftitular,
string $nometitular,
float $saldo,
)
{
$this->cpf = $cpftitular;
$this->nome = $nometitular;
$this->saldo = $saldo;
}
public function sacar($valorSacar): void
{
if ($valorSacar > $this->saldo) {
echo "Saldo indisponível!";
} else {
$this->saldo -= $valorSacar;
}
}
}
$conta = new Conta(
'999.999.999-99',
'Osvaldo A. Neto',
100
);
$conta->sacar(90);
var_dump($conta);
retorno de execução:
$ > php .\conta.php
object(Conta)#1 (3) {
["cpf"]=>
string(14) "999.999.999-99"
["nome"]=>
string(15) "Osvaldo A. Neto"
["saldo"]=>
string(2) "10"
}
Conclusão
Nessa post apontei uma solução simples para o problema inicial, porém, existem outras recomendações que poderiam deixar esse código ainda melhor, como:
- Tornar os atributos "private" (ou readonly) para garantir a segurança dos valores, e também encapsular sua aplicação.
- Declarar diretamente os atributos dentro do
__construct
, para simplificar o código, por exemplo:
public function __construct
(
public readonly string $cpftitular,
public readonly string $nometitular,
private float $saldo,
) {}
Neste caso como o "parâmetro" esta sendo declarado no construtor ele é automaticamente convertido para "atributo".
- Outro ponto que melhoraria seria o "If" e "Else" para aplicarmos aquele princípio "Tell, don't ask & Fail Fast", ou seja, vamos evitar usar else, e colocar a falha como primeiro ponto na validação:
public function sacar(float $valorSacar): void
{
if ($valorSacar > $this->saldo) {
echo "Saldo indisponível!" . PHP_EOL;
return;
}
$this->saldo -= $valorSacar;
}
Bom, essas são as observações que gostaria de expor. Espero ter ajudado :)
Bom estudo a todos!