Comment passer une variable a une function dans une class

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Comment passer une variable a une function dans une class

par f_trt » 03 août 2006, 17:40

Fichtre j'en apprend énormement avec vous et surtout avec du concret.

Voici ce que j'ai retenu en final :
$core->addBehavior('adminInitWidgets',array('changeMarieBehaviors','initWidgets'));

class changeMarieBehaviors
{
	// Ajout de $lesimg pour pouvoir atteindre celle-ci dans le méthode sans changer rien au niveau API
	public static $lesimg = array(); 
	public static function initWidgets(&$widgets)
	{
		$widgets->create('changeMarie',__('Change Marie (v1.0)'),array('tplChangeMarie','ChangeMarieWidget'));
		$widgets->changeMarie->setting('title',__('Title not visible with style sheet of Marie:'),'');
		$widgets->changeMarie->setting('srep',__('Name sub-folder contain picture under public example "aleatoire":'),'');
		$widgets->changeMarie->setting('imgdef',__('Image par defaut:'),'','combo',self::$lesimg);
		$widgets->changeMarie->setting('homeonly',__('Home page only'),1,'check');
	}
}

//J'utilise la class du gestionnaire multi-media
try {
	$core->media = new dcMedia($core,$type);
	//$d le sous repertoire souhaité si rien alors c'est la racine de public
	$core->media->chdir($d);
	$core->media->getDir();
	$dir =& $core->media->dir;
} catch (Exception $e) {
	$core->error->add($e->getMessage());
}

//$dir['files']; est le tableau qui contient les fichiers
$items = array_values($dir['files']);
$ft_nb= count($items);
for ( $ft_i=0; $ft_i < $ft_nb ; $ft_i++){
  //Va falloir améliorer pour tronquer les noms longs d'image cause debordement dans l'admin
  changeMarieBehaviors::$lesimg[$items[$ft_i]->relname] = $items[$ft_i]->relname;
}
Et voici ici dans l'admin de DOTCLEAR ce que cela donne ici
et ce a quoi vous aurez grandement contribué ici

A bientôt

par titerm » 03 août 2006, 17:02

Mais cela implique de penser à faire les affectations par référence
Ouais, du coup ca fais un peu bricolage (IMHO) et beaucoup de risque d'erreur par la suite, d'ou ma suggestion d'encapsuler dans un objet.

par naholyr » 03 août 2006, 16:35

// A peaufiner en gérant les doublont, etc...
class Registry {
	static private $_registry = array();

	static public function register($name, $obj)  {
        self::$_registry[$name] = $obj;
    }

    static public function registry($name)  {
        return self::$_registry[$name];
    }
}

Dans ce cas, la var étant un tableau, elle est passée par valeur a la registry, il faudra donc gérer les tableau plus finement si tu veux pouvoir les modifier, ou plus simplement, les encapsuler dans un objet qui lui ne circule que par référence en php5.
Ou forcer le passage par référence :
class Registry {
	static private $_registry = array();

	static public function register($name, &$obj)  {
        self::$_registry[$name] =& $obj;
    }

    // cette méthode ne peut s'appeler "registry" sinon :
    // Fatal error: Constructor Registry::registry() cannot be static
    static public function &retreive($name)  {
        return self::$_registry[$name];
    }
}
Mais cela implique de penser à faire les affectations par référence
$mavar = array(1);
Registry::register('mavar', $mavar);
$test =& Registry::retreive('mavar'); // <= ici, avec le '&'
$test[] = 2;
// $test = [ 1 , 2 ]
// $mavar = [ 1 ]
$mavar = array(1);
Registry::register('mavar', $mavar);
$test = Registry::retreive('mavar'); // <= ici, pas de '&'
$test[] = 2;
// $test = [ 1 , 2 ]
// $mavar = [ 1 ]

par titerm » 03 août 2006, 16:09

Dans la mesure du possible, il est quand meme préférable d'éviter d'avoir recour a des globales.

Si tu dois partager des données entre plusieurs objets indépendant, je te suggère de plutot exploiter le pattern registry

Ce qui donnerais un code du genre
// A peaufiner en gérant les doublont, etc...
class Registry {
	static private $_registry = array();

	static public function register($name, $obj)  {
        self::$_registry[$name] = $obj;
    }

    static public function registry($name)  {
        return self::$_registry[$name];
    }
}

Dans ce cas, la var étant un tableau, elle est passée par valeur a la registry, il faudra donc gérer les tableau plus finement si tu veux pouvoir les modifier, ou plus simplement, les encapsuler dans un objet qui lui ne circule que par référence en php5.

$tmp= array('IMG0' => 'IMG0','IMG1' => 'IMG1');
Registry::register('lesimg',$tmp);

// a partir d'ici tmp ne sert plus, donc meme si tu es dans une fonction, cela n'a pas d'incidence


$core->addBehavior('adminInitWidgets',array('changeMarieBehaviors','initWidgets'));

class changeMarieBehaviors
{
   public static function initWidgets(&$widgets)
  {
      // Recupération de la var depuis la registry
      $lesimg = Registry::registry('lesimg');
      $widgets->create('changeMarie',__('Change Marie'),array('tplChangeMarie','ChangeMarieWidget'));
      $widgets->changeMarie->setting('imgdef',__('Image par defaut:'),'','combo',$lesimg);
  }
}

par f_trt » 03 août 2006, 15:18

Grand merci naholyr pour tes explications.
Je vais faire comme tu m'as dit, par contre j'ai réussi à faire fonctionner aussi en faisant un double global pour resituer le contexte je travail a un plugin DOTCLEAR pour cela je souhaite utiliser l'API pour l'heure il y a pas encore de doc mais mon bout de code se trouve dans un fichier
_admin.php ce dernier est surement include par le moteur DC (DOTCLEAR)
Mon double global comme cela:

