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

sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 4 mars 2009 à 17:42 - Dernière réponse : sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention
- 7 mars 2009 à 12:12
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...
Afficher la suite 

Votre réponse

20 réponses

Meilleure réponse
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 12:08
3
Merci
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.

Merci malalam 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de malalam
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 4 mars 2009 à 17:44
0
Merci
Désolé pour la mise en page...
Commenter la réponse de sebshiva
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 5 mars 2009 à 10:03
0
Merci
up!
Commenter la réponse de sebshiva
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 5 mars 2009 à 10:13
0
Merci
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???
Commenter la réponse de sebshiva
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 6 mars 2009 à 19:15
0
Merci
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();
Commenter la réponse de malalam
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 01:28
0
Merci
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";...
Commenter la réponse de sebshiva
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 09:44
0
Merci
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.
Commenter la réponse de malalam
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 10:11
0
Merci
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!
Commenter la réponse de sebshiva
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 10:28
0
Merci
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)
Commenter la réponse de sebshiva
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 10:28
0
Merci
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 ?
Commenter la réponse de malalam
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 10:30
0
Merci
(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).
Commenter la réponse de malalam
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 10:31
0
Merci
Ah ok pour le tri, j'ai répondu en même temps que toi :-)
2mn...:-)
Commenter la réponse de malalam
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 10:39
0
Merci
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);
?>
Commenter la réponse de malalam
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 10:46
0
Merci
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).
Commenter la réponse de sebshiva
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 10:51
0
Merci
Et ? Ca ne change rien à mon code, puisque $FindObject->ResultFind est un tableau multidimensionnel.
Commenter la réponse de malalam
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 11:00
0
Merci
:-) ç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!
Commenter la réponse de sebshiva
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 11:01
0
Merci
"Et ? Ca ne change rien à mon code, puisque $FindObject->ResultFind est un tableau multidimensionnel."
Oui! désolé, nos réponses se sont croisées!
Commenter la réponse de sebshiva
malalam 10918 Messages postés lundi 24 février 2003Date d'inscription 2 mars 2010 Dernière intervention - 7 mars 2009 à 11:43
0
Merci
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.
Commenter la réponse de malalam
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 11:51
0
Merci
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!
Commenter la réponse de sebshiva
sebshiva 193 Messages postés lundi 16 mars 2009Date d'inscription 17 juin 2010 Dernière intervention - 7 mars 2009 à 12:12
0
Merci
Merci beaucoup! :)
Commenter la réponse de sebshiva

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.