2010-06-10 12 views
0

J'utilise cakephp 1.2 et j'ai un tableau qui semble avoir une valeur de changement même si cette variable n'est pas manipulée. Voici le code qui me cause des problèmes.Les valeurs de tableau changent de façon inattendue

VEUILLEZ NOTER - MISE À JOUR La modification du nom de la variable ne change rien au résultat.

function findCountByString($string, $myArr=array()) { 

$main_conditions['or'] = array(); 
$main_conditions['or']['Article.title LIKE '] = '%'.$string.'%'; 
$main_conditions['or']['Article.html_content LIKE '] = '%'.$string.'%'; 
$conditions['and'][] = $main_conditions; 
$filter_conditions['or'] = array(); 
if(count($myArr) > 0) { 
    # UPDATE NUMBER 2 
    # if I comment out the below line everything is fine, this makes no sense!!! 
    $filter_conditions['or']['ArticleEntity.entity_id'] = $myArr; 
    $conditions['and'][] = $filter_conditions; 
} 

echo "Start of findCountByString()"; 
var_dump($myArr); 

$test = $this->find('count', array(
    'conditions' => $conditions, 
    'joins' => array('LEFT JOIN `articles_entities` AS ArticleEntity ON `ArticleEntity`.`article_id` = `Article`.`id`'), 
    'group' => 'Article.id' 
    )); 

echo "End of findCountByString()"; 
var_dump($myArr); 

return $test; 

}

Je reçois la sortie suivante:

Start of findCountByString() 

array(4) { 
    [0]=> 
    string(36) "4bdb1d96-c680-4c2c-aae7-104c39d70629" 
    [1]=> 
    string(36) "4bdb1d6a-9e38-479d-9ad4-105c39d70629" 
    [2]=> 
    string(36) "4bdb1b55-35f0-4d22-ab38-104e39d70629" 
    [3]=> 
    &string(36) "4bdb25f4-34d4-46ea-bcb6-104f39d70629" 
} 

End of findCountByString() 

array(4) { 
    [0]=> 
    string(36) "4bdb1d96-c680-4c2c-aae7-104c39d70629" 
    [1]=> 
    string(36) "4bdb1d6a-9e38-479d-9ad4-105c39d70629" 
    [2]=> 
    string(36) "4bdb1b55-35f0-4d22-ab38-104e39d70629" 
    [3]=> 
    &string(38) "'4bdb25f4-34d4-46ea-bcb6-104f39d70629'" 
} 

L'ont changé la valeur dans mon tableau, et je ne sais pas pourquoi?

Des suggestions?

+2

Soit il y a une référence à '$ filters' quelque part qui est modifiée dans l'appel' find', soit le comportement de la fonction 'pr()' change. Pouvez-vous montrer d'où proviennent les '$ filters ', jusqu'à la source? Que se passe-t-il si vous copiez '$ filters' avec un autre nom de variable et que vous faites le même test? –

+0

J'ai ajouté des notes supplémentaires, changer le nom de la variable ne fait aucune différence – Lizard

+0

'$ filters' (Maintenant' $ myArr') est un tableau passé à cette fonction – Lizard

Répondre

1

Probablement $filters est une référence et il est en cours de modification dans l'appel de méthode ou pr lui-même a des effets d'état/secondaires. La deuxième option peut être éliminée en supprimant les appels au pr et en le remplaçant par var_dump.

Votre extrait de code ne fournit pas d'informations suffisantes. Votre meilleure option ici est un débogueur.

EDIT: Votre dernier élément est une référence (probablement un vestige d'un foreach par référence). Corrigez le code qui construit le tableau afin qu'il ne laisse pas de référence dans le dernier élément.

+0

J'ai ajouté des notes supplémentaires, en changeant le nom de la variable ne fait aucune différence, j'ai a également remplacé pr() par print_r(); – Lizard

+0

@Lizard utilise "var_dump", pas "print_r". Qu'est-ce que '$ myArr' est utilisé dans la fonction, de toute façon? – Artefacto

+0

J'ai mis à jour la question à la fonction FULL, car j'ai trouvé la ligne de code qui est en faute, mais cela a encore moins de sens maintenant. – Lizard

1

Seems like the bug with accessing a PHP array by reference. En raison des particularités du fonctionnement interne de PHP, si une référence est faite à un seul élément d'un tableau et que le tableau est copié, que ce soit par affectation ou lorsqu'il est passé par valeur dans un appel de fonction, la référence est copiée dans le cadre du tableau. Cela signifie que les modifications de ces éléments dans les deux tableaux seront dupliquées dans l'autre tableau (et dans les autres références), même si les tableaux ont des portées différentes (par exemple, un est un argument dans une fonction et l'autre global)! Les éléments qui n'ont pas de références au moment de la copie, ainsi que les références attribuées à ces autres éléments après la copie du tableau, se comporteront normalement (c'est-à-dire indépendamment de l'autre tableau).

Ce ne sera pas réparé pour bientôt. C'est un problème posé en profondeur dans la mise en œuvre et la fixation entraînerait des problèmes de vitesse et de nombreux autres problèmes, c'est quelque chose qui peut être codé autour ainsi ne devrait pas causer de problèmes massifs.

http://bugs.php.net/bug.php?id=8130.

+0

Je l'appellerais "comportement prévu", pas un bug. Si un tableau a une référence et que je la copie, pourquoi devrais-je m'attendre à ce que la référence cesse d'en être une? Cela semble arbitraire, avec l'inconvénient que faire autrement impliquerait de copier l'élément au lieu d'incrémenter simplement son nombre de références. – Artefacto

+0

Ohh c'est un bug et un très profond. J'ai trouvé au moins 5 rapport de bug sur PHP.net et ils ont tous été reconnus comme tels. C'est juste que corriger cela signifierait réécrire un gros morceau du noyau de PHP et changerait trop de choses pour ce "problème" (qui peut être évité assez facilement). Bottom line: n'utilisez pas de références sur les tableaux. Si vous pensez toujours que ce n'est pas un bug, lisez attentivement l'article dans le premier lien de ma réponse. Après cela, si vous pensez toujours que c'est "comportement normal", je suis heureux pour vous :) – AlexV

+0

OK, je pensais au cas où vous avez explicitement ajouté une référence à un tableau, mais, comme le souligne l'article, le drapeau de référence est définir également lors de la création d'une référence à partir d'un élément de tableau. Eh bien, ce n'est certainement pas normal, mais une fois que vous comprenez comment les références sont implémentées en PHP, c'est ce à quoi vous vous attendez (il n'y a aucun moyen de distinguer comment la référence a été créée). – Artefacto