Problème avec les requêtes préparé

yukimura27 Messages postés 10 Date d'inscription mardi 13 avril 2010 Statut Membre Dernière intervention 21 février 2011 - 14 févr. 2011 à 15:23
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 - 14 févr. 2011 à 22:02
Bonjour,

J'aimerais que l'on éclair ma lanterne car j'ai quelques soucis et quelques incompréhension par ci par la .

j'ai une page PDO.php avec connection a la base de données :

<?php

class Connection
{

/* Attributs */
protected $bdd;
private $host;
private $login;
private $pwd;
private $db;


/* Constructeur */
public function __construct()
{
$this->host = "";
$this->login = "";
$this->pwd = "";
$this->db = "";
}

/* Méthodes de connection*/
public function Connect($host,$db,$user,$pwd)
{
try
{
$this->bdd = new PDO("mysql:host=$host;dbname=$db", $user, $pwd);
}
catch (PDOException $e)
{
die( "Erreur : " . $e->getMessage() . "
");
}
}

}

?>

ensuite une page sql.php avec mes requete sql préparé :

<?php
require_once "PDO.php";

class Sql extends Connection
{

/* Requete preparé News*/
public function recupNews()
{
$select = $this->bdd->prepare("SELECT * FROM news ORDER BY dateNews DESC LIMIT ".$first.",".$nombre." ");
$select->execute();
return $select->fetch(PDO::FETCH_ASSOC);
}

public function compteNews()
{
try
{
$count = $this->bdd->prepare("SELECT COUNT(id) AS nombreNews FROM news");
$count->execute();
return $data['nombreNews'] = $count->fetch(PDO::FETCH_ASSOC);
}
catch(Exception $e)
{
die($e->getMessage().''.$e->getTrace().'

');
}

}

/* Requete preparé Comment */
public function addCom()
{
if(!empty($_POST))
{
extract($_POST);
$comm = $this->bdd->prepare("INSERT INTO comment (pseudo, url, mail, contenu, news_id) VALUES ('$pseudo', '$url', '$mail', '$contenu', '$news_id') ");
$comm->execute();
return $data = $count->fetch(PDO::FETCH_ASSOC);
}

}

/* Requete preparé Admin */
public function createNews()
{
extract($_POST);
$create = $this->bdd->prepare("INSERT INTO news (titre, contenu) VALUES ('$titre' , '$contenu') ");
$create->execute();
}

public function editNews()
{
if(!empty($_POST))
{
extract($_POST);
$edit = $this->bdd->prepare("UPDATE news SET titre='$titre', contenu='$contenu' WHERE id=$id");
$edit->execute();
echo "New Modifiée";
$_GET["id"]=$id;
}

$sql= "SELECT * FROM news WHERE id={$_GET['id']}";
$result = $this->bdd->query($sql);
return $result->fetch(PDO::FETCH_ASSOC);
}

public function deleteNews()
{
$sql= "DELETE FROM news WHERE id={$_GET['id']}";
$result = $this->bdd->query($sql) or die ('Erreur SQL !
'.$sql.'
'.mysql_error() );
}

}
?>

une autre page NewsList.php qui stock puis affiche les news :

<?php
require_once "Sql.php";

class NewsList extends Sql
{

/* Attributs */
private $newsList = array();
private $nombreNewsParPage;

/* Contructeur */
public function __construct()
{
$this->newsList = "";
$this->nombreNewsParPage = 4;
}

/* GETTER */
public function getNombreNewsParPage()
{
return $this->nombreNewsParPage;
}

/* SETTER */
public function setNewsList($news)
{
$this->newsList[] = $news;
}

public function setNombreNewsParPage($nombreNewsParPage)
{
$this->nombreNewsParPage = $nombreNewsParPage;
}

/* Méthodes */
public function stockNews($first, $nombre)
{
try
{
while($data = $this->recupNews->select)
{
$news = new News();
$news->setIdNews($data['idNews']);
$news->setTitreNews($data['titreNews']);
$news->setContenuNews($data['contenuNews']);
$news->setDateNews($data['dateNews']);

$this->setNewsList($news);
}
}
catch(Exception $e)
{
die($e->getMessage().''.$e->getTrace().'

');
}
}

public function afficherNewsList()
{
$nombreNews = $this->compteNews();

$nombrePage = ceil($nombreNews/$this->getNombreNewsParPage());
$page = isset($_GET['p']) ? $_GET['p'] : 1;
$firstNews = ($page-1)*$this->getNombreNewsParPage();

$this->stockNews($firstNews,$this->getNombreNewsParPage());

foreach($this->newsList as $news)
{
echo $news->getTitreNews();
echo $news->getDateNews();
echo $news->getContenuNews();
}

for($i=1;$i<=$nombrePage;$i++)
{
echo "< a href='index.php?page=".$i."'>".$i."< /a> ";
}

}


}



?>

une autre encore ^^ News.php qui utilise les fonction magic pour le stockage des mes news :

<?php

class News
{
/* Attributs */
private $idNews;
private $titreNews;
private $contenuNews;
private $dateNews;

/* Constructeurs */
public function __construct()
{
$idNews = 0;
$titreNews = "";
$contenuNews = "";
$dateNews = "";
}

/* GETTER */
public function getIdNews()
{
return $this->idNews;
}

public function getTitreNews()
{
return $this->titreNews;
}

public function getContenuNews()
{
return $this->contenuNews;
}

public function getDateNews()
{
return $this->dateNews;
}

/* SETTER */
public function setIdNews($id)
{
$this->idNews = $id;
}

public function setSitreNews($titre)
{
$this->titreNews = $titre;
}

public function setContenuNews($contenu)
{
$this->contenuNews = $contenu;
}

public function setDateNews($date)
{
$this->dateNews = $date;
}




}




?>

et enfin un index.php qui affiche le tout :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test d'affichage de news en php POO</title>

</head>



News


<?php

require_once 'NewsList.php';

$app = new Connection();
$app->Connect(localhost,news,root,'');

$newsList = new NewsList();
$newsList->afficherNewsList();

?>


</html>

Voila je débute dans la POO PHP donc je voudrais savoir :

- si mon héritage est correcte ?
- si mes requête préparé sont bien utilisé ?
- Pourquoi dans ma function compteNews, il me dit que "Call to a member function prepare() on a non-object in C:\xampp\htdocs\NewsCommentPage\sql.php on line 19"
- Comment mieux sécuriser mes requêtes avec petit exemple si possible ^^ car j'ai regardé pas mal de tuto mais j'ai pas bien compris ou mal appréhendé.
- Comment mieux optimiser mon code ?

Merci...

3 réponses

yukimura27 Messages postés 10 Date d'inscription mardi 13 avril 2010 Statut Membre Dernière intervention 21 février 2011
14 févr. 2011 à 15:45
je viens de voir qu'il y avait une erreur dans mon code mais ça na rien a voir ^^.

Dans sql.php function editNews et deleteNews, c'est comment ça :

public function editNews()
{
if(!empty($_POST))
{
extract($_POST);
$edit = $this->bdd->prepare("UPDATE news SET titre='$titre', contenu='$contenu' WHERE id=$id");
$edit->execute();
echo "New Modifiée";
$_GET["id"]=$id;
}

$sql = $this->bdd->prepare("SELECT * FROM news WHERE id={$_GET['id']}");
$sql->execute();
return $sql->fetch(PDO::FETCH_ASSOC);
}

public function deleteNews()
{
$delete = $this->bdd->prepare("DELETE FROM news WHERE id={$_GET['id']}");
$delete->execute();
return $delete->fetch(PDO::FETCH_ASSOC);

}
0
yukimura27 Messages postés 10 Date d'inscription mardi 13 avril 2010 Statut Membre Dernière intervention 21 février 2011
14 févr. 2011 à 15:46
Arggg et il y a pas le return $delete->fetch(PDO::FETCH_ASSOC); dans deleteNews.

Voila ^^
0
phpAnonyme Messages postés 392 Date d'inscription mercredi 28 octobre 2009 Statut Membre Dernière intervention 23 mars 2012 55
14 févr. 2011 à 22:02
lut,

Si tu initialise dans le constructeur host,login, etc... ne vaut-il pas mieux les utilisés, dans ta méthode Connect() ?? Car à la place tu utilise les arguments passés dans la méthode Connect() ! Faut savoir ce que tu veux !
Sinon à la place tu pouvait tout aussi bien passés les arguments directement dans le constructeur :

$app = new Connection(host, db, user, pwd);
$app->Connect();


Après étendre une classe de connexion c'est pas ce qu'il y a de mieux à faire ! Contrairement aux interfaces on ne peut étendre qu'une seule classe à la fois.
Donc le mieux serait d'utiliser une méthode statique avec un singleton.
Et un autre avantage c'est que tu n'aura pas à instancier ta classe de connexion à chaque fois.

Par exemple
<?php
class Connection 
{

private static $_instance = null;

static public function connect()
{
if(is_null(self::$_instance)) {
try {
self::$_instance = new PDO(_DB_DSN, _DB_USER, _DB_PASSWD);
self::$_instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(Exception $e) { 
die($e->getMessage());
}
}
return self::$_instance;
}
}
?>

Il te resterait qu'à faire une connexion comme ceci
Connection::connect()->prepare();

comme tu fais déjà avec
$this->bdd->prepare();



- Tu n'utilise pas "correctement" ou du moins pas à bon usage les requêtes préparées, je t'invite à lire ou à relire la doc.
http://fr2.php.net/manual/fr/pdo.prepare.php


[quote=Toi]Pourquoi dans ma function compteNews, il me dit que "Call to a member function prepare() on a non-object in C:\xampp\htdocs\NewsCommentPage\sql.php on line 19"/quote
C'est comme je t'ai dit plus haut c'est l'inconvénient de ta connexion.
En faite ton objet de connexion est 'app' et l'objet des news est 'newsList', ils ont donc des noms différents.
Dans ta méthode compteNews() tu fais appel au nom d'objet 'bdd' alors qu'il ne fais pas parti du groupe d'objet 'newsList' mais de 'app'.
Alors quand tu utilise $this dans la méthode compteNews tu fais référence à 'newsList'.
D'où l'erreur car il ne le trouve pas et il n'est pas "définit" dans la classe News.
Vu que tu étend la classe Connection à la classe News et que l'accès à l'objet 'bdd' est protégé tu peux utiliser 'parent'.
En claire au lieu de faire '$this->bdd', tu devrais faire 'parent::bdd'


- Ton code n'est pas optimisé s'est sûre, il y a encore des erreurs, des lacunes, et des choses qu'on ne devrait pas voir qui ne sont pas forcément de l'ordre de l'objet comme par exemple l'utilisation de extract() qui est à proscrire sur des données inconnues, hin !


Bon comme d'habitude mes explications sont très sommaires, mais j'espère tout de même avoir pu t'éclairer un peu. Expliquer la POO c'est pas facile surtout en évitant de mettre trop de technique dedans.



______________________________________________________________________
0
Rejoignez-nous