Solucionado (ver solução)
Solucionado
(ver solução)
11
respostas

The use statement with non-compound name 'validacao' has no effect

ao tentar usar o autoload é apresentado o seguinte erro no browser:

Warning: The use statement with non-compound name 'contacorrente' has no effect in C:\curso php\objetos\index.php on line 4

Warning: The use statement with non-compound name 'validacao' has no effect in C:\curso php\objetos\index.php on line 5

o index.php

<?php
include "autoload.php";
use contacorrente;
use validacao;

contacorrente.php

<?php

use exception\saldoinsuficienteexception;

outoload.php

<?php

function load($namespace){
    $namespace = str_replace("\\", "/", $namespace);
    $caminhoabsoluto = __DIR__."/".$namespace.".php";

    include_once $caminhoabsoluto;
}

spl_autoload_register(__NAMESPACE__."\load");
?>

o pode estar errado?

11 respostas

Marcos, boa tarde!

A classe Validacao está com o nome do arquivo com a primeira letra maiúscula e a da classe também?

boa tarde. em qual parte está em maiúsculo?

Marcos, boa tarde!

Tanto na definição da classe

namespace Seu\Namespace\Aqui;
class Validacao 
{
 //SUA IMPLEMENTAÇÃO
{

E também o nome do arquivo deve estar em maiúsculo, Validacao.php e deve ser igual ao nome da classe acima

Espero ter ajudado e bons estudos!

na verdade consultei aqui e em nenhum arquivo está maiúsculo, coloquei em todos minúsculo

Marcos,

1) O código esta exatamente como você colocou acima, no sentido de que apenas colocou os uses, sem usar ainda as classes? Se este foi o caso o problema pode ser isto. Como fez a inclusão dos arquivos mas ainda não fez uso das classes elas estão sem efeito "no effect".

2) Caso não seja o acima, experimente fazer uma inclusão com include ou require para verificar se o erro permanece.

3) Em ultimo caso, poste todo o diretório do projeto no github e nos envie para avaliar!

índex.php

<?php
include "autoload.php";
//use contacorrente;
//use validacao;
//use exception\saldoinsuficienteexception;
$contajoao = new contacorrente("joao","0783", "21867-3","500");
$contamaria = new contacorrente("maria","4831", "71321-3", "1000");
$contajose = new contacorrente("Jose", "0780", "150234-8", "10000");
$contapedro = new contacorrente("pedro", "0780", "150235-9", "10000");
$contamarcia = new contacorrente("Marcia", "0780", "150238-7", "90000");
$contamarcos = new contacorrente("Marcos", "0780", "150000-7", "8000");
$contafrancisca = new contacorrente("Francisca", "0780", "15023-9", "100000");
echo $contamaria->saldo;
$contajoao->sacar("400") ->depositar("770");
$contamaria->depositar("1000") ->sacar(25);
echo "<pre>";
echo "total de contas: ". contacorrente::$totaldecontas . "<br> <br>";
echo "valor da taxa de operação: ". contacorrente::$taxaoperacao . "<br> <br>";
var_dump($contajoao);
var_dump($contamaria);
echo "</pre>";
echo "antiga agencia maria:  {$contamaria-> __get("agencia")} , saldo antigo da maria: {$contamaria->getsaldo()}" . PHP_EOL;
$contamaria->__set("agencia", "2734");
//$contamaria->saldo == "50000";
echo PHP_EOL . " nova agencia da Maria: {$contamaria-> __get ("agencia")} , novo saldo a maria: {$contamaria->getsaldo()}" . PHP_EOL;
echo "<h3>Saldo depois de transferir 750,00 da conta do João para a conta da Maria:</h3> <br/>";
try {
    $contajoao ['teste'];
}catch(Error $error) {
    echo "<br><b>" . $error->getMessage(). "</b>";
}
try {
    $contajoao->transferir("1750", $contamaria);
}catch(exception $error){
    echo $error->getMessage();
}
echo "<pre>";
var_dump($contajoao);
var_dump($contamaria);
echo "saldo maria" . $contamaria->saldo;
echo "</pre>";

validacao.php

