isset à l'intérieur d'une class
Bonjour ou bonsoir.
Si à $affichage->t(), je ne mets pas d'argument, j’obtiens une erreur, et pour éviter cette erreur, j'ai pensé de placer un isset à l'intérieur de la class. Est-ce que ça se fait?
<?php
class A
{
private $t;
function t($t)
{
$this->t=$t;
return $this->t;
}
}
$affichage = NEW A();
echo $affichage->t();
Genre:
if(isset=$t) {$="ajouter un argument"}
else { $this->t=$t; }
à la place de:
$this->t=$t;
Réponses apportées à cette discussion
Dans n'importe quelle fonction ou méthode de classe, un paramètre peut être assorti d'une valeur par défaut, voire éventuellement être défini à null par défaut.
Ainsi :
function maFonction($param=null)
{
$this->_paramClass = $param;
}
Ensuite, appeler maFonction() en envoyant un paramètre ou encore sans envoyer de paramètre ne retournera aucune erreur.
Si dans le reste de ta classe il y a des erreurs parce que la propriété est à null, c'est une autre histoire bien entendu.
Bonjour cyrano!
J'ai tenté quelque chose comme:
<?php
class A
{
private $t;
function t($t='test')
{
if(isset($t))
{
$this->t=$t;
return $this->t;
}
else
{
$this->t='none';
return $this->t;
}
}
}
$affichage = NEW A();
echo $affichage->t(ss);
Le but de mon poste était de voir si j'omettais les guillemets simple par erreur comme ceci:
$affichage->t(dd);
Si je ne mets rien, ça va donner "test" par défaut. Si je mets (2), ça va donner 2. Si je mets une chaine de caractère entre guillemets, ça va donner une chaine.
J'ai vu la fonction :
property_exists('A', '$t')
Mais, ça ne marche pas pour mon cas.
Salut,
on va remettre un peu les choses à plat.
Dans la mesure où tu indiques une valeur par défaut à un paramètre, le if/else dans ta fonction tel que tu l'as créé ne sert pas à grand chose.
D'abord parce que la valeur indiquée par défaut est différente de celle utilisée dans le else. Tu pourrais donc d'abord simplifier en écrivant :
class A
{
private $t;
function t($t='none')
{
$this->t=$t;
return $this->t;
}
}
Dans ce cas, si tu n'envoies aucun paramètre ou bien que tu envoies une variable qui vaut NULL, alors la valeur qui sera affectée sera « none », autrement, ce sera la valeur envoyée
Ensuite, lorsque tu écris :
echo $affichage->t(ss);
Soit « ss » est défini quelque part comme constante, soit ça va te générer une erreur, mais cette erreur n'a strictement aucun rapport avec ta classe.
Alors, y a aucun moyen d'avoir une erreur personnalisé dans le cas d'une constante alors que c'est du numérique qu'on attends ou bien une chaine de caractères. Si je comprends bien.
Comme convertir automatiquement la constante en numérique ou bien en chaine de caractères.
Surtout pour vérifier si c'est une bonne valeur qu'on indique et le bon type.
Ha ben attention, tu abordes là un autre aspect du problème :
- Nous avons d'une part le fait qu'il existe ou non une valeur;
- Nous avons d'autre part quel format a cette valeur;
Dans ta fonction/méthode, rien ne t'empêche de vérifier le type, ou bien si la valeur reçu est dans une tranche de valeurs. Pour certains types, tu peux l'indiquer dans a définition de la fonction, par exemple, les entiers ou les objets, exemple :
class A
{
private $t;
function t(int $t=1)
{
$this->t=$t;
return $this->t;
}
}
Ici, la méthode t() attend un entier et la valeur par défaut sera 1;
Autre exemple :
class A
{
private $t;
/**
*
* @param PDOStatement $t
* @return PDOStatement
*/
public function t(PDOStatement $t=null)
{
$this->t=$t;
return $this->t;
}
}
Ici, la méthode attend une instance de PDOStatement, quoique ce soit facultatif, ça veut dire que tu peux ne rien envoyer du tout, mais si tu envoies quelque chose qui n'est pas une instance de PDOStatement, tu auras une erreur.
Mais tu pourrais aussi bien avoir des vérifications à l'intérieur de la méthode elle-même :
class A
{
private $t;
/**
*
* @param float $t
*/
public function t($t=null)
{
if(!is_null($t) && !is_numeric($t))
{
$t = null;
}
$this->t=$t;
return $this->t;
}
}
ici, si on reçoit une valeur non numérique, on affectera NULL à la variable avant l'affectation. Ceci est un exemple, tu peux définir toutes les conditions que tu veux selon le besoin.
Est-ce que tu t'y retrouves mieux ?
Ceci dit, attention, tu as évoqué les erreurs personnalisées : là encore, c'est un autre aspect de la programmation, la gestion d'erreur personnalisée existe en PHP, mais ça pourrait prendre un chapitre entier dans un bouquin
Oui, c'est bien expliqué pour moi.
J'aurais crû que le fait de mettre :
(!is_null($t) && !is_numeric($t)
ça aurait mis null si je mettais une constante par erreur dans ceci:
$o = NEW A;
echo $o->t(ss);
L'erreur que j'obtiens:
Notice: Use of undefined constant ss - assumed 'ss' in t.php on line 22
Oui, ça, je te l'ai expliqué plus tôt, l'erreur ne vient pas de la classe mais de l'appel à la méthode qui comporte une erreur parce que « ss » n'est pas défini comme constante. L'erreur est déterminée avant même que le déroulement chronologique du code n'arrive à la méthode de la classe elle-même.
Dans ce cas, il faut à l'entrée d'un formulaire ou à la sortie s'assurer que c'est bien des chaines de caractères ou du numérique qu'on désire.
Merci. Ça m'a permis d'apprendre sur la manière d'écrire des vérifications dans une classe.
Un truc que je ne pige pas dans mes lectures, ce sont les instanciations dans les fonctions d'une classe et les deux -> dans mon exemple:
public function artiste($idArtiste) {
$artiste = $this->artiste->getArtiste($idArtiste);
$vue = new Vue("Artiste");
$vue->generer(array('artiste' => $artiste));
}
J'ai fini par suivre un tutoriel et j'ai adapté à mon cas. j'étudie l'exemple pour le comprendre. Le résultat marche bien mais faut que je le comprenne pour évoluer plus loin.
Ceci :
$artiste = $this->artiste->getArtiste($idArtiste);
On appelle ça du chainage. Sommairement, artiste, la propriété de l'instance courante, est une instance d'une classe artiste qui a donc une méthode getArtiste().
C'est une manière plus courte d'écrire quelque chose comme ceci :
$oArtiste = $this->artiste;
$artiste = $oArtiste->getArtiste($idArtiste);
Il existe d'autres éléments sur le chainage, mais qui n'ont à priori aucun intérêt ici.
Bonjour Cyrano.
A l'intérieur d'une fonction, une instanciation, je comprends pas vraiment l'idée. Je vais tenter de raisonner ce qui suit:
public function artiste($idArtiste) {
$artiste = $this->artiste->getArtiste($idArtiste);
$vue = new Vue("Artiste");
$vue->generer(array('artiste' => $artiste));
}
C'est mettre dans une variable, la propriété (public $artiste)
Quand je fais appel à la fonction artiste($idArtiste), getArtiste($idArtiste)va utiliser le propriété le ID de la table "artiste" à son tour .... j'essaie de faire le déroulement ce que qui se passe avec la fonction "public function artiste($idArtiste)" quand il est utilisé. Je ne sais pas comment l'organisé pour l'expliquer.
Typiquement, d.après ce que je peux déduire de ce bout de code, ta méthode artiste est dans un contrôleur.
Ce contrôleur a d'abord besoin d'un modèle pour collecter des données, c'est ce qui se passe dans la première ligne où tu définis la valeur de ta variable $artiste en demandant au modèle contenu dans $this->artiste de te retourner les informations dont tu as besoin.
Ensuite, tu as besoin de la vue pour retourner les informations à afficher : donc tu crées une instance de la classe de vue en lui indiquant quel template utiliser et tu fais appel à sa méthode generer() pour que le contenu de ta page soit construite.
Voilà, maintenant, je ne vois pas trop ce que tu ne comprends pas.
Salut et bonjour ou bonsoir :-) Cyrano.
$oArtiste = $this->artiste;
$artiste = $oArtiste->getArtiste($idArtiste);
La variable $oArtiste va chercher la propriété $artiste
et la variable $artiste va chercher la fonction getArtiste() situé dans mon modèle. et dès l'exécution de artiste($idArtiste)ça va chercher la l'affichage détaillée des artiste dans la vue.
Je dis selon ce que je comprends.
Salut,
c'est globalement assez juste.
Mais garde à l'esprit que la propriété artiste de ta classe est elle-même l'instance d'une autre classe, et qu'elle possède donc elle-même des propriétés et des méthodes, ce qui te permet de faire :
$artiste = $this->artiste->getArtiste($idArtiste);
Pour obtenir exactement le même résultat que si tu fais :
$oArtiste = $this->artiste;
$artiste = $oArtiste->getArtiste($idArtiste);
À ce stade, ton contrôleur fait appel au modèle pour collecter les données dont il besoin avant de construire la vue.
Ceci étant, pour t'y retrouver plus facilement, je te suggère d'adopter un certain nombre de règles d'écriture pour ton code.
- Pour les propriétés ou les méthodes privées de tes classes, préfixe-les avec un underscore, par exemple $_artiste au lieu de $artiste;
- Pour savoir à quel type de données tu as affaire, ajoute une lettre en préfixe : par exemple pour un objet, ajoute un « o », pour en entier, un « i », pour un nombre flottant un « f », pour un tableau indexé ou un tableau associatif un « a » (array), etc...
Utilise l'écriture en camelCase, c'est à dire que lorsque les noms de tes variables ou de tes méthodes composées de plusieurs mots , chaque mot sauf le premier commence par une majuscule, par exemple $maVariable, ça donnerait quelque chose comme ceci :
<?php class maClasse { private $_uneProprietePrivee; protected $_uneProprieteProtégée public $uneProprietePublique; private function _uneMethodePrivee(){} protected function _uneMethodeProtegee(){} public function uneMethodePublique(){} }
Donc très schématiquement, tu pourrais avoir une structure de classes ressemblant à ceci :
<?php
class artisteMdl
{
public function getArtiste($idArtiste)
{
$aInfosArtiste = array();
// ... code de ollecte des données.
return $aInfosArtiste;
}
}
class artisteVue
{
private $_sTitre;
public function __construct()
{
$this->_sTitre = "Artiste";
}
public function generer($aInfosArtiste)
{
//... code de construction de la page
}
}
class artisteCtrl
{
/**
* var artisteMdl
*/
private $_oArtisteMdl;
/**
* var artisteVue
*/
private $_oArtisteVue;
/**
* Le constructeur : définit un certain nombre des propriétés de la classe.
* Définit en particulier ici les objets qui seront alors accessible dans les méthodes.
*/
public function __construct()
{
$this->_oArtisteMdl = new artisteMdl();
$this->_oArtisteVue = new artisteVue();
}
/**
* Affichage de la page d'un artiste donné
* @param Int @idArtiste Entier identifiant un artiste.
*/
public function afficherPageArtiste($idArtiste)
{
$aInfosArtiste = $this->_oArtisteMdl->getArtiste($idArtiste);
$this->_oArtisteVue->generer($aInfosArtiste);
}
}
Bonjour.
Au final, le procédural est nettement plus simple.
Les histoires de MVC et d'Orienté Objet, c'est vraiment réservé
à un cercle fermé d'individus et c'est la multiplication
inutile de codes. Je dirais que ce n'est qu'une mode
en programmation.
Salut Dancom,
je devine derrière ces affirmations une frustration certaine devant des choses complexes et difficiles à appréhender.
La POO n'a strictement rien d'une mode, c'est une méthode de travail, une manière de programmer et d'organiser son code. Ça ne signifie pas pour autant que ça soit facile à apprendre, loin s'en faut. Néanmoins, c'est précisément fait pour éviter ce que tu reproches : la duplication de code. On ne doit justement pas dupliquer quoi que ce soit. En revanche, il faut découper le code en le répartissant en entités autonomes beaucoup plus petites et réutilisables dans différents endroits d'une même application. On construit ensuite des assemblages et donc on doit organiser soigneusement l'architecture de l'ensemble, ce qui est au moins aussi important que la manière de coder en elle-même.
Attention aussi à un autre aspect que tu as plus que probablement très largement sous-estimé : l'importance de maîtriser les concepts de POO avant de t'attaquer aux Designs Patterns en général et au MVC en particulier.
C'est de toutes façons un apprentissage ardu, et je suis moi-même tout à fait bien placé pour en parler, d'autant plus que je suis autodidacte. Et pourtant, je programme en objet tous les jours. Revenir au procédural serait pour moi tout à fait contre-productif, peut-être même pire que ça.
Et je t'accorde quand même que, lorsqu'on apprend, le procédural apparait comme beaucoup plus facile et rapide. Par ailleurs, les bon tutos pour aborder la POO sont très rares. Peut-être que je pourrai un de ces jours me lancer dans la création d'un tuto complet, mais il va falloir du temps, d'abord pour en concevoir le cheminement, ensuite en décortiquant soigneusement chaque élément, puis en avançant pas à pas en montrant et surtout en faisant bien comprendre comment on améliore l'efficacité d'un code en passant progressivement du procédural à l'objet.
Et en attendant, rien ne t'empêche de coder en utilisant certaines classes, même si le code principal de tes applications est en procédural, une classe pour se connecter à une base de données ou encore pour générer un PDF ou bien pour gérer des uploads de fichiers sera quand même beaucoup plus pratique que de devoir tout recoder à chaque fois en procédural, même si c'est parfaitement possible.