IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Fonctions récursives et out of memory


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2002
    Messages : 329
    Points : 139
    Points
    139
    Par défaut Fonctions récursives et out of memory
    Bonjour,

    Le code suivant permet d'appliquer des fonctions php aux variables de sessions à l'apparition de chaque nouvelle page.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     function array_map_recursive($func, $arr)
     {
     	
     	if(is_array($arr))
     	{
     		$result=array();
     		do{
     			$key=key($arr);
     			if(is_array(current($arr)))
     			{
     				$result[$key]=array_map_recursive($func,$arr[$key]);
     			}
     			else
     			{
     				$result[$key]=$func(current($arr));
     			}
     		}while(next($arr)!==false);
     		return $result;
     	}
     	else
     	{
     		return $func($arr);
     	}
     }
     
     
    $fonctions_entrantes=array("addslashes", "htmlentities");
    $fonctions_sortantes=array("stripslashes");
    
    //Traitement des $_SESSION
    if(isset($_SESSION))
    {
      	foreach($fonctions_entrantes as $fct_in)
     	{
     		$_SESSION=array_map_recursive($fct_in,$_SESSION);
     	}
    }
    Au début, tout fonctionne correctement mais à partir d'un certain nombre de page ouverte. L'erreur Out of Memory sur la ligne en rouge apparait.

    Je ne comprends pas pourquoi !!
    Quelqu'un a-t-il une explication ?
    Merci

  2. #2
    Membre éprouvé Avatar de vorace
    Homme Profil pro
    Développeur
    Inscrit en
    Août 2010
    Messages
    573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Août 2010
    Messages : 573
    Points : 915
    Points
    915
    Par défaut
    peut-être parce qu'une fonction récursive est très gourmande en ressource mémoire...
    Le code suivant permet d'appliquer des fonctions php aux variables de sessions à l'apparition de chaque nouvelle page
    si c'est des variables de sessions tu n'as pas besoin de leur refaire ce traitement à chaque 'apparition' d'une page...et si dans cette nouvelle page y a création de nouvelle variable de session : c'est à ce niveau que tu fais ton traitement (et qu'une fois).

  3. #3
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2002
    Messages : 329
    Points : 139
    Points
    139
    Par défaut
    Bonjour,

    peut-être parce qu'une fonction récursive est très gourmande en ressource mémoire...
    J'imagine parfaitement que la fonction est consommatrice de mémoire mais de là, à saturer l'ensemble des capacités de l'ordi, je suis fort surpris d'autant plus que je dois avoir qu'une vingtaine au mieux de variables de sessions.

    si c'est des variables de sessions tu n'as pas besoin de leur refaire ce traitement à chaque 'apparition' d'une page...et si dans cette nouvelle page y a création de nouvelle variable de session : c'est à ce niveau que tu fais ton traitement (et qu'une fois).
    Je suis tout à fait d'accord. Cependant, mes variables de sessions sont créées et complétées au moment de la construction des pages. Et en fonction des pages, les sessions varient donc je vois difficilement la possibilité de controler un unique traitement. Je désirai faire un traitement de masse !!!!

    Ou alors une autre solution serait de vérifier que la routine sur addslashes ne s'exécute que si \ n'est pas présent, via un controle par expression régulière .

    C'est une réflexion.

    Je suis toujours preneur d'avis !
    merci

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    J'ai testé ta fonction, et je ne sais comment me suis retrouvé 2 fois avec des &amp et lt ,qui se reproduisent à l'infini et je n'arrive pas à reproduire cette faille..


    Cela vient peu être d'un conflit entre les deux fonctions dans la boucle, pas le temps pour une d'avoir achevé son boulot, mais cela me paraît étrange.


    regarde du coté de http://php.net/manual/fr/function.ar...-recursive.php pour ma part je trouve celle-ci très utile

  5. #5
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2002
    Messages : 329
    Points : 139
    Points
    139
    Par défaut
    Bonjour,

    je veux bien tenter array_walk_recursive mais je ne suis pas sur de bien comprendre son fonctionnement dans mon cas.
    je vais creuser
    merci

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    donne nous un tableau exemple d'une session en entrée et en sortie à ce moment là, moi j'ai compris que tu ne t'occupais que du dernier segment du tableau...

  7. #7
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2002
    Messages : 329
    Points : 139
    Points
    139
    Par défaut
    non, non je m'occupe de tous les segments !

    je te mets un exemple.

  8. #8
    Membre éprouvé Avatar de vorace
    Homme Profil pro
    Développeur
    Inscrit en
    Août 2010
    Messages
    573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Août 2010
    Messages : 573
    Points : 915
    Points
    915
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function clean($variable){
    return addslashes(htmlentities($variable));
    }
    le voila ton traitement de masse, à chaque fois que tu crées une variable de session tu lui appliques cette fonction,...
    Je suis tout à fait d'accord. Cependant, mes variables de sessions sont créées et complétées au moment de la construction des pages. Et en fonction des pages, les sessions varient donc je vois difficilement la possibilité de controler un unique traitement. Je désirai faire un traitement de masse !!!!
    Je ne vois vraiment pas : on à l'impression que tes pages donnent naissance à d'autres pages après que tu les ai codé et sans que tu puisse le contrôler...tu fais une IA ?

  9. #9
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Bonsoir,

    Je ferais la même remarque que vorace, je ne comprend pas tout. M'enfin comme dirait un personnage célèbre.
    Dans tous les cas voici comment faire pour ne pas avoir à s'occuper de la récursivité, PHP 5.3+ bien évidemment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
     
    $addslashes   = function(&$v, $k) { $v = addslashes($v); };
    $htmlentities = function(&$v, $k) { $v = htmlentities($v, ENT_QUOTES); };
     
    $fonctions_entrantes = array($addslashes, $htmlentities);
     
    if (isset($_SESSION)) {
         foreach($fonctions_entrantes as $fct_in) {
           array_walk_recursive($_SESSION, $fct_in);
        }
    }
     
    ?>

  10. #10
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2002
    Messages : 329
    Points : 139
    Points
    139
    Par défaut
    Et voilà ! ca ne fonctionne pas !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function addslach(&$item)
    	{
    		$item=addslashes($item);
    	}
     
     
    	$liste = array("a", "sfds'sdf", "rree'  eeer' efqsd");
    	$liste2=array($liste, "ee're", "ttt'lkk");
     
    	echo "<pre>";
    	print_r($liste2);
    	echo "</pre>";
    	array_walk_recursive($liste2, "addslach");
     
    	echo "<pre>";
    	print_r($liste2);
    	echo "</pre>";

  11. #11
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    c cado :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function Rec_json_encode_parse_Array_recursive(&$item, $key)
    {
            if (is_string($item)) {$item = mb_encode_numericentity($item, array (0x80, 0xffff, 0, 0xffff), 'UTF-8');}
    }
     
     
    function json_encode_parse_Array_recursive($arr)
    {
             //convmap since 0x80 char codes so it takes all multibyte codes (above ASCII 127). So such characters are being "hidden" from normal json_encoding
            array_walk_recursive($arr,"Rec_json_encode_parse_Array_recursive");
            return mb_decode_numericentity(json_encode($arr), array (0x80, 0xffff, 0, 0xffff), 'UTF-8');
     
    }

    moi je m'en sert pour transferer des donnée AJAX, qui modifie tous les segments

  12. #12
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    J'ai oublié de préciser qu'il était possible de faire encore plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
     
    $filter = function(&$v, $k) {
       $v = addslashes($v);
       $v = htmlentities($v, ENT_QUOTES);
    };
    if (isset($_SESSION)) {
       array_walk_recursive($_SESSION, $filter);
    }
     
    ?>

  13. #13
    Membre éprouvé Avatar de vorace
    Homme Profil pro
    Développeur
    Inscrit en
    Août 2010
    Messages
    573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Août 2010
    Messages : 573
    Points : 915
    Points
    915
    Par défaut
    Citation Envoyé par bastien Voir le message
    Et voilà ! ca ne fonctionne pas !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function addslach(&$item)
    	{
    		$item=addslashes($item);
    	}
     
     
    	$liste = array("a", "sfds'sdf", "rree'  eeer' efqsd");
    	$liste2=array($liste, "ee're", "ttt'lkk");
     
    	echo "<pre>";
    	print_r($liste2);
    	echo "</pre>";
    	array_walk_recursive($liste2, "addslach");
     
    	echo "<pre>";
    	print_r($liste2);
    	echo "</pre>";
    la réponse peut-être :
    Dans tous les cas voici comment faire pour ne pas avoir à s'occuper de la récursivité, PHP 5.3+ bien évidemment :
    chez moi ton code marche...

  14. #14
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    J'ai oublié de préciser qu'il était possible de faire encore plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
     
    $filter = function(&$v, $k) {
       $v = addslashes($v);
       $v = htmlentities($v, ENT_QUOTES);
    };
    if (isset($_SESSION)) {
       array_walk_recursive($_SESSION, $filter);
    }
     
    ?>
    je test pas ce soir, mais j'aime +1

  15. #15
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2002
    Messages : 329
    Points : 139
    Points
    139
    Par défaut
    Je vous remercie.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction récursive renvoi sur page d'erreur
    Par peck dans le forum Langage
    Réponses: 1
    Dernier message: 23/12/2005, 10h08
  2. Problème de fonction récursive avec un TcxDBTreeList
    Par isachat666 dans le forum Composants VCL
    Réponses: 1
    Dernier message: 05/12/2005, 13h12
  3. [pb mémoire] out of memory d'eclipse
    Par Casp dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 12/05/2005, 16h39
  4. Out of memory
    Par shurato dans le forum ANT
    Réponses: 1
    Dernier message: 10/11/2004, 16h19
  5. [JBuilder 8] Out of memory problem ...
    Par keros dans le forum JBuilder
    Réponses: 2
    Dernier message: 08/09/2003, 19h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo