POO [Résolu]

Signaler
Messages postés
7
Date d'inscription
lundi 4 avril 2016
Statut
Membre
Dernière intervention
2 août 2016
-
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
-
Bonjour,

Je suis un tutoriel sur la programmation orientée objet en php. Mais voila, je rencontre un petit problème avec mon code.
Voici mon fichier users.php

<?php
$users = App::getInstance()->getTable('users')->getAll();
?>
<div id="contenu">
<table>
<thead>
<tr>
<th>
<a>Nom</a>
</th>
<th>
<a>Nom d'utilisateur</a>
</th>
<th>
<a>Groupe</a>
</th>
<th>
<a>Désactivé</a>
</th>
</tr>
</thead>
<tbody>
<?php
foreach ($users as $user):
?>
<tr id="user_<?= $user->id_user ?>" onclick="window.location.href='<?= $user->url ?>'">
<td> <?= $user->name_user ?> </td>
<td> <?= $user->username_user ?> </td>
<td> <?= $user->name_group ?> </td>
<td class="boolean">
<input type="checkbox" <?= ($user->active_user) ? 'checked' : '' ?> disabled="">
</td>
</tr>
<? endforeach; ?>
</tbody>
<tfoot></tfoot>
</table>
</div>

Ce qui ne fonctionne pas c'est lorsque je fais cette ligne, je me retrouve avec une page blanche.

<?= $user->url ?>

Voici mes autres fichiers:

App.php:

<?php
use Core\Config;
use Core\Database;

class App{
private static $_instance;
private $db_instance;

public static function getInstance(){
if(is_null(self::$_instance)){
self::$_instance = new App();
}
return self::$_instance;
}

public static function load(){
session_start();
require ROOT . '/app/Autoloader.php';
\App\Autoloader::register();
require ROOT . '/core/Autoloader.php';
\Core\Autoloader::register();
}

public function getTable($name){
$class_name = '\\App\\Model\\Model' . ucfirst($name);
return new $class_name($this->getDb());
}

public function getDb(){
$config = Config::getInstance(ROOT . '/config/config.php');
if(is_null($this->db_instance)){
$this->db_instance = new Database($config->get('db_name'), $config->get('db_user'), $config->get('db_pass'), $config->get('db_host'));
}
return $this->db_instance;
}
}

ModelUsers.php:

<?php
namespace App\Model;

use Core\Model\Model;

class ModelUsers extends Model{
public function __get($name)
{
$method = 'get' . ucfirst($name);
$this->$name = $this->$method();
return $this->$name;
}

public function getUrl(){
return 'index.php?p=users.edit&id='. $this->id_user;
}
}

Model.php:

<?php
namespace Core\Model;
use Core\Database;
class Model{
protected $table;
protected $db;

public function __get($name)
{
$method = 'get' . ucfirst($name);
$this->$name = $this->$method();
return $this->$name;
}

public function __construct(Database $db)
{
$this->db = $db;
if(is_null($this->table)){
$class_parts = explode('\\', get_class($this));
$class_name = end($class_parts);
$this->table = strtoupper(str_replace('Model', '', $class_name));
}
}

public function query($statement, $attributes = null, $one = false){
if($attributes){
return $this->db->prepare($statement, $attributes, get_called_class(), $one);
}else{
return $this->db->query($statement, get_called_class(), $one);
}
}

public function getAll(){
return $this->query("SELECT * FROM " . $this->table);
}
}

Database.php:

<?php
namespace Core;
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, $db_pass, $db_host)
{
$this->db_name = $db_name;
$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=' . $this->db_name . ';host=' . $this->db_host, $this->db_user, $this->db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo = $pdo;
}
return $this->pdo;
}

public function query($statement, $class_name = null, $one = false)
{
$req = $this->getPDO()->query($statement);
if($class_name === null){
$req->setFetchMode(PDO::FETCH_OBJ);
}else{
$req->setFetchMode(PDO::FETCH_CLASS, $class_name);
}
if ($one) {
$data = $req->fetch();
} else {
$data = $req->fetchAll();
}
return $data;
}

public function prepare($statement, $attributes, $class_name = null, $one = false)
{
$req = $this->getPDO()->prepare($statement);
if($class_name === null){
$req->setFetchMode(PDO::FETCH_OBJ);
}else{
$req->setFetchMode(PDO::FETCH_CLASS, $class_name);
}
$req->execute($attributes);
if ($one){
return $req->fetch();
}
else{
return $req->fetchAll();
}
}
}

Je ne sais pas si vous avez tout ce que vous avez besoin pour m'aider, mais faites le moi savoir.

1 réponse

Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
Salut,

Bon je ne connais pas la synthaxe
<?= ... ?>
he ne connais que
<?php ... ?> 
.

Sinon si tu veux afficher des choses, faire seulement
<?= $user->url ?>
ne suffit pas, utilise le 'echo' et termines tes lignes par ";". Par exemple :


<td> <?php echo $user->name_user; ?> </td>
<td> <?php echo $user->username_user; ?> </td>
<td> <?php echo $user->name_group; ?> </td>


et vois déjà ce que ca donne.

naga
Messages postés
7
Date d'inscription
lundi 4 avril 2016
Statut
Membre
Dernière intervention
2 août 2016

<?= ... ?>

c'est la version abréger de
<?php echo ...; ?>


Selon plusieurs commentaires que j'ai eu, ce n'est pas une bonne pratique mais ce n'est pas la solution à mon problème. J'ai toutefois changer ma syntaxe pour en être sur et malheureusement j'ai encore mon problème. Après plusieurs tests, je sais d'où vient le problème mais je n'ai pas encore trouver ce qui ne va pas.

C'est que mon objet
$users
est de type stdclass tandis qu'elle devrait être de type ModelUsers. Dans ce cas,
<?php echo $user->url ?>
fonctionnerait. Mais lorsque je fais,
$req->setFetchMode(PDO::FETCH_CLASS, $class_name);
afin de le mettre en ModelUsers, c'est là que tout plante.

Pour le moment j'ai régler mon problème en écrivant
onclick="window.location.href='index.php?p=users.edit&id=<?php echo $user->id_user; ?>'

au lieu d'utiliser le FETCH_CLASS.

Mais j'aurais bien aimer comprendre pourquoi il ne fonctionne pas...
Messages postés
7
Date d'inscription
lundi 4 avril 2016
Statut
Membre
Dernière intervention
2 août 2016

Je faisais référence à la classe elle même, elle ne pouvait donc pas fonctionner. J'ai créer une autre classe pour mettre les méthodes créer un objet de cette classe avec ma base de données. Merci beaucoup pour ton coup de main!
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
Ok merci pour l info, je dois être un peu a la ramasse sur les quelques nouveautées de syntaxe ^^

Du coup je vais essayer de comprendre le tout en même temps.

Premier point:


$class_name = '\\App\\Model\\Model' . ucfirst($name);
return new $class_name($this->getDb());


avec l instantiation :


$users = App::getInstance()->getTable('users')->getAll();


Si je comprends bien, le but est de créer une classe via la méthode App::getTable qui, en utilisant un nom de classe en parametre va faire l allocation (et du coup la lecture en bdd sera dans le constructeur).

Pour la méthode "__get" , c est un copié collé entre ModelUsers qui est l extension de Model => inutile de le réecrire. ( c est d ailleurs pas impossible que ca pose probleme vu que le parent est censé passer en premier mais j ai un doute).

Ensuite dans ta fonction "ModelUsers::geturl", tu renvois "$this->id_user" alors que id_user n'appartient pas à la classe , ce qui est logique vue que tu est censé avoir plus d un utilisateur OR ta classe représente une table.

Enfin:

$users = App::getInstance()->getTable('users')->getAll();


Puis :

foreach ($users as $user)


$user ne sera en aucuns cas un ModelUsers! tu retourne
$this->query("SELECT * FROM " . $this->table);
et donc un tableau de row qui en aucuns cas ne connais de fonction "getUrl".

En fait j ai l impression que le but était d'implémenter un objet par entrée dans ta BDD , Model devant être le conteneur et ModelUsers représentant un objet de ce conteneur (et donc pas une extension). Je penses que tu t'es un peu emmelé les pinceaux ^^
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
(j essayerai de prendre un peu de temps demain pour corriger)
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
ah ok du coup t as trouvé pendant ma recherche ^^ et en fait t'es arrivé au même point ! ca va je me suis pas trop paumé =p