tl;dr:多くの組み合わせを徹底的にテストした後、for
各文字を上書きするループがメモリ内の文字列の内容をクリア/変更しているようです。最初の内容がどこから来るのか注意してください。それらの変数にまだ存在している可能性があります! 以下の更新を参照してください。
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 でこれを行う信頼できる方法は見つかりませんでした。
アップデート
コメントで示唆されているように、文字列リテラルを使用して変数を初期化すると、リテラルがメモリに保持される可能性があるため、結果に影響を与える可能性があります。したがって、スクリプトを変更して、cli から引数を取り、それに適用して変数を初期化し、変数の内容がnewstr_rot13()
であることを確認します。また、ガベージ コレクションを強制するように追加しました。したがって、テスト スクリプトは次のようになります。gc_collect_cycles()
<?php
$cc = str_rot13($argv[1]);
#v1: unset($cc);
#v2: $cc=null;
#v3: for( $i=0; $i < strlen($cc); $i++ ) $cc[$i] = 'x';
gc_collect_cycles();
sleep(120); // enough time for taking script pid and run the memory dump
echo "done \n";
?>
最初の 2 つのメソッド (unset/null) はメモリからの新しい値をクリアしないよう$cc
です (gc_collect_cycles をオンにしても)が、実際にはfor
ループによって値が変更されます! gc_collect_cycles が使用されているかどうかに関係なく。
PHP 7.2.20 (cli) でテスト済み。
注意引数の初期値 ($argv) はメモリ内にまだあります!