2
respostas

Separar back-end do front-end com PHP e JS

Olá! Eu estou desenvolvendo um web app com xampp, php e js. No momento atual acabei de finalizar o back do crud de login... O problema é que eu quero fazer com tudo puro, sem libs adicionais ou framwork. Além disso, quero conectar sem abrir tag php no index e nos scripts Pensei que poderia fazer com um ajax(com JS puro), mas não sei se estou tomando o caminho certo, ou o que falta ainda...

Segue o meu controller:

<?php
namespace App\controllers;

use App\model\User_model;
use PDO;
use App\config\database\ConnectionCreator;

require __DIR__ . '/../../vendor/autoload.php';

class User 
{
    private User_model $user_model;

    function __construct(PDO $connection)
    { 
        $this->user_model = new User_model($connection);
    }

    function createUser(string $name, string $username, string $email, string $password) 
    {
        if($this->checkUsernameExists($username)){
            if(empty($this->getEmail($username))){
                $pass_hash = password_hash($password, PASSWORD_DEFAULT);
                $created = $this->user_model->createUser($name, $username, $email, $pass_hash);
                if($created){
                    return 'Usuário criado com sucesso';
                }
            } else {
                return 'Este e-mail já existe';
            }
        }
        
        return 'Este usuário já existe';
    }

    function getEmail(string $username) 
    {
        return $this->user_model->getEmail($username); 
    }

    function checkUsernameExists(string $username): bool 
    {
        return $this->user_model->checkUsernameExists($username);    
    }

    private function getAllUsers(): array 
    {
        return $this->user_model->getAllUsers();   
    }

    private function checkPassword(string $username, string $pass): bool
    {
        $password_hash = ($this->user_model->getPassword($username))[0]['senha']?? 0;

        return password_verify($pass, $password_hash);
    }

    function checkLogin()
    {
            $username = $_POST['username'];
            $password = $_POST['password'];
            if ($this->checkPassword($username, $password)) {
                // Login bem-sucedido
                echo 'Login bem-sucedido';
            } else {
                // Credenciais inválidas
                echo 'Credenciais inválidas';
            }
            //return $this->checkPassword($username, $pass);
    }

    function updatePassword(string $username, string $old_pass, string $npass): bool
    {
        if($this->checkLogin($username, $old_pass)) {
            $user = $this->user_model->getId($username);
            $user_id = $user[0]['id'];
            $npass_hash = password_hash($npass, PASSWORD_DEFAULT);

            return $this->user_model->updatePassword($user_id, $npass_hash);
        }

        return false;
    }

    function deleteUser(string $username): bool
    {
        return $this->user_model->deleteUser($username);
    }

}

Vou mandar o model no outro post...

2 respostas

Segue model:

<?php
namespace App\model;

use PDO;
use PDOStatement;

class User_model {
    private PDO $connection;
    function __construct(PDO $connection)
    {
        $this->connection = $connection;
    }

    function createUser(string $name, string $username, string $email, string $password): bool
    {
        $sqlQuery = "INSERT INTO users_login (nome, username, email, senha) VALUES (:name, :username, :email, :password);";
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(':name', $name);
        $stmt->bindValue(':username', $username);
        $stmt->bindValue(':email', $email);
        $stmt->bindValue(':password', $password);

        return $stmt->execute();
    }

    function checkUsernameExists(string $username): bool 
    {
        $sqlQuery = 'SELECT username FROM users_login WHERE username = :username;';
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(':username', $username);
        $stmt->execute();
        
        return $stmt->rowCount() < 1;
    }

    function getEmail(string $username): array
    {
        $sqlQuery = 'SELECT email FROM users_login WHERE username = :username;';
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(':username', $username);
        $stmt->execute();

        return $stmt->fetchAll();
    }

    function getAllUsers(): array {
        $sqlQuery = 'SELECT * FROM users_login';
        $stmt = $this->connection->query($sqlQuery);

        return $this->hydrateUsersList($stmt);
    }

    private function hydrateUsersList (PDOStatement $stmt): array
    {
        $usersDataList = $stmt->fetchAll();
        $usersList = [];

        foreach($usersDataList as $userData) {
            $usersList[] = $userData;
        }
        return $usersList;
    }

    function getId($username): array
    {
        $sqlQuery = "SELECT id FROM users_login WHERE username = :username;";
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(':username', $username);
        $stmt->execute();
        $result = $stmt->fetchAll();

        return $result;
    }

    function getPassword(string $username): array
    {
        $sqlQuery = "SELECT senha FROM users_login WHERE username = :username;";
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(':username', $username);
        $stmt->execute();
        $result = $stmt->fetchAll();
        return $result;
    }

    function updatePassword($id, $new_passw): bool 
    {
        $sqlQuery = 'UPDATE users_login SET senha = :new_passw WHERE id = :id;';
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(':new_passw', $new_passw);
        $stmt->bindValue(':id', $id);
        
        return $stmt->execute(); 
    }

    function deleteUser(string $username): bool {
        $sqlQuery = 'DELETE FROM users_login WHERE username = :username;';
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(':username', $username);

        return $stmt->execute();
    }
}

Eu só preciso entender como eu chamo um desses métodos(enviando e recebendo valores) no meu JS com as condições que eu informei, ou se não tem como fazer isso dessa forma... Fico grato caso alguem possa me auxiliar.. Meu esquema de pastas está assim: Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Olá, Elton! Tudo bem com você?

Peço desculpa pela demora em respondê-lo.

Uma opção para realizar essa separação é utilizar AJAX com JS puro. Com o AJAX, você pode enviar requisições assíncronas para o servidor e receber os dados de resposta sem precisar recarregar a página.

No seu caso, você pode criar um arquivo JavaScript separado, por exemplo, "script.js", e utilizar o AJAX para fazer as requisições para o back-end. No seu arquivo PHP, você pode criar rotas para receber essas requisições e retornar os dados desejados.

Aqui está um exemplo básico de como utilizar o AJAX com JS puro:

// script.js

function fazerRequisicao() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      // Manipule a resposta do servidor aqui
      console.log(this.responseText);
    }
  };
  xhttp.open("GET", "rota.php", true);
  xhttp.send();
}

No exemplo acima, a função fazerRequisicao() cria uma instância do objeto XMLHttpRequest e define uma função para ser executada quando a resposta do servidor estiver pronta. No exemplo, a função apenas imprime a resposta no console.

No seu arquivo PHP, você pode criar a rota correspondente para receber essa requisição:

// rota.php

require __DIR__ . '/../../vendor/autoload.php';

// Aqui você pode incluir o arquivo com a definição da classe User

// Exemplo de uso da classe User
$userController = new App\controllers\User(new PDO(/* configurações do banco de dados */));

// Exemplo de chamada de método do controller
$userController->checkLogin();

No exemplo acima, é feito o require do autoload e a criação de uma instância do controller User. Em seguida, é chamado o método checkLogin() do controller.

Lembrando que esse é apenas um exemplo básico para ilustrar o uso do AJAX com JS puro. Você pode adaptar esse exemplo para suas necessidades específicas e criar as rotas e métodos no seu arquivo PHP conforme as funcionalidades que você deseja implementar.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.