0

PHP + MVC - Como resolver falha de extends

criado por Leonardo Felipe em 15/08/2012 10:26am
Bom Dia pessoal, estou reestruturando um projeto antigo para o Modelo MVC.... Comecei tudo bem, digitava o login e senha e autenticava certo e entrava no Home, então tive a necessidade de fazer umas alterações devido aos extends que necessitei então, não sei porque, começou a apresentar:
Warning: mysqli_prepare() expects parameter 1 to be mysqli, null given in...

Não entendi porque, pois estava funcionando!

PS.: O que está apresentado não é todo o código de cada arquivo... Só postei o que achei necessário para entenderem o problema.

// MainVar.class.php - Variáveis do Sistema( classe que criei para que qualquer arquivo possa usar suas variáveis )
class MainVar {
   
var $DBName        = 'dbName';
   
var $DBServer        = 'localhost';
   
var $DBUser          = 'root';
   
var $DBPassword   = '';

   
{ ..... }
}

// Conexao.class.php - Classe de Conexao
class Conexao extends MainVar {
   
   
public function __construct(){
       
   
}
   
   
public function Connect(){
       
        $mysqli
= mysqli_connect($this->DBServer, $this->DBUser, $this->DBPassword, $this->DBName);
                       
       
if(mysqli_connect_errno()){
            trigger_error
('Erro ao tentar conectar ao banco de dados! '.$mysqli->error,E_USER_ERROR);
       
}
       
        $mysqli
->autocommit(false);
       
        mysqli_query
($mysqli, "SET NAMES 'utf8'");
        mysqli_query
($mysqli, 'SET character_set_connection=utf8');
        mysqli_query
($mysqli, 'SET character_set_client=utf8');
        mysqli_query
($mysqli, 'SET character_set_results=utf8');
       
       
return $mysqli;
   
}
}

// logar.php
require_once
('Config/MainVar.class.php');
require_once
('Config/Conexao.class.php');
require_once
('Libs/Funcoes.class.php');
require_once
('Controller/LoginController.php');

if($_GET['acessar'] == 'acessar'){
       
    $LoginController
= new LoginController();
    $login
= $_POST['login'];
    $senha
= $_POST['senha'];
   
   
// Tenta logar o usuário com os dados
   
if($LoginController->ValidaUsuario($login, $senha)){
       
       
// Usuário logado com sucesso, redireciona ele para a página restrita
        header
("Location: index.php");
       
exit;
     
}
}

// LoginController.php
require_once
('Model/LoginModel.php');

class LoginController extends LoginModel{
   
   
private $LoginModel;
   
private $Funcoes;
   
   
public function __construct(){
        $this
->Funcoes = new Funcoes();
   
}
   
   
public function ValidaUsuario($login, $senha){
       
       
if($senhaCodificada = $this->Funcoes->CodificaSenha($login, $senha)){
           
           
// Chamo o ValidaUsuario de LoginModel
            $total
= parent::ValidaUsuario($login, $senhaCodificada);
           
return ($total == 1) ? true : false;
           
       
}
   
}
   
{...}
}

// LoginModel.php
class LoginModel extends Conexao{
   
   
private $mysqli;
   
   
public function __construct(){
        $this
->mysqli = parent::Connect();
   
}
   
   
public function ValidaUsuario($login, $senha){
       
        $sql
= "SELECT COUNT(*) AS total
                FROM tabela_usuarios
                WHERE login = ? AND senha = ?"
;
       
       
if($query = mysqli_prepare($this->mysqli, $sql)){

           
//* O PROBLEMA É QUE AQUI NÃO ENTRA MAIS!!!!! *//
       
           
/* ADICIONA OS PARÂMETROS */
            mysqli_stmt_bind_param
($query, "ss",
                                   $login
,
                                   $senha
);
           
           
/* ADICIONA OS PARAMETROS */
           
if(mysqli_stmt_execute($query)){
               
                mysqli_stmt_bind_result
($query,$total);
               
               
if(mysqli_stmt_fetch($query)){
                   
return $total;
               
}
           
}
       
}
   
}
   
{...}
}

