2010-06-10 109 views
0

我正在使用cakephp 1.2,並且我有一個數組,即使該變量沒有被操縱,該數組似乎也有值更改。下面是這個代碼給我造成的麻煩。數組值意外改變

請注意 - 更新更改變量名稱對結果沒有任何影響。

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; 

}

我得到以下輸出:

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'" 
} 

的在我的數組值已經改變了,我不知道爲什麼?

有什麼建議嗎?

+2

要麼在'find'調用中修改'$ filters',要麼'pr()'函數的行爲發生變化。你能顯示'$ filters'來自哪裏,直到源代碼?如果將'$ filters'複製到其他變量名稱並執行相同的測試,會發生什麼情況? – 2010-06-10 11:16:14

+0

我添加了額外的註釋,改變變量名稱沒有什麼區別 – Lizard 2010-06-10 11:42:29

+0

'$ filters'(現在'$ myArr')是一個傳遞給這個函數的數組 – Lizard 2010-06-10 11:44:08

回答

1

可能$filters是一個參考,它正在改變方法調用或pr本身具有狀態/副作用。第二個選項可以通過刪除對pr的呼叫並將其替換爲var_dump來消除。

您的代碼段沒有提供足夠的信息。這裏最好的選擇是調試器。

編輯: 你最後的元素是一個參考(可能是一個foreach的參考剩餘)。修復構建數組的代碼,以便它不會在最後一個元素中留下引用。

+0

我添加了額外的註釋,改變變量名稱沒有區別,我有也將pr()替換爲print_r(); – Lizard 2010-06-10 11:43:08

+0

@Lizard使用「var_dump」,而不是「print_r」。無論如何,在函數中使用了什麼'$ myArr'? – Artefacto 2010-06-10 11:59:54

+0

我已經將問題更新爲FULL函數,因爲我發現了有問題的代碼行,但現在它變得更加沒有意義。 – Lizard 2010-06-10 12:01:39

1

Seems like the bug with accessing a PHP array by reference。由於PHP內部工作的特殊性,如果引用數組中的單個元素,然後複製數組,則無論是通過賦值還是通過函數調用中的值傳遞,都會複製引用作爲數組的一部分。這意味着即使數組有不同的作用域(例如一個是函數內部的一個參數,另一個是全局的),對任何一個數組中的任何這樣的元素的更改都將被複制到另一個數組中(以及其他引用中)!在複製時沒有引用的元素,以及在數組副本之後分配給這些其他元素的引用將正常運行(即獨立於其他數組)。

這不會很快被修復。這是一個深層次的問題,在執行和修復它會導致速度問題和許多其他問題,這是可以編碼的東西,所以不應該導致大量問題。

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

+0

我會稱之爲「預期的行爲」,而不是一個錯誤。如果一個數組有一個引用,我複製它,爲什麼我會期望引用不再是一個引用?似乎是任意的,不利的一點是否則將需要複製元素而不是僅增加其引用計數。 – Artefacto 2010-06-10 12:48:40

+0

哦,這是一個錯誤和一個非常深刻的。我已經在PHP.net上發現至少5個錯誤報告,並且他們都被公認爲是這樣。這只是修復這將意味着重寫PHP的核心大塊,並會改變太多東西到處都是這個「麻煩」(誰可以很容易地避免)。底線:不要在數組上使用引用。如果您仍然認爲這不是一個錯誤,請仔細閱讀我答案的第一個鏈接中的文章。之後,如果你仍然認爲這是「正常行爲」,我爲你感到高興:) – AlexV 2010-06-10 13:09:43

+0

好吧,我在想你明確地向數組添加引用的情況,但正如文章指出的那樣,引用標誌是還可以在創建數組元素的引用時進行設置。好吧,這當然不是很正常,但是一旦你瞭解瞭如何在PHP中實現引用,這就是你所期望的(即無法區分引用是如何創建的,即什麼是原始符號)。 – Artefacto 2010-06-10 14:18:18