【问题标题】:PHP include doesn't read changes of source filePHP include 不读取源文件的更改
【发布时间】:2014-06-06 04:34:58
【问题描述】:

我的问题(可能不会出现在您的计算机上)

我有 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. 是否有任何解决方法(而不是“sleep()”)让“包含”读取更改?

我已阅读此问题但没有找到答案:

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

【问题讨论】:

  • 我测试了你的代码。对我来说很好。我得到&lt;?php $num=4; ?&gt;,然后是4
  • 真的吗?你的 PHP 和 apache 版本是什么?我正在使用 ubuntu 14.04、apache 2.4.7 和 PHP 5.5.9-1。如果它在您的计算机上工作,这可能是操作系统问题,而不是 PHP 问题。
  • 我在 Windows 机器上。本地测试 - Apache/2.4.7 (Win32) PHP/5.5.8
  • 我怀疑你的 PHP 环境中启用了加速器/优化器/字节码缓存,它正在缓存 second.php。我建议您将数字写入一个简单的文本文件(可能是 properties 文件格式)而不是 PHP 文件。
  • 排除静默错误。而不是include 使用require。检查来自file_get/put_contents 调用的错误返回

标签: php


【解决方案1】:

您可能已经安装并启用了 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
?>

【讨论】:

  • 正是如此。非常感谢您花时间回答。也 +1
  • 我花了大约一个小时试图调试我的代码,然后我注意到文件系统 grep 和 PHP 包含之间的不一致。当我试图进入包含时,我的调试器(PHPStorm + XDebug)崩溃了我的系统(所以我不得不重新启动),这个问题已经消失了,希望能落入它周围的一些缓存包装器中。在我的情况下,由外部程序 (PHPStorm) 更改的文件已写入磁盘,但后来 PHP 没有使用 include 获取更改。以前从来没有这样的情况,为什么opcache 会失败?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多