Ir para conteúdo
Fórum Script Brasil
  • 0

Consegui mudar o nome da tabela Users


Frank K Hosaka

Pergunta

Eu tenho 12 tabelas no MySQL, onze delas têm o prefixo tb (tbconta, tbdiario, tbproduto) , isso é coisa que herdei do tempo que usei o Microsoft Access.

Mas em 2022 comecei a estudar o Laravel, e ele acrescentou uma nova tabela chamada Users.

Agora, eu pedi para o MysQL mudar o nome da tabela Users para tbusuario, isso é bem fácil.

O problema é quando o Laravel reclama que não está conseguindo achar a tabela users.

Para resolver o problema, eu fui no Model User, e acrescentei a linha protected $table="tbusuario"; e tudo voltou a funcionar como se nada tivesse acontecido.

O Model do Laravel é sofisticado, ele permite associar um nome diferente da tabela para o projeto todo. Eu tenho 12 Model no Laravel, um para cada tabela.

Já no meu projeto em MVC, eu não tenho nenhum Model associado à tabela do MySQL. Só tenho o arquivo Conexao.php, onde defini funções genéricas assim

public function select($sql) {return json_decode(json_encode($this->instancia()->query("select $sql"))); }. Não senti necessidade de usar um Model para cada tabela.

Link para o comentário
Compartilhar em outros sites

4 respostass a esta questão

Posts Recomendados

  • 1

A abordagem que você descreveu para lidar com o nome da tabela no Laravel, usando a propriedade $table no Model, é de fato a solução adequada para quando você precisa especificar um nome de tabela diferente do padrão que o Laravel assume (que seria o nome do modelo no plural e em minúsculas para o nome da tabela).

No entanto, para seu projeto em MVC que não utiliza o Laravel e onde você não tem modelos específicos para cada tabela, sua abordagem é mais direta e menos abstrata, confiando no arquivo Conexao.php para lidar com consultas genéricas. Esta é uma diferença fundamental entre usar um framework ORM completo como o Eloquent do Laravel, que encoraja e facilita o uso de modelos para cada tabela (ajudando com a organização, a manutenção e a legibilidade do código, além de fornecer proteção contra injeção de SQL e outros benefícios), e usar uma abordagem mais manual e genérica.

Agora, se você quiser alinhar um pouco mais o seu projeto MVC sem utilizar o Laravel (ou Eloquent) com a abordagem de ter um modelo para cada tabela (como você já faz no Laravel), você poderia definir classes PHP que representem cada uma das suas tabelas. Estas classes poderiam encapsular as funcionalidades específicas relacionadas a cada tabela, como operações CRUD (Create, Read, Update, Delete). Aqui está um exemplo básico do que poderia ser um modelo para uma tabela genérica:

class ModeloGenerico {
    protected $table;

    public function __construct($table) {
        $this->table = $table;
    }

    public function select($where = "") {
        $sql = "SELECT * FROM $this->table";
        if (!empty($where)) {
            $sql .= " WHERE $where";
        }
        // Supondo que Conexao tem um método estático para pegar a instância de conexão
        return json_decode(json_encode(Conexao::getInstance()->query($sql)));
    }

    // Métodos adicionais para update, delete, etc., podem ser adicionados aqui
}

E então você poderia usar:

$usuarioModel = new ModeloGenerico('tbusuario');
$usuarios = $usuarioModel->select("nome = 'John Doe'");

Isso ainda não é tão sofisticado quanto usar o Eloquent no Laravel, mas organiza seu código em um estilo mais orientado a objetos e modular.

Para cada tabela, você poderia estender ModeloGenerico e configurar o $table no construtor, ou simplesmente instanciar ModeloGenerico com diferentes nomes de tabela. Essa abordagem não é tão avançada quanto o Eloquent, mas pode ajudar a organizar o código e prepará-lo para um potencial refatoramento futuro ou transição para um ORM completo.

 
Link para o comentário
Compartilhar em outros sites

  • 1
1 hora atrás, Frank K Hosaka disse:

O Eloquent é fantástico, mas ele não tem nada a ver com o Model. O Eloquent é uma gramática, e o Model é apenas uma alavanca para dar mais poder de fogo para o Eloquent.

 

Totalmente Errado! 

https://laravel.com/docs/10.x/eloquent

