一般问题是:在PHP中取消设置该变量后,是否可以从物理内存中删除String变量的值?
问题源于安全标准的某些要求(在处理某些重要数据时,应该无法将数据从内存转储到磁盘)。根据“Is memory encrypted?”主题,没有好方法可以加密内存中的数据。
因此,当在PHP中取消设置String变量时,您无法确定内存中的数据是否被覆盖。关于为变量设置新值的相同故事。
因此,如果可以在不更改unset
方法的核心代码的情况下从内存中清除变量值,我感兴趣吗?
答案 0 :(得分:4)
首先,我不确定擦除字符串是否符合您所描述的安全要求,因为理论上仍然可以在字符串被擦除之前转储内存。但是无论如何都无法满足,因为如果不将数据存储在内存中就无法处理数据。
无论如何,如果你想确保字符串被擦除,我认为在PHP中这样做的唯一方法是遍历字符串并修改每个字符:记住,内存的内容在被覆盖之前不会消失,甚至如果你没有引用变量并且PHP已经运行了。
我相信这会奏效:
for( $i=0; $i < strlen($str); $i++ )
$str[$i] = 'x';
答案 1 :(得分:0)
使用PHP 5.6进行了一些测试:
<?php
$cc = 'AAAABBBBCCCCDDDD';
#v1: unset($cc);
#v2: $cc=null;
#v3: for( $i=0; $i < strlen($cc); $i++ ) $cc[$i] = 'x';
sleep(500); // enough time for taking script pid and run the memory dump
?>
尝试上述脚本的每个版本(启用#v1,启用#v2,启用#v3); 转储进程的内存(请参阅https://serverfault.com/a/408929/374467),并且'AAAABBBBCCCCDDDD'字符串始终显示在生成的二进制文件中(包含进程内存)。当$ cc值作为命令行参数($ argv)发送时也会进行测试。结果相同。
到目前为止,我发现在PHP中没有可靠的方法。
答案 2 :(得分:-2)
据我所知,问题不在于使用unset()
或PHP的垃圾收集器,而是确保已使用的内存实际上已清除物理级别?
简单方法 - 在取消设置之前将其设置为null (或任何其他值)请参阅What's better at freeing memory with PHP: unset() or $var = null
硬和supid方式是用垃圾分配所有php内存,以确保它被覆盖,但我不确定虚拟内存是否在预定义的diapason上修复,或者根据进程需要进行更改。