Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Sugestão] Solução: Erro de sintaxe PHP 8.3.X

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.

post-413553

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!

1 resposta
solução!

Olá Osvaldo, tudo bem?

Agradeço por dispor de seu tempo para compartilhar com riqueza de detalhes esse passo a passo com a Comunidade Alura. Com certeza poderá ajudar estudantes que passam por situações semelhantes.

Abraços e bons estudos!