"Laravel includes Eloquent, an object-relational mapper (ORM) that makes it enjoyable to interact with your database. When using Eloquent, each database table has a corresponding "Model" that is used to interact with that table. In addition to retrieving records from the database table, Eloquent models allow you to insert, update, and delete records from the table as well."

Eloquent não é uma gramática. É um ORM (Object-Relational Mapper), uma ferramenta usada em programação para facilitar a interação com bancos de dados. Enquanto "gramática" pode se referir às regras estruturais de uma língua ou a uma especificação detalhada de uma linguagem de programação, sendo asim o Eloquent ainda é uma biblioteca ou um componente do framework Laravel, que vai te fornecer uma abstração para trabalhar com bancos de dados, permitindo que você use objetos PHP em vez de código SQL bruto, não confunda com Facade DB do Laravel.

Editado por William Duarte
Link para o comentário
Compartilhar em outros sites

  • 1
1 hora atrás, Frank K Hosaka disse:

Esse não é o meu caso com o MVC. Para quem está começando a estudar o MVC, que é o meu caso, acho melhor só colocar uma conexão e as funções que serão utilizadas na pasta Modelos do MVC.

A grande dor de cabeça do MVC são as pastas. Eu só consegui fazer o MVC funcionar depois que eu aprendi a usar o autloader e o roteador. Eles estão aqui:

Entendo que você está tendo dificuldades em organizar e entender o funcionamento do MVC em seu projeto e como interligar diferentes partes como o roteador, controle e modelo. Aqui vão algumas sugestões para ajudar na estruturação e no entendimento:

Separação Clara de Responsabilidades: Mantenha a separação clara entre o modelo, a visão e o controle. O Modelo deve lidar apenas com a lógica de negócios e acesso a dados. A Visão deve ser responsável apenas pela apresentação, e o Controle deve fazer a intermediação entre o Modelo e a Visão.

Evitar Acoplamento e Dependências Diretas: Tente evitar que uma parte do seu código dependa diretamente dos detalhes de implementação de outra parte. Isso torna o seu código mais modular e fácil de manter ou substituir. Por exemplo, em vez de ter o controle sabendo detalhes de implementação do modelo, ele deve apenas interagir com sua interface.

Melhoria na Organização do Roteador: Em relação ao seu roteador, a abordagem de utilizar uma "gambiarra" pode funcionar temporariamente, mas não é sustentável a longo prazo. Considere refatorar seu roteador para que ele mapeie URIs para controladores de maneira mais clara e flexível.

Uso de Sessão e Constantes: Parece que você está usando a sessão e constantes para armazenar informações e estados entre as requisições. Isso é prático, mas certifique-se de que esses usos estão claros e justificados, evitando armazenar dados em excesso ou sem necessidade, o que pode complicar o entendimento e a manutenção do código.

Refatoração e Limpeza: Seu código parece complexo e difícil de manter ("uma baderna", como você mencionou). Dedique algum tempo para refatorá-lo, simplificando e dividindo partes complexas em funções ou métodos menores e mais compreensíveis.

Documentação: Documente seu código, especialmente partes complicadas ou não intuitivas. Isso ajudará não só você a entender o que você fez quando voltar a esse código no futuro, mas também qualquer outra pessoa que trabalhe com ele.

Orientação a Objetos: Se você está lutando para entender o conceito de 'objeto', pode valer a pena investir algum tempo em aprendizado adicional sobre programação orientada a objetos. Isso poderá ajudá-lo a estruturar melhor seu código e aproveitar os recursos que essa abordagem oferece.

Debugging: Para entender melhor onde e por que os erros acontecem, utilize ferramentas de debugging e logs para rastrear o fluxo do programa e entender onde as falhas ocorrem.

Aplicar essas sugestões pode ajudar a tornar o seu código mais organizado, compreensível e manutenível.
 

Para refatorar o código siga os princípios SOLID, vamos primeiro entender cada princípio aplicado ao contexto de MVC (Model-View-Controller):

Single Responsibility Principle (SRP): Cada classe deve ter apenas uma razão para mudar. Isso significa que cada classe deve ter apenas um trabalho.

Open/Closed Principle (OCP): Entidades de software (classes, módulos, funções, etc.) devem estar abertas para extensão, mas fechadas para modificação.

Liskov Substitution Principle (LSP): Objetos de uma superclasse devem ser substituíveis por objetos de suas subclasses sem quebrar a aplicação.

Interface Segregation Principle (ISP): Nenhuma classe deve ser forçada a implementar interfaces que não vai usar.

