j'ai un soucis avec mon constructeur dans mon Database.php, l'erreur viendrai d'ici

<?php

use App\Autoloader;

require '../App/Autoloader.php';

if(isset($_GET['p'])) {
$p = $_GET['p'];
} else {
$p = 'home';
}

// Initialision des objects
$db = new App\Database('blog'); L'ERREUR EST A CETTE LIGNE LA , je ne comprend pas bien pourquoi j'ai une erreur je transmet egalement le Database.php et le Autoloader.php plus bas.

ob_start();

if ($p === 'home') {
require '../pages/home.php';
} elseif ($p === 'single') {
require '../pages/singles.php';
}

$content = ob_get_clean();
require '../pages/templates/default.php';

le Database.php

<?php
namespace App;

use \PDO;

class Database{

private $db_name;
private $db_user;
private $db_pass;
private $db_host;
private $pdo;

public function __construct($db_name, $db_user = 'tidus', $db_pass = 'root', $db_host = 'localhost'){ JE SAIS QUE BEAUCOUP DE GENS ONT EU DES SOUCIS AVEC LE CONSTRUCTEUR L'ERREUR VIENS PEUT ETRE D'ICI EGALEMENT , malgré mais plusieurs recherche je ne trouve pas l'erreur ici , meme si le getPDO et ecris en dur meme en mettant les $db cela ne marche pas non plus , donc si vous avez des idée c'est avec plaisir .
    $this->db_user = $db_user;
    $this->db_pass = $db_pass;
    $this->db_host = $db_host;
}

private function getPDO(){
    if($this->pdo === null){
        $pdo = new PDO('mysql:dbname=blog;host=localhost', 'tidus', 'root');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->pdo = $pdo;
    }
    return $this->pdo;
}

public function query($statement){
    $req = $this->getPDO()->query($statement);
    $datas = $req->fetchAll(PDO::FETCH_OBJ);
    return $datas;
}

}

le Autoloader.php

<?php
namespace App;

class Autoloader {

static function register() {
    spl_upload_register(array(__CLASS__, 'autoload'));

}

static function autoload($class){
    if (strpos($class, __NAMESPACE__ . '\\') === 0){
        $class = str_replace(__NAMESPACE__ . '\\', '', $class);
        $class = str_replace('\\', '/', $class);
        require __DIR__ . '/' . $class . '.php';

    }
}

}

8 réponses


Bonjour, est-ce que tu peux nous indiquer le message d'erreur que tu obtiens ?

Hello, bon déjà je repost ton code en propre ^^

<?php

use App\Autoloader;

require '../App/Autoloader.php';

if(isset($_GET['p'])) {
    $p = $_GET['p'];
} else {
    $p = 'home';
}

// Initialision des objects
$db = new App\Database('blog'); L'ERREUR EST A CETTE LIGNE LA , je ne comprend pas bien pourquoi j'ai une erreur je transmet egalement le Database.php et le Autoloader.php plus bas.

ob_start();

if ($p === 'home') {
    require '../pages/home.php';
} elseif ($p === 'single') {
    require '../pages/singles.php';
}

$content = ob_get_clean();
require '../pages/templates/default.php';
<?php
namespace App;

use \PDO;

class Database{
    private $db_name;
    private $db_user;
    private $db_pass;
    private $db_host;
    private $pdo;

    public function __construct($db_name, $db_user = 'tidus', $db_pass = 'root', $db_host = 'localhost'){ JE SAIS QUE BEAUCOUP DE GENS ONT EU DES SOUCIS AVEC LE CONSTRUCTEUR L'ERREUR VIENS PEUT ETRE D'ICI EGALEMENT , malgré mais plusieurs recherche je ne trouve pas l'erreur ici , meme si le getPDO et ecris en dur meme en mettant les $db cela ne marche pas non plus , donc si vous avez des idée c'est avec plaisir .
        $this->db_user = $db_user;
        $this->db_pass = $db_pass;
        $this->db_host = $db_host;
    }

    private function getPDO() {
        if ($this->pdo === null) {
            $pdo = new PDO('mysql:dbname=blog;host=localhost', 'tidus', 'root');
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->pdo = $pdo;
        }

        return $this->pdo;
    }

    public function query($statement){
        $req = $this->getPDO()->query($statement);
        $datas = $req->fetchAll(PDO::FETCH_OBJ);
        return $datas;
    }
}
<?php

namespace App;

class Autoloader {
    static function register() {
        spl_upload_register(array(__CLASS__, 'autoload'));
    }

    static function autoload($class){
        if (strpos($class, __NAMESPACE__ . '\\') === 0){
            $class = str_replace(__NAMESPACE__ . '\\', '', $class);
            $class = str_replace('\\', '/', $class);
            require __DIR__ . '/' . $class . '.php';
        }
    }
}

Okay alors pour commencer, tu n'as pas ajouté le $db_name au $this, ce n'est pas ce qui provoque le bug parce que de toutes façon ça ne sert à rien d'ajouter dans $this tes paramètres db_user etc... Tu ne t'en sert pas, dans getPDO tu utilises les valeurs en dur

Pour utiliser ce qui est dans ton constructeur tu devrait modifier la function getPDO()

$pdo = new PDO('mysql:dbname=' . $this->db_name . ';host=' . $this->db_host, $this->db_user, $this->db_pass);

Même chose pour ton getPDO, tu passes ton $pdo en class globale $pdo mais tu ne l'utilises pas, dans ta function query() tu appèles getPDO()

si tu veux passer en global tu devrait faire un truc du genre

