Fatal error: Cannot use object of type search as array in /home/... [Résolu]

Signaler
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
-
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
-
Bonjour! Première fois que je poste une question...
Je débute en POO et tente de passer une fonction de recherche dans une classe avant de la développer d'avantage et pouvoir l'utiliser ailleurs (le but de l'objet non?)
J'ai cherché la réponse à mon problème en vain...

Voici ma "classe".. (ma première, soyez indulgents )

<?php

require('fonctions_gepo.php');

class search

{

   var $MotifSearch;

   var $IfSearch=0;

   var $VewType;

   var $word_sound;

   var $meta=array();

   function find($MotifSearch)

   {

      connect();

      $sql = "SHOW TABLES";

      $tables = mysql_query($sql);

      if (!$tables)

      {

     echo "Erreur DB, impossible de lister les tables\n";

     echo 'Erreur MySQL : ' . mysql_error();

     exit;

      }

      $i=0;;$f=0;

      while ($table_name = mysql_fetch_row($tables))

      {

     $req_fields_name="select * from ".$table_name[0];

     $result_fields_name[$i]=mysql_query($req_fields_name);    

     for ($for=0;$for<mysql_num_fields($result_fields_name[$i]);$for++)

     {

        $meta = mysql_fetch_field($result_fields_name[$i], $for);            

        if ((!strpos($meta->name, "id_"))&& ($meta->table!="admin")     &&($meta->type=="blob")||($meta->type=="string")||($meta->type=="timestamp"))

        {

           $word_sound = soundex($MotifSearch);

           $req_r_find="select ".$meta->name.",id_".$meta->table." from ".$meta->table." where ".$meta->name." like '%".$MotifSearch."%' or soundex($meta->name) = '" . $word_sound . "'";

           $res_req_r_find=mysql_query($req_r_find);

           if (!empty($res_req_r_find))

           {

          while ($ligne_req_r_find = mysql_fetch_array($res_req_r_find))

            {

             $result_find[$f][0]=$ligne_req_r_find[$meta->name];

             $result_find[$f][1]=$meta->name;

             $result_find[$f][2]=$meta->table;

             $result_find[$f][3]=$ligne_req_r_find["id_".$meta->table];

             if ($meta->table=="contact") $result_find[$f][4]="details_contact";

             if (($meta->table=="client")||($meta->table=="fournisseur"))

             $result_find[$f][4]="details";

             if ($meta->table=="dd") $result_find[$f][4]="details_dd";

             $f++;

          }

            }

           }    

        }

        $i++;

     }

     return($result_find);

      }

   }

?>

et dans mon script :

$result_find = new search;
$result_find->find($_POST['mcle']);

count($result_find) me donne 1...
et Fatal error: Cannot use object of type search as array in /home/...

Je pense que le soucis vient de $meta->... mais je ne vois pas pourquoi... bein oui, débutant... Merci de vos lumières...
A voir également:

20 réponses

Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Tu fais des erreurs de débutant :
for ($t=0;$t<count($this->ResultFind);$t++)
On ne met jamais de fonction dans l'argument central d'une boucle for(), car celui-ci est évalué à chaque tour de la boucle. Et ça ne sert à rien dans la plupart des cas.
Tu dois assigner le résultat du count() dans une variable, avant ta boucle, ou dans le for() mais d'une manière bien précise :
$iCount = count($aTableau);
for($iCpt = 0; $iCpt < $iCount; $iCpt++)
oufor($iCpt 0, $iCount count($aTableau); $iCpt < $iCount; $iCpt++)
C'est valable pour d'autres boucles de ton code.

Selon moi, et hors contexte, ton objet est trop spécifique à ton applicatif.

On ne fait pas d'exit brutal dans un objet. Bon tu es en PHP4...donc tu ne peux pas utiliser les exceptions, mais générer des erreurs utilisateur et utiliser un gestionnaire d'erreur serait une bien meilleure idée.

Quand tu es certain du type des variables comparées, utilises la comparaison stricte === ou !==, au lieu des habituels == ou !=

Je n'aime pas ta façon de présenter le code...tous mes blocs sont encapsulés entre des accolades : même pour une condition if() ne contenant qu'une seule ligne.

Ton objet utilise les sessions...tu devrais vérifier qu'elles sont bien déclarées avant de les utiliser : la session est-elle démarrée, et quand tu utilises unevariable de session spécifique, vérifie qu'elle existe.
C'est valable pour toute variable.

Mais bon...globalement, j'ai vu pire :-) C'est pas mal pour un début.
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
Désolé pour la mise en page...
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
up!
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
bon, personne...

Je test et cherche toujours...
Si je remplace $meta->table par $meta['table'] (il me semble que le problème vient de là...) J'obtiens :

Fatal error: Cannot use object of type stdClass as array in /...

Pas d'idée? J'ai rien compris aux classes???
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Hello,

tu sais, si tu acceptes tes messages comme des réponses validés, ton post passe en "résolu", et donc personne ne vient le voir...j'ai donc retiré tes "réponses acceptées".

Le message d'erreur est clair : count() est une fonction qui attend un tableau (type array donc), et tu lui passes un objet. Donc, ça plante.
Tu peux utiliser les itérateurs, mais si tu débutes...tu vas galérer.
Ou créer une méthode search::count() qui te renverra le résultat désiré, tout simplement. Et tu l'appeleras ainsi :
$iCount = $monInstanceDeSearch->count();
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
Merci malalam de te préoccuper de mon cas!
Désolé pour le "réponse acceptée", c'est la première fois que je post sur un forum...
J'ai trouvé la réponse à ce problème depuis.
ça me fait plaisir que ce soit toi qui me réponde, je vois ton niveau et suis honoré que tu te penches sur mon cas!

J'ai un nouveau soucis depuis...
Je vais mettre tout mon code pour que tu puisses comprendre et m'éclairer sur la manière de coder ma classe. Je crée cette classe pour apprendre et maîtriser la POO, je suis autodidacte.

J'ai fini, a force de recherche et de réflexions à faire tourner mon objet, j'essaie de l'améliorer en lui donnant la possibilité de trier par champs son résultat.
Là, je rame pour le tri...Pendant toute une journée, j'ai cherché à utiliser "array_multisort" en vain... et mon problème de session... ou utiliser serialize...
Bref, je rame...

Voici mon code:
la classe:
<?php
require('fonctions_gepo.php');
session_start();
class search
{
    var $ResultFind=array();
    var $ResultFindTot=array();
    var $Mcle;

function find($MotifSearch)
{
    connect();
    $sql = "SHOW TABLES";
    $tables = mysql_query($sql);
    if (!$tables)
    {
        echo "Erreur DB, impossible de lister les tables\n";
        echo 'Erreur MySQL : ' . mysql_error();
        exit;
    }
    $i=0;;$f=0;
    while ($table_name = mysql_fetch_row($tables))
    {
        $req_fields_name="select * from ".$table_name[0];
        $result_fields_name[$i]=mysql_query($req_fields_name);   
        for ($for=0;$for<mysql_num_fields($result_fields_name[$i]);$for++)
        {
            $meta = mysql_fetch_field($result_fields_name[$i], $for);
       if ((!strpos($meta->name, "id_")) && ($meta->table!="admin")     &&(($meta->type=="blob")||($meta->type=="string")||($meta->type=="timestamp")))
            {
                $WordSound = soundex($MotifSearch);
                $req_r_find = "select ".$meta->name.",id_".$meta->table;
                   if (($meta->name != "nom_".$meta->table)&&($meta->table!="msg"))
                  $req_r_find .= " ,nom_".$meta->table;                $req_r_find ." from ".$meta->table." where ".$meta->name." like '%".$MotifSearch."%' or soundex($meta->name) '" . $WordSound . "'";
                $res_req_r_find=mysql_query($req_r_find);
                if (!empty($res_req_r_find))
                {
                    while ($ligne_req_r_find = mysql_fetch_array($res_req_r_find))
                    {
                        $this->ResultFind[$f]['val']=stripslashes($ligne_req_r_find[$meta->name]);
                        $this->ResultFind[$f]['nom']=stripslashes($ligne_req_r_find["nom_".$meta->table]);
                        $this->ResultFind[$f]['field']=$meta->name;
                        $this->ResultFind[$f]['table']=$meta->table;
                        $this->ResultFind[$f]['id']=$ligne_req_r_find["id_".$meta->table];
                        if ($meta->table=="contact") $this->ResultFind[$f]['type']="details_contact";
                        if (($meta->table=="client")||($meta->table=="fournisseur"))
                        $this->ResultFind[$f]['type']="details";
                        if ($meta->table=="dd") $this->ResultFind[$f]['type']="details_dd";
                        $f++;
                    }
                }
            }   
        }
        $i++;
    }
    close_db();
    $this->Mcle=$MotifSearch;
    $_SESSION['Mcle']=$this->Mcle;
    return($this->ResultFind);
}

function tri($ActArg) {
    $this->ResultFindTot=$_SESSION['ResultFind'];
    $this->ResultFind=$_SESSION['ResultFind'];
    $ResultFindTemp=array();
    $temp=0;
     for ($t=0;$t<count($this->ResultFind);$t++)
    {
        if ($this->ResultFind[$t]['table']==$ActArg)
        {
            $ResultFindTemp[$temp]=$this->ResultFind[$t];
            $temp++;
        }
    }
    $this->ResultFind=$ResultFindTemp;
    return($this->ResultFind);
}

function order($ActArg) {
    $this->ResultFindTot=$_SESSION['ResultFind'];
    $this->ResultFind=$_SESSION['ResultFind'];
    $ResultFindTemp=array_multisort($this->ResultFind[0], SORT_STRING, SORT_ASC);
// var_dump($this->ResultFind);
    $this->ResultFind=$ResultFindTemp;
      return ($this->ResultFind);
}
}

et ou je l'utilise :

$FindObject = new search();
if (empty($_GET['ObAct']))
{
    $FindObject->find($_POST['mcle']);
    $_SESSION['ResultFind'] = $FindObject->ResultFind;
}
else if ($_GET['ObAct']=="tri")
{
    $FindObject->tri($_GET['ArgAct']);
}

else if ($_GET['ObAct']=="order")
{
    $FindObject->order($_GET['ArgAct']);
//    print_r($FindObject->ResultFind);
}
echo "Trouv&eacute; : ResultFind[$a]['type'].".php?id=".$FindObject->ResultFind[$a]['id']."&type=".$FindObject->ResultFind[$a]['table'].""> ".$FindObject->ResultFind[$a]['val']."\n";
    echo "dans le champs ".$FindObject->ResultFind[$a]['field']."\n";...
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Prends les problèmes un après l'autre.
Le tri d'abord : donne moi un exemple de tableau (fait un var_dump mis en forme et copie le ici), et le tri que tu veux obtenir.
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
bonjour! :)