Dependency Inversion Principle (DIP): Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações.


Agora, vamos aplicar esses princípios ao código fornecido:
 

Refatorando Index.php:

SRP: O Index.php deve apenas lidar com a inicialização da aplicação e roteamento. O tratamento específico de cada rota deve ser delegado a controllers específicos.

OCP: O roteador pode ser modificado para ser extensível, permitindo adicionar novas rotas sem alterar o código existente.

DIP: Utilize interfaces ou abstrações para definir o contrato dos controllers, assim você não depende diretamente da implementação.

<?php
ini_set('display_errors', 1);
require __DIR__ . '/Modelos/Config.php';

// Define a rota padrão
$rotaPadrao = 'ControleLogin_login';

// Obtém a rota do URL ou utiliza a rota padrão
$rota = isset($_GET['rota']) ? $_GET['rota'] : $rotaPadrao;
$segmentos = explode('_', $rota);

// Define o controle e a função a partir dos segmentos da rota
$nomeControle = $segmentos[0] ?? 'ControleLogin';
$metodo = $segmentos[1] ?? 'login';
$parametro = $segmentos[2] ?? null;

// Instancia o controle e chama o método
$controle = new $nomeControle();
$controle->$metodo($parametro);


Refatorando Config.php:

SRP: O Config.php deve apenas definir configurações, não deveria lidar com lógica de definição de caminhos ou autoload.

DIP: O autoloading deve depender de uma abstração e não de detalhes concretos. Você pode utilizar o PSR-4 autoloading padrão com Composer, o que tornaria desnecessário definir um autoloader personalizado.
 

<?php
date_default_timezone_set('America/Sao_Paulo');

// Define as constantes de caminho baseadas no ambiente
$baseDir = $_SERVER['SERVER_NAME'] === 'astudy.net' ? $_SERVER['DOCUMENT_ROOT'] : $_SERVER['DOCUMENT_ROOT'].'/Frank/';

define('PROJETO', $baseDir);
define('CONTROLES', PROJETO.'/Controles/');
define('MODELOS', PROJETO.'/Modelos/');
define('VISOES', PROJETO.'/Visoes/');
define('HOST', 'localhost');
define('DBNAME', 'diario');
define('USER', 'root');
define('PASSWORD', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? '12345678' : '');

// Restante das configurações...

 

Mais uma dica final"

Melhoria do Autoload: Se mantiver o autoload customizado, torne-o mais claro com comentários e separando claramente cada etapa.

 

spl_autoload_register(function ($classe) {
    $diretorios = ['Controles', 'Modelos', 'Visoes'];
    
    foreach ($diretorios as $diretorio) {
        $arquivo = PROJETO . DIRECTORY_SEPARATOR . $diretorio . DIRECTORY_SEPARATOR . $classe . '.php';
        if (file_exists($arquivo)) {
            require_once $arquivo;
            return;
        }
    }
    
    // Lança um erro se o arquivo da classe não for encontrado
    throw new Exception("Erro ao carregar a classe '{$classe}'. Arquivo não encontrado.");
});
Editado por William Duarte
Link para o comentário
Compartilhar em outros sites

  • 0
Postado (editado)

Obrigado, William.

O Eloquent é fantástico, mas ele não tem nada a ver com o Model. O Eloquent é uma gramática, e o Model é apenas uma alavanca para dar mais poder de fogo para o Eloquent.

Esse não é o meu caso com o MVC. Para quem está começando a estudar o MVC, que é o meu caso, acho melhor só colocar uma conexão e as funções que serão utilizadas na pasta Modelos do MVC.

A grande dor de cabeça do MVC são as pastas. Eu só consegui fazer o MVC funcionar depois que eu aprendi a usar o autloader e o roteador. Eles estão aqui:

Arquivo Index.php
<?php
ini_set('display_errors', 1);
require __DIR__ . '/Modelos/Config.php';
if($_GET)
{
    $comando=explode('_',key($_GET));
    $controle=new $comando[0];
    $funcao=$comando[1];
    if(count($comando)==3)
    {
        $_GET[$funcao]=$comando[2];
    }
    call_user_func(array($controle,$funcao));
} 
else 
{
    $login=new ControleLogin();
    $login->login();
}