global $lesimg;
$lesimg = array($items[0]->relname => array('IMG0' => 'IMG0','IMG1' => 'IMG1'); 

$core->addBehavior('adminInitWidgets',array('changeMarieBehaviors','initWidgets'));

class changeMarieBehaviors
{
	public static function initWidgets(&$widgets)
	{
		global $lesimg;
		$widgets->create('changeMarie',__('Change Marie'),array('tplChangeMarie','ChangeMarieWidget'));
		$widgets->changeMarie->setting('imgdef',__('Image par defaut:'),'','combo',$lesimg);
	}
}
J'en déduis donc que _admin.php est include de façon spécial dans le reste du moteur DC.

Encore merci à tous les deux de m'avoir aidé, je regrette pas d'avoir fait mon post ici, pour info coté forum DC je n'ai pas eu de réponse encore mais c'est aussi parceque mon post se retrouve dilué la bas dans la philosophie des plugins.

par naholyr » 03 août 2006, 14:39

ça n'empêche rien
// déclaration
class MaClass
{
    public static $maVar = array();
    /* ...
    suite de la déclaration
    ... */
}

// construction de ma variable
MaClass::$maVar[] = 1;
MaClass::$maVar[] = 2;
MaClass::$maVar[] = 3;
Tu peux donc remplir ton tableau dans ton module en dehors de ta classe, en le traitant comme n'importe quelle variable globale. Ce sera juste un peu plus propre qu'une variable globale puisqu'il sera dans l'espace de nom de ta classe.

par f_trt » 03 août 2006, 13:51

Utilise les balises PHP pour encadrer du code PHP
Oui désolé.

Merci à tous les deux pour votre aide, je suis aussi allez voir le lien
http://fr3.php.net/manual/fi/language.oop5.static.php malheureusement
je n'avance pas.

La déclaration
class changeMarieBehaviors
{
   public static $lesimg = array('IMG0' => 'IMG0','IMG1' => 'IMG1'); 
ne me convient pas, j'ai pas assez precisé mon besoins, j'avais simplifié
pour essayer d'être le plus clair possible dans mon problème.
Le contenu de $lesimg est un tableau mais ce tableau est rempli en dehors de ma class changeMarieBehaviors et doit être utilisé par ou dans la méthode initWidgets.

J'ai essayé aussi global comme cela :
$lesimg = array('IMG0' => 'IMG0','IMG1' => 'IMG1');

$core->addBehavior('adminInitWidgets',array('changeMarieBehaviors','initWidgets'));
class changeMarieBehaviors
{
	public static function initWidgets(&$widgets)
	{
		global $lesimg;
		$widgets->create('changeMarie',__('Change Marie'),array('tplChangeMarie','ChangeMarieWidget'));
		$widgets->changeMarie->setting('imgdef',__('Image par defaut:'),'','combo',$lesimg);
	}
}
mais d'après ce que je comprend c'est plutôt dans l'autre sens, en fait je souhaiterai que la portée de ma variable $lesimg arrive jusque dans initWidget

par ouckileou » 03 août 2006, 13:16

Ah c'est aussi une méthode de l'API... pas compris :oops:

par naholyr » 03 août 2006, 12:06

Tu ne pourras pas, car ce n'est pas toi qui appelle ta méthode.
L'appel est géré par leur API, et ta fonction est censée prendre un unique paramètre &$widgets.

Pour accéder à $lesimg dans ta méthode, il faut que tu utilise une variable globale, ou une variable statique à ta classe :
//

$core->addBehavior('adminInitWidgets',array('changeMarieBehaviors','initWidgets'));
class changeMarieBehaviors
{
   public static $lesimg = array('IMG0' => 'IMG0','IMG1' => 'IMG1');
   public static function initWidgets(&$widgets)
  {
      $widgets->create('changeMarie',__('Change Marie'),array('tplChangeMarie','ChangeMarieWidget'));
      $widgets->changeMarie->setting('imgdef',__('Image par defaut:'),'','combo',self::$lesimg);
  }
}
Source : http://fr3.php.net/manual/fi/language.oop5.static.php

par ouckileou » 03 août 2006, 11:49

Tu passes ton tableau en paramètre de la fonction, comme tu le fais déjà avec "&$widgets" (passage par référence)

Où est le problème ?

par ouckileou » 03 août 2006, 11:47

Utilise les balises
 pour encadrer du code PHP

Comment passer une variable a une function dans une class

par f_trt » 03 août 2006, 11:21

Bonjour à tous,
newbie et pas du tout encore familié des class je suis en train de faire un plugin pour DotClear 2 je pourrai faire mon truc en PHP classique mais voilà je souhaite respecter le travail des dev de DOTCLEAR et utiliser leurs API.


Voici mon problème :
Soit la variable $lesimg contenant un tableau

Soit le code suivant (tout est dans le même script _admin.php) et tel quel:
$lesimg = array('IMG0' => 'IMG0','IMG1' => 'IMG1');

$core->addBehavior('adminInitWidgets',array('changeMarieBehaviors','initWidgets'));
class changeMarieBehaviors
{
   public static function initWidgets(&$widgets)
  {
      $widgets->create('changeMarie',__('Change Marie'),array('tplChangeMarie','ChangeMarieWidget'));
      $widgets->changeMarie->setting('imgdef',__('Image par defaut:'),'','combo',$lesimg);
  }
}
Comment passer le tableau $lesimg a la fonction initWidgets() ?

D'avance merci de m'eclairer.

Pour info j'ai aussi posté ma demande dans le forum DOTCLEAR mais comme c'est plus un problème de PHP et que le fils de discussion dans DOTCLEAR dérive vers la gestion des plugins c'est pour cela que je viens vers vous ici.