<?php
class validacao{
    public static function protegeatributo ($atributo){
if ($atributo == "titular" || $atributo == "saldo"){
echo "<br/> erro ao alterar o valor do saldo <br/> <br/>" . PHP_EOL . PHP_EOL;
        }
        return $atributo;
    }
    public static function verificanumerico ($valor){
        if (!is_numeric($valor)) {
            throw new InvalidArgumentException("<h3>o valor passado:<b> $valor </b>não é um número, portanto a transação não foi concluída.</h3><br/>");
        }
        if ($valor<=0){
            throw new InvalidArgumentException("o valor: $valor, não pode ser transferido.");
        }
     return $valor;
    }
}
?>

contacorrente.php

<?php
//use exception\saldoinsuficienteexception;
class contacorrente
{
    private $titular;
    private $agencia;
    private $numero;
    private $saldo;
    public static $totaldecontas;
    public static $taxaoperacao;
    public function __construct($titular, $agencia, $numero, $saldo)
    {
        $this->titular = $titular;
        $this->agencia = $agencia;
        $this->numero = $numero;
        $this->saldo = $saldo;
        self::$totaldecontas ++;
        try{
            if(self::$totaldecontas <1){
                throw new Exception("valor menor ou igual a zero não pode ser dividido.");
            }
            self::$taxaoperacao = (30/self::$totaldecontas);
        }catch(Exception $erro){
        echo $erro->getMessage();
        exit;
        }
    }
    //função para sacar
    public function sacar($valor){
        validacao::verificanumerico($valor);
        $this->saldo = $this->saldo - $valor;
        return $this;
    }
    //funcao para depositar
    public function depositar($valor){
        validacao::verificanumerico($valor);
        $this->saldo = $this->saldo += $valor;
        return $this;
    }
    //função para transferir
    public function transferir ($valor,contacorrente $contacorrente){
        validacao::verificanumerico($valor);
        $this->sacar($valor);
        $contacorrente->depositar($valor);
        return $this;
    }
    public function __get($atributo)
    {
       validacao::protegeatributo($atributo);
        $this->$atributo;
    }
    public function __set($atributo, $valor){
       validacao::protegeatributo($atributo);
        $this->$atributo = $valor;
    }
    //funçao para formatar o saldo
        private function formatasaldo (){
     return number_format ($this->saldo, 2, ",", ".");

saldoinsuficienteexception.php

<?php



class saldoinsuficienteexception extends exception{

    public function __construct($mensagem, $codigo = null, $ex = null){
parent::__construct($mensagem, $codigo, $ex);

    }
}

?>

autoload.php

<?php

function load($namespace){
    $namespace = str_replace("\\", "/", $namespace);
    $caminhoabsoluto = __DIR__."/".$namespace.".php";

    include_once $caminhoabsoluto;
}

spl_autoload_register(__NAMESPACE__."\load");
?>
solução!

Marcos, Tudo bem contigo?

Copiei o código e executei, não recebi os Warnings!

Apenas como observação. Para ver a execução eu simplifiquei aqui o index.html, e alterei a seguinte linha:

Alterei:

echo "antiga agencia maria:  {$contamaria-> __get("agencia")} , saldo antigo da maria: {$contamaria->getsaldo()}" . PHP_EOL;

Para:

 echo "antiga agencia maria: {$contamaria->agencia}";

E no arquivo contacorrente.php, alterei a função __get($atributo) Inclui um return:

    public function __get($atributo)
    {
       validacao::protegeatributo($atributo);
        return $this->$atributo;
    }

Feitas estas alterações teu código executou ok, sem nenhum Warning ref. ao Autoload.php. Me parece tudo ok. Testei tanto no browser quanto no prompt.

tudo bem sim, espero que você também.

Esse return que você adicionou me ajudou a concertar um problema que era o fato de não conseguir exibir o atributo agencia.

De fato os erros não são exibidos pois comentei as primeiras linhas do código:

<?php
include "autoload.php";
//use contacorrente;
//use validacao;
//use exception\saldoinsuficienteexception;

no curso vi o instrutor incluindo essas linhas e fiquei na dúvida se deveria ou não incluí-las. No exemplo dele deu certo mas no meu apresentou esses erros. Então devo seguir sem usar os "use"?

Obrigado pela ajuda.

Marcos,

Tudo bem contigo?

Vamos lá, primeiro de tudo, eu estou aprendendo também, então estou respondendo em cima da pesquisa e testes que consegui realizar. Tive de gastar um tempo.

Se você conseguiu uma outra resposta sobre este tópico, por favor não deixe de compartilhar!

Sobre o vídeo do instrutor, de fato, eu não havia habilitado o AutoLoader quando fiz os exercicios, concluí usando apenas o "require_once". Depois reproduzindo o código conforme o instrutor fez eu também recebi os mesmos warnings.

Agora, depois que ele carrega o use, eu não consegui explicação de por que no caso dele este warning não aparece. Pode ter a ver com o ambiente dele ou versão do PHP. Não estou certo.

Lembrando que um Warning é um aviso não é necessáriamente um erro. Um Warning ou Alerta do compilador indica situações que podem causar problemas ou podem ter efeitos indesejáveis dos quais o programador não esta ciente.

Respondendo objetivamente: Neste caso especifico não é necessário o "use".

Porque o arquivo esta na raiz do projeto, e o Autoloader considera a raiz o namespace padrão e vai carregar isto automáticamente.

Para você ver isto funcionando, coloque estes echo´s no código no teu Autoloader:

    function load ($namespace){
        $namespace = str_replace("\\", "/", $namespace);

        $caminhoAbsoluto = __DIR__ . "/". $namespace . ".php";

        echo PHP_EOL;
        echo "Caminho Absoluto: " . $caminhoAbsoluto . PHP_EOL;
        echo PHP_EOL;

        return include_once $caminhoAbsoluto;
    }

Em que momento que o Autoloader é chamado? Não é no "use", mas quando você fizer a primeira chamada do método construtor da classe ContaCorrente:

$contajoao = new ContaCorrente("joao","0783", "21867-3","500");

Isto fica bem claro na documentação do PHP, o "use" não faz o import (include) do arquivo, ele apenas mapeia o caminho onde o AutoLoader deve procurar pela classe.

Por padrão o Autoloader vai procurar no namespace atual, que é a pasta raiz. Vai procurar pelo arquivo da classe ContaCorrente.php, independente de você mapear o namespace com o "use".

Isto fica claro no código acima no Caminho Absoluto, com a linha do "use" comentada ou removida.

E dai que esta o Warning: "PHP Warning: The use statement with non-compound name 'ContaCorrente' has no effect"

Este "use ContaCorrente" não tem efeito (has no effect), nenhum no teu código. Até por que esta classe ContaCorrente não esta dentro de um namespace, e informando o nome desta maneira, ele não tem um caminho composto, ele já esta direto na raiz, e não é necessário.

O "use" vai servir apenas como um mapeamento de onde o compilador deve procurar por classes usadas no teu código.

Uma sugestão é você criar uma pasta /classes e dentro dela salvar o ContaCorrente.php. Dai no inicio do ContaCorrente.php, informa:

namespace classes;

E de volta no index.php informa:

use classes\ContaCorrente;

Neste caso, quando você chamar a função construtora da classe ContaCorrente o Autoloader vai procurar a classe no namespace atual que é a raiz. Não vai achar, dai vai procurar na pasta classes que voc~e mapeou com o "use" vai achar e executar.

E consequentemente neste caso executa sem warning, por que o "use" foi necessário para que o AutoLoader carregasse o arquivo ContaCorrente.php no namespace classes.

Sugiro conforme tiver tempo, examinar as seguintes fontes que me ajudaram (espero eu) ter entendido um pouco melhor:

1) Treinamento Alura: PHP: INTRODUÇÃO À ORIENTAÇÃO A OBJETOS - PARTE 2 Aula 1 - NAMESPACES

2) Artigo: Entendendo namespaces no PHP http://www.diogomatheus.com.br/blog/php/entendendo-namespaces-no-php/

3) Documentação do PHP PS: Este sinceramente eu não li tudo...kkkk https://www.php.net/manual/pt_BR/language.namespaces.php

Um abraço e vamos seguindo nos estudos!

Mais uma vez obrigado pela disposição.

Imaginei que o erro pudesse ser como você falou, não era necessário o "use". E ainda bem que você também viu o mesmo problema que eu, talvez seja devido a versão do PHP que o instrutor está usando mesmo mas faz a gente perder muito tempo.

valeu, bons estudos.