protected $pdo; // Ah oui utilises plutot protected, comme ça si tu veux optimiser ton code et utiliser des child tu pourras y acceder

public function __construct ($db_name, $db_user = 'tidus', $db_pass = 'root', $db_host = 'localhost') {
        $this->db_user = $db_user;
        $this->db_pass = $db_pass;
        $this->db_host = $db_host;
        $this->getPDO();
}

public function query($statement){
        $req = $this->pdo->query($statement);
        $datas = $req->fetchAll(PDO::FETCH_OBJ);
        return $datas;
}

Bon la je t'ai juste donné des trucs pour rendre ton code cohérent, je n'ai rien indiqué qui pourrait résoudre le lag

Faudrait que tu nous donnes le message d'erreur que tu recoit pour qu'on puisse trouver la solution :p

J'obtient le message d'erreur :

désolé du retard j'etais sur la formation symfony que je fait en paralelles.

Fatal error: Uncaught Error: Class "App\Database" not found in C:\Users\tom\Documents\blog php\public\index.php:14 Stack trace: #0 {main} thrown in C:\Users\tom\Documents\blog php\public\index.php on line 14

Mmmh probleme avec ton autoload ^^'

essayes ça

public static function register()
    {
        spl_autoload_register(function ($class) {
            $file = str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
            if (file_exists($file)) {
                require $file;
                return true;
            }
            return false;
        });
    }

J'ai la meme erreur ...

<?php
namespace App;

class Autoloader {

public static function register()
{
    spl_autoload_register(function ($class) {
        $file = str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
        if (file_exists($file)) {
            require $file;
            return true;
        }
        return false;
    });
}

static function autoload($class){
    if (strpos($class, __NAMESPACE__ . '\\') === 0){
        $class = str_replace(__NAMESPACE__ . '\\', '', $class);
        $class = str_replace('\\', '/', $class);
        require __DIR__ . '/' . $class . '.php';

    }
}

}

Attends, dans ton index.php tu ne lances pas ton register(), du coup le spl_autoload_register ne va jamais tracker les appels de class :o

Lances un Autoload::register() juste après ton require

En tout cas faut chercher du coté de l'autoload, ou alors des namespaces mal nommés, parce que l'erreur dit que le projet n'arrive pas a trouver la class Database :p

Après le mieux ce serait de passer par composer, au moins c'est sur que l'autoload fonctionne x)

Hello,

Je me permets aussi d'indiquer que le tuto de Grafikart sur la POO commence à ce faire vieux et qu'il y a donc des nouveautés de PHP utile.

Je te conseil d'aller voir les PSR :

Et aussi de voir les nouveautés de php depuis php 7 à la version 8.1 (voir 8.2 qui arrive bientôt)

Fichier app/Database.php :

<?php

namespace App;

use PDO;
use PDOStatement;

class Database extends PDO
{
    public function __construct(string $dsn, ?string $username = null, ?string $password = null, ?array $options = null)
    {
        parent::__construct($dsn, $username, $password, $options);
        parent::setAttribute(parent::ATTR_DEFAULT_FETCH_MODE, parent::FETCH_ASSOC);
        // Seulement si tu es encore en php 7.4 ou moins
        // mais, j'espère que ce n'est plus le cas.
        parent::setAttribute(parent::ATTR_ERRMODE, parent::ERRMODE_EXCEPTION);
        // Fin code que pour PHP ≤ 7.4
    }

    public function request(string $statement, array $parameters = []): PDOStatement
    {
        $request = parent::prepare($statement);
        $request->execute($parameters);

        return $request;
    }
}

Fichier app/Autoloader.php :

<?php

namespace App;

class Autoloader
{
    public static function register(): void
    {
        spl_autoload_register(static fn (string $classname) => Autoloader::load($classname));
    }

    public static function load(string $classname): void
    {
        $namespace = __NAMESPACE__ . '\\';
        if (!str_starts_with($classname, $namespace)) {
            return;
        }

        $class = str_replace($namespace, '', $classname);
        $class = str_replace('\\', '/', $class);

        require ROOT . sprintf("/app/%s.php", $class);
    }
}

// Si tu ne veux pas oublier de register tu peux le mettre ici
// plutôt que dans le fichier index.php
Autoloader::register();

Fichier public/index.php :

<?php

use App\Database;

define('ROOT', realpath(__DIR__ . '/../'));

require ROOT . '/app/Autoloader.php';

// Tes lignes if isset + else sont remplaçables par :
$page = $_GET['p'] ?? 'home';

// J'utilise postgresql et non mysql mais c'est pareil pour la connexion
$db = new Database('pgsql:host=localhost;dbname=tuto;port=5432', 'tuto', 'tuto');
$users = $db->request('select id, name, email, created_at from users');

foreach ($users as $user) {
    var_dump($user);
}

Et j'ai comme résultat :

I:\Projects\tuto\public\index.php:17:
array (size=4)
  'id' => string 'a0ef9ed0-3a63-4cb9-bf2a-04b8d048a4b4' (length=36)
  'name' => string 'quentin' (length=7)
  'email' => string 'quentin@grafikart.fr' (length=20)
  'created_at' => string '2022-08-13 10:16:46' (length=19)

I:\Projects\tuto\public\index.php:17:
array (size=4)
  'id' => string '57ea93dd-d4a4-43bf-a6e3-4d9733f0a9f2' (length=36)
  'name' => string 'robin' (length=5)
  'email' => string 'robin@grafikart.fr' (length=18)
  'created_at' => string '2022-08-13 10:17:27' (length=19)