Arquivo Modelos / Config.php
<?php
date_default_timezone_set('America/Sao_Paulo');
if($_SERVER['SERVER_NAME']=='astudy.net')
{
  	defined('PROJETO') || define('PROJETO',$_SERVER['DOCUMENT_ROOT']);
    $dbname="Diario";
    $user="Root";
    $password="12345678";
}
else
{   
  	defined('PROJETO') || define('PROJETO',$_SERVER['DOCUMENT_ROOT'].'/Frank/');
    $dbname="diario";
    $user="root";
    $password="";
}
defined('CONTROLES') || define('CONTROLES',PROJETO.'/Controles/');
defined('MODELOS') || define('MODELO',PROJETO.'/Modelos/');
defined('VISOES') || define('VISOES',PROJETO.'/Visoes/');
defined('HOST') || define('HOST','localhost');
defined('DBNAME') || define('DBNAME',$dbname);
defined('USER') || define('USER',$user);
defined('PASSWORD') || define('PASSWORD',$password);
defined('lctoBaixaEstoque') || define('lctoBaixaEstoque',11301);
defined('lctoAcertoMais') || define('lctoAcertoMais',11658);
defined('lctoAcertoMenos') || define('lctoAcertoMenos',11659);
defined('diaAcerto') || define('diaAcerto','2024-03-31');

spl_autoload_register(function($Class)
{
    $includeDir = false;
    $findDir = ['Controles','Modelos','Visoes'];
    foreach ($findDir as $DirName) 
    {
        if (!$includeDir
            && file_exists(FindClass($DirName, $Class))
            && !is_dir(FindClass($DirName, $Class))) 
        {
            include_once (FindClass($DirName, $Class));
            $includeDir = true;
        }
    }
    if (!$includeDir) 
    {
        die(FindClass($DirName,$Class)."- Erro interno no servidor ao encontrar dados 
            cruciais de funcionamento!");
        
    }
});

function FindClass($dir, $class) 
{
  	if($_SERVER['SERVER_NAME']=="astudy.net")
    {
    	return (
        	$_SERVER['DOCUMENT_ROOT']
        	. DIRECTORY_SEPARATOR . $dir
        	. DIRECTORY_SEPARATOR . $class . '.php');
	}
	else
    {
      return (
        	$_SERVER['DOCUMENT_ROOT']
     		. DIRECTORY_SEPARATOR . 'frank'
        	. DIRECTORY_SEPARATOR . $dir
        	. DIRECTORY_SEPARATOR . $class . '.php');
    }
}

Eu alterei o código do roteador . O autor original usava a sintaxe <a href=?cotroller=ControleDiario.method=diario>, eu fiz uma bela gambiarra e consegui fazer a mesma coisa com a sintaxe <a href=?ControleDiario.diario>.

O meu código é bem obscuro, mas muito mais obscuro é o arquivo web.php do Routes do Laravel.

Depois que consegui resolver o problema da navegação dentro do MVC, outro grande problema é como usar o método de uma classe a partir de vários métodos diferentes em classes diferentes.

A minha ideia é transformar o método bastante solicitado numa função. O problema é que o método está amarrado num arquivo HTML, ou seja, eu não consegui montar uma função PHP com um HTML embutido.

Lá em 2020, eu usei uma tabela auxiliar no MySQL no código PHP. No MVC de 2024, usei a variável global SESSION bem como as definições de constantes, e o algoritmo ficou assim:

Balancete chama Apuração, assim <a href="?ControleDiario.apuracao.balancete">
A apuração guarda o endereço de quem chamou $_SESSION['endereco']=$_GET['apuracao'] e depois chama  facaAEscolha.html, o usuário faz a escolha, o HTML devolve a apuração escolhida para a apuracao, assim:
<a href="?ControleDiario.apuracao.<?=$período ?>"><?=$periodo?></a>, e finalmente a função apuração salva o valor escolhido na SESSION['apuracao'], e finalmente termina  a rotina com um header("location:?".$_SESSION['endereco'].

É uma baderna!

Não há como tornar o código legível, mas isso é o máximo que eu consegui com o meu método científico da tentativa e erro. Enfim, o MVC é bacana, mas ainda não peguei o jeito do conceito de 'objeto'. Por enquanto, ele é apenas uma variável que morre assim que o usuário aperta a tecla enviar. Para não perder tudo no caminho, eu salvei alguns valores no SESSION, e espero utilizar o recurso do SESSION no arquivo Conexão para me informar exatamente aonde começou o problema, quando ele reclama que o MySQL não conseguiu entender o que foi solicitado.

Editado por Frank K Hosaka
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...