le var_dump() avec test comme MotifSearch et ->tri:


array(3) {
[0]=>
array(6)
{
["id"]=>
string(1) "1"
["nom"]=>
string(7) "Boulard"
["val"]=>
string(63) "Description du projet...
C'est le test de ma demande de devis!"
["table"]=>
string(2) "dd"
["type"]=>
string(10) "details_dd"
["field"]=>
string(21) "projet_description_dd"
}

[1]=>
array(6) 
{
["val"]=>
string(4) "test"
["nom"]=>
string(9) "Lucarelli"
["field"]=>
string(21) "projet_description_dd"
["table"]=>
string(2) "dd"
["id"]=>
string(1) "6"
["type"]=>
string(10) "details_dd"
}

[2]=>
array(5)
{
["val"]=>
string(198) "et encore un!!! ;)

re petit test histoire de voire les ascenseurs et le nombre de message non lu, surtout s'il met bien les s!!!
Voila voila, Je reviens à la ligne
pour voire mon foreach

Seb"
["nom"]=>
string(0) ""
["field"]=>
string(3) "msg"
["table"]=>
string(3) "msg"
["id"]=>
string(1) "6"
}
}

J'espère que c'est ce que tu attendais pour le "mis en forme"

Merci!
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
Oups, j'ai oublié...
Je veux pouvoir trier par 'nom' .
count($FindObject->ResultFind) me donne 1, même s'il y a 10 résultats, je ne comprends pas pour quoi je n'arrive plus à accéder aux valeurs alors qu'elles y sont bien! (var_dump)
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
ca va pour la mise en forme :-) Par contre, je n'ai pas compris l'ordre de tri désiré, en fonction de la recherche ?
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
(ceci dit, pour la mise en forme : tu fais un var_dump() en "texte" - ligne de commande, ou un EDI de type Zend -,  ou si tu es sur du html, tu encapsule le résultat dans une balise , en fait).
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Ah ok pour le tri, j'ai répondu en même temps que toi :-)
2mn...:-)
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Un exemple (j'ai simplifié ton tableau, mais le principe est le même) :

<?php
$aTab = array(
    0 => array(
        'nom' => 'toto', 'id' => 666
    ),
    1 => array(
        'nom' => 'lulu', 'id' => 9, 'type' => 'test'
     ),
     2 => array(
         'nom' => 'riri', 'id' => 999
     )
);

foreach($aTab as $iK => $aVals) {
    $aNoms[$iK] = $aVals['nom'];
}

array_multisort($aNoms, SORT_STRING, $aTab);
print_r($aTab);
?>
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
non, en fait ma classe à une fonction qui recherche dans toutes les tables et tous les champs d'une base de données.
Quasiment toutes les tables on un champ 'nom_nomdelatable'.
Le résultat est dans le tableau $FindObject->ResultFind
Je veux pour éviter de refaire une requête sql (peut-être à tort) pouvoir trier ce tableaux, ordonné par 'nom_nomdelatable' (alphabétique).
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Et ? Ca ne change rien à mon code, puisque $FindObject->ResultFind est un tableau multidimensionnel.
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
:-) ça marche nikel!!!
J'ai passé ma journée d'hier la dessus...
J'ai tourné autour de la solution... comme quoi, mieux vaut 1 qui sait que 10 qui cherchent...
Merci beaucoup, mais, peux tu m'expliquer ce qui n'allait pas, je ne veux me contenter d'un bout de code qui tourne mais que je ne maîtrise pas.
Et, t'en que j'y suis, quels conseils pourrais tu me donner pour optimiser tout ça, mon approche poo est elle bonne? quelles critiques pourrais tu faire sur tout ça?
Lâches toi, je suis prêt à tout entendre!
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
"Et ? Ca ne change rien à mon code, puisque $FindObject->ResultFind est un tableau multidimensionnel."
Oui! désolé, nos réponses se sont croisées!
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Heu...ce que tu as mal fait...le array_multisort était mal utilisé, en fait. Globalement ton problème était juste là.
Quant à la POO...c'est un vaste sujet!
Difficile de faire de la "vraie" POO en PHP4 de toute manière. Alors est-ce que tu l'utilises bien...ma foi...difficile à dire. Ca reste une question de philosophie. La mienne, c'est la modularité. Chaque objet est un spécialiste. Mais je peux aussi avoir des objets "moteurs" (ou "monteurs...builders" si on se base sur les design patterns). Ceci dit, globalement, utiliser de l'objet sert à avoir un code modulable, dont chaque "partie" (cela peut-être un package) est indépendante et peut-être réutilisée à volonté.  Un objet trop lié au contexte de l'applicatif est généralement une erreur...mais il y a des exceptions :-)
On ne juge pas de la capacité à coder en objets d'un développeur en ne regardant qu'un seul de ses objets, hors contexte qui plus est. J'aurais donc du mal à te répondre...désolé.
Il y a de bons codeurs ici...
Regarde les sources de Coucou747, Akhenaton, Neigedhiver, Codefalse, ... j'en oublie je suis désolé, mais il y en a pas mal mine de rien...et les miennes ;-) Ca t'aidera sans doute à mieux comprendre la POO.
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
Merci pour ton aide en tout cas, dernière question, trouves tu mon code propre? Je code depuis quelques années maintenant de manière amateur, pour le plaisir ou pour servir des passions (un sites dynamique sur la "bonne" musique par ex...), en apprenant tout seul et je n'ai jamais pu avoir d'avis ou de critique sur ma manière de coder... vaste sujet vas tu me répondre mais par ex, comment optimiser mon code ou le rendre plus "élégant"? Enfin, "$FindObject->ResultFind", je le passe en session pour garder ses valeurs en mémoire. Serialize serait il plus approprié? Au niveau des ressources etc... c'est grave? J'espère que tu comprend ma question.

P.S. J'ai déja vu tes sources, même si je ne comprends pas toujours tout, je les trouves très bien! ;)

Un grand merci encore!
Messages postés
194
Date d'inscription
lundi 16 mars 2009
Statut
Membre
Dernière intervention
17 juin 2010
4
Merci beaucoup! :)