Stack Overflow em Português Asked on December 23, 2020
Utilizo um método para instanciar classes e métodos dinamicamente.
Propriedades recebidas:
modulo
= nome da pasta com os arquivos .class.php
ferramenta
= nome do arquivo .class.php
acao
= nome do métodoMétodo que executa a solicitação:
private function executar()
{
try {
# Monta o patch e faz require da classe
$classe = DIR_MODULOS . $this -> modulo . DS . $this -> ferramenta . '.class.php';
require_once $classe;
# Instancia o objeto e executa o método
$obj = new $this -> ferramenta();
$resposta = $obj -> {$this -> acao}($this -> dados);
# Retorna a resposta
$this -> retorno = $resposta;
} catch (Exception $e) {
$this -> error = $e->getMessage();
}
}
modulo
vier incorreta, não irá achar o caminho da pasta.
ferramenta
vier incorreta, não irá achar o arquivo da classe.
acao
vier incorreta, não irá achar o método na classe.
Qual a melhor forma de tratar os erros já que o try-catch
não os trata?
(de preferência, funções nativas)
A ideia é retornar apenas uma string simples conforme o erro.
Exemplo:
Consegui resolver utilizando o file_exists
, class_exists
e method_exists
.
PS: Como citado pelo Maniero, por ser dinâmico poderá trazer falhas de segurança. No meu caso tratadas antes de chegar a esse método, mas segurança nunca é muito.
Como ficou:
private function executar()
{
# Verifica ...
if (...) {
# Verifica propriedades mínimas
if (...) {
# Monta o path do diretório
$dir = DIR_MODULOS . $this -> modulo;
# Verifica se existe o diretório
if (file_exists($dir)) {
# Monta o path do arquivo
$classe = DIR_MODULOS . $this -> modulo . DS . $this -> ferramenta . '.class.php';
# Verifica se existe o arquivo
if (file_exists($classe)) {
# Inclui a classe
require_once $classe;
# Verifica se existe a classe no arquivo
if (class_exists($this -> ferramenta)) {
# Cria objeto
$obj = new $this -> ferramenta();
# Verifica se o método existe
if (method_exists($obj, $this -> acao)) {
# Executa o método
$retorno = $obj -> {$this -> acao}($this -> dados);
# Retorna a resposta
$this -> retorno = $retorno;
} else {
$this -> error = "Ação inexistente.";
}
} else {
$this -> error = "Ferramenta inválida 2.";
}
} else {
$this -> error = "Ferramenta inválida 1.";
}
} else {
$this -> error = "Módulo inválido.";
}
} else {
$this -> error = "Erro na estrutura JSON.";
}
} else {
$this -> error = "Erro ...!";
}
}
Links úteis:
Correct answer by rbz on December 23, 2020
O uso de try-catch
aí já é errado. Eu respondo isso em várias perguntas aqui no SOpt (recomendo seguir os links fortemente). Não capture Exception
a não ser na saída final do código e não capture uma exceção para fazer nada útil.
O que está reportando é um erro de programação, e erros de programação a gente corrige e não tenta se recuperar. Exceção é para se recuperar de uma falha não esperada, mas não um erro de programação.
Em códigos de natureza dinâmica, e em linguagem de tipagem dinâmica tudo é mais ou menos de natureza dinâmica, você deve verificar o que vai usar antes de usar. A verificação só não precisa ser feita onde é garantido que dará certo.
O erro de programação aí é não considerar que o dado pode vir errado. Então antes de usar algo com potencial de estar errado verifique se está certo e decida o que fazer se estiver errado. Só execute se tudo está correto. Quase sempre o if
é seu amigo.
Quem sabe um dia eu escreva um livro sobre o assunto :). Sim, para dominar exceção e tratamento de erro precisa de um livro. Por isso mesmo a maioria das pessoas não vão aprender, quase todo mundo hoje em dia não quer ler, não quer gastar tempo aprendendo, faz o que é simples, mesmo que seja errado e se funcionar, tá bom. É bem complicado tratar erros corretamente, e mais ainda usar exceção. Uma coisa que sempre falo é que se não domina um recurso, não o use, e este é o caso da exceção, por isso tenho uma palestra chama "Exceção - o goto do século XXI" já que é o mecanismo que mais causa problemas para as pessoas, causa muito mais que o goto
que todo mundo sabe que não é para usar.
Answered by Maniero on December 23, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP