2014-06-06 59 views
2

我的問題的變化(可能不會出現在您的計算機)PHP包括不讀取源文件

我有2個PHP腳本。

讀取的第一個腳本包含第二個腳本以獲取變量,更改該值並執行file_put_contents以更改第二個腳本。

<?php 
include('second.php'); // in second.php, $num defined as "1" 
$num ++;    // now $num should be "2" 
// Change content of second.php 
file_put_contents('second.php', '<?php $num='.$num.'; ?>'); 
include('second.php'); // Now here is the problem, $num's value is still "1" 
echo $num;    // and I get an unexpected result "1" 
?> 

第二個腳本只包含一個變量

<?php $num=1; ?> 

我希望得到的結果是「2」,但似乎第二個包括不讀取file_put_contents所做的更改。

我的第一個猜測是file_put_contents函數中可能存在併發問題,因此第二個文件在第二個包含執行時沒有真正改變。

我試圖通過改變第一腳本到這個測試我的猜測:

<?php 
include('second.php'); 
$num ++; 
file_put_contents('second.php', '<?php $num='.$num.'; ?>'); 
// show the contains of second.php 
echo '<pre>' . str_replace(array('<','>'), array('&lt;', '&gt;'), 
    file_get_contents('second.php')) . '</pre>'; 
include('second.php'); 
echo $num; 
?> 

我真的很驚訝地發現,該程序的結果是這樣的:

<?php $num=4; ?> 
3 

這意味着, file_put_contents正確地讀取文件(換句話說,文件實際上已經被物理地改變),但是「include」仍然使用第一個值。

我的問題

  1. 任何人都可以解釋一下嗎?
  2. 是否有任何解決方法(而不是「睡眠()」)使「包含」讀取更改?

我已經閱讀了這個問題,並沒有發現答案:

Dynamically changed files in PHP. Changes sometimes are not visible in include(), ftp_put()

暫時的解決辦法

使用eval似乎是臨時的解決辦法。這並不優雅,因爲eval通常與安全漏洞相關聯。

<?php 
require('second.php'); 
$num ++; 
file_put_contents('second.php', '<?php $num='.$num.'; ?>'); 
echo '<pre>' . str_replace(array('<','>'), array('&lt;', '&gt;'), file_get_contents('second.php')) . '</pre>'; 
require('file.php'); 
echo $num . '<br />'; 
eval(str_replace(array('<?php','?>'), array('', ''), file_get_contents('second.php'))); 
echo $num; 
?> 

這是結果:

<?php $num=10; ?> 
9 
10 
+3

我測試你的代碼。對我來說工作得很好。我得到了<?php $ num = 4; ?>'後面跟着'4'。 –

+0

真的嗎?什麼是你的PHP和Apache版本?我正在使用Ubuntu 14.04,apache 2.4.7和PHP 5.5.9-1。如果它在你的計算機上工作,這可能是操作系統問題,而不是PHP問題。 – goFrendiAsgard

+0

我在一臺Windows機器上。本地測試 - Apache/2.4.7(Win32)PHP/5.5.8 –

回答

3

也許你已經安裝OPcache並啓用(由於Php 5.5: OPcache extension added),你的緩存文件second.php

查看phpinfo()是否屬實。

如果是這樣,請使用opcache_invalidate('second.php')使緩存的文件無效或使用opcache_reset()重置所有緩存的文件。

<?php 
include('second.php'); 
$num ++; 

file_put_contents('second.php', '<?php $num='.$num.'; ?>'); 

opcache_invalidate('second.php');//Reset file cache 

include('second.php'); 
echo $num;//2 
?> 
+0

情況正是如此。非常感謝您花時間回答。也+1 – goFrendiAsgard

+0

我花了大約一個小時試圖調試我的代碼,然後我注意到文件系統grep和PHP包含之間的不一致。當我試圖進入include包時,我的調試器(PHPStorm + XDebug)崩潰了我的系統(所以我不得不重新啓動),問題已經消失,希望能落入它的緩存包裝中。 在我的情況下,由外部程序(PHPStorm)更改的文件被寫入磁盤,但後來在PHP中沒有找到include的更改。以前從未如此,爲什麼'opcache'可能會失敗? – NeverEndingQueue