Então, aí está a dificuldade:
if($query = mysqli_prepare($this->mysqli, $sql)){
$this->mysqli deve(acho) está vazia como informa o Warning.


Achando isso, em LoginModel fiz:

class LoginModel extends Conexao{
   
   
private $mysqli;
   
   
public function __construct(){
        $this
->mysqli = parent::Connect();
        var_dump
($this->mysqli); // ADICIONEI ESTE VAR_DUMP();
   
}
   
{ ... }
}

Mas não retornou nada na tela. Tô achando que a classe de Conexão não esteja realizando corretamente o extends da classe MainVar OU nã está conseguindo trazer os valores de DBServer, DBUser, DBUser e DBName para a function Connect() da classe Conexao:

$mysqli = mysqli_connect($this->DBServer, $this->DBUser, $this->DBPassword, $this->DBName);

ACHO que está vindo assim, tudo vazio:

$mysqli = mysqli_connect(, , ,);

Mas não to sabendo como confirmar isto...

Será este o problema msm? Como posso testar e consequentemente resolver... Como faço??? Estou perdido, OMG!!!

Agradeço antecipadamente pelas dicas!!!

Lista de Respostas:

0
15/08/2012 2:38pm
(~12 anos atrás)
Leonardo Felipe respondeu:
Boa tarde pessoal,

=================
Wilson Tamarozzi Jr.

Obrigado pela resposta Wilson... Mas não uso PDO, uso uma extensão do PHP * MySQLi - feita para aproveitar os recursos mais avançados do MySQL *.
Mas não foi este o problema não.... Explicação abaixo!

=================

Bem, consegui filtrar o problema. Em LoginModel.php na function __construct() conectava ao banco usando parent::Connect(), desta forma:

LoginModel.php
class LoginModel extends Conexao{
 
   
private $mysqli;
 
   
public function __construct(){
        $this
->mysqli = parent::Connect();
   
}
 
   
public function ValidaUsuario($login, $senha){
     
        $sql
= "SELECT COUNT(*) AS total
                FROM tabela_usuarios
                WHERE login = ? AND senha = ?"
;
     
       
if($query = mysqli_prepare($this->mysqli, $sql)){

            O PROBLEMA
É QUE AQUI NÃO ENTRA MAIS!!!!!
     
           
/* ADICIONA OS PARÂMETROS */
            mysqli_stmt_bind_param
($query, "ss",
                                   $login
,
                                   $senha
);
         
           
/* ADICIONA OS PARAMETROS */
           
if(mysqli_stmt_execute($query)){
             
                mysqli_stmt_bind_result
($query,$total);
             
               
if(mysqli_stmt_fetch($query)){
                   
return $total;
               
}
           
}
       
}
   
}
   
   
{...}
}

Mas o problema é que não está entrando no método __construct(). Para testar fiz o seguinte:

LoginModel.php
class LoginModel extends Conexao{
 
   
private $mysqli;
 
   
public function __construct(){
       
//$this->mysqli = parent::Connect(); VOU UTILIZAR ESTE MÉTODO NA FUNCTION VALIDAUSUARIO()
   
}
 
   
public function ValidaUsuario($login, $senha){
     
        $sql
= "SELECT COUNT(*) AS total
                FROM tabela_usuarios
                WHERE login = ? AND senha = ?"
;

       $this
->mysqli = parent::Connect(); // COLOQUEI AQUI A CHAMADA DO MÉTODO DE CONEXÃO
     
       
if($query = mysqli_prepare($this->mysqli, $sql)){

            O PROBLEMA
É QUE AQUI NÃO ENTRA MAIS!!!!!
     
           
/* ADICIONA OS PARÂMETROS */
            mysqli_stmt_bind_param
($query, "ss",
                                   $login
,
                                   $senha
);
         
           
/* ADICIONA OS PARAMETROS */
           
if(mysqli_stmt_execute($query)){
             
                mysqli_stmt_bind_result
($query,$total);
             
               
if(mysqli_stmt_fetch($query)){
                   
return $total;
               
}
           
}
       
}
   
}
   
   
{...}
}

A testar funcionou perfeitamente, autenticou e acessou minha home.php.

O estranho é que em LoginController.php eu uso o método __construct() da seguinte forma:

LoginController.php
require_once('Model/LoginModel.php');

class LoginController extends LoginModel{
 
   
private $LoginModel;
   
private $Funcoes;
 
   
public function __construct(){
        $this
->Funcoes = new Funcoes(); // INSTANCIO A CLASSE FUNÇÕES
   
}
 
   
public function ValidaUsuario($login, $senha){
     
       
if($senhaCodificada = $this->Funcoes->CodificaSenha($login, $senha)){ // CHAMO O MÉTODO DE CRIPTOGRAFAR SENHA
         
           
// Chamo o ValidaUsuario de LoginModel
            $total
= parent::ValidaUsuario($login, $senhaCodificada);
           
return ($total == 1) ? true : false;
         
       
}
   
}
   
   
{ ... }
}

E consegue entrar no __construct() instanciar a classe Funcoes e utilizar seus métodos.

Só não entendi o porque.... Alguém poderia me explicar para que eu consigar utilizar do __construct() de LoginModel.php para fazer a Conexão!!???

Agradeço antecipadamente...

0
16/08/2012 11:44am
(~12 anos atrás)
Marcos Regis respondeu:
Fiz o seguinte teste aqui e tudo ocorreu como o esperado

<?php
class MainVar {
   
public $DBName        = 'dbName';
   
public $DBServer      = 'localhost';
   
public $DBUser        = 'root';
   
public $DBPassword    = '';
}

// Conexao.class.php - Classe de Conexao
class Conexao extends MainVar {
   
   
public function __construct(){
       echo
'Chamou o construtor de Conexao <br />';
   
}
   
   
public function Connect(){
       
        $mysqli
= "mysqli_connect($this->DBServer, $this->DBUser, $this->DBPassword, $this->DBName)";
                             
       
return $mysqli;
   
}
}

// LoginModel.php
class LoginModel extends Conexao{
   
   
private $mysqli;
   
   
public function __construct(){
        echo
'Chamou o construtor de LoginModel <br />';
        $this
->mysqli = parent::Connect();
   
}
   
   
public function ValidaUsuario($login, $senha){
       
        $sql
= "SELECT COUNT(*) AS total
                FROM tabela_usuarios
                WHERE login = ? AND senha = ?"
;
       
       
if($this->mysqli!=null){

            echo
'ENTROU<br />'. time() . '<br />' . $this->mysqli;
           
           
       
}
   
}
   
}


$a
= new LoginModel;

$a
->ValidaUsuario('A',"B");

Qual a versão do PHP que está usando???

Nova Resposta:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)