前回の記事に引き続き書いていきます。
前の記事で述べたように、ini_set関数はphpの実行中にphpの一部の設定を動的に変更できます。すべての構成を動的に変更できるわけではないことに注意してください。変更可能な ini 設定については、http://php.net/manual/zh/configuration.changes.modes.php
を参照してください。ini_set の実装に直接進みます。関数は少し長いですが、ロジックは非常に明確です。 リーリー
ご覧のとおり、いくつかの必要な検証作業に加えて、主なことは zend_alter_ini_entry_ex を呼び出すことです。zend_alter_ini_entry_ex 関数で引き続きフォローアップします。
リーリー
注意深く理解する必要があるロジックが 3 つあります:1) ini_entry の Modified フィールドは、構成が動的に変更されたかどうかを示すために使用されます。 ini 設定が変更されると、modified は 1 に設定されます。上記のコードには重要なセクションがあります:
リーリー
このコードは、php コードで ini_set を何度呼び出しても、最初の ini_set だけがこのロジックに入り、orig_value を設定することを意味します。 ini_set の 2 回目の呼び出し以降、この時点での Modified は 1 に設定されているため、このブランチは再度実行されません。したがって、ini_entry->orig_value は常に、最初の変更前の構成値 (つまり、最も元の構成) を保存します。2) ini_set で変更した設定をすぐに有効にするには、on_modify コールバック関数が必要です。
前の記事で述べたように、モジュールのグローバル変数を更新できるようにするために on_modify が呼び出されます。もう一度思い出してください。まず、モジュールのグローバル変数の設定は文字列型ではなくなりました。bool を使用する必要がある場合は bool を使用し、int を使用する必要がある場合は int を使用します。次に、各 ini_entry にはモジュールのグローバル変数のアドレスと対応するオフセットが格納されるため、on_modify はメモリを迅速に変更できます。さらに、on_modify が呼び出された後も、EG (ini_directives) の設定値が最新になるように、ini_entry->value をさらに更新する必要があることを忘れないでください。
3) 新しいハッシュ テーブル EG (modified_ini_directives) がここに表示されます。
EG (modified_ini_directives) は、動的に変更された ini 設定を保存するためにのみ使用されます。ini 設定が動的に変更された場合、その設定は EG (ini_directives) と EG (modified_ini_directives) の両方に存在します。各 ini_entry は変更されたフィールドでマークされているため、EG (ini_directives) を走査して変更されたすべての設定を取得することはできないでしょうか?
答えは「はい」です。個人的には、ここでの EG (modified_ini_directives) は主にパフォーマンスを向上させるためのものであると感じています。EG (modified_ini_directives) を直接トラバースするだけで十分です。さらに、EG (modified_ini_directives) の初期化を zend_alter_ini_entry_ex まで延期することで、PHP のパフォーマンス最適化ポイントを詳細に確認することもできます。
2、
ini_setの動作時間はphp.iniファイルの動作時間とは異なります。リクエストの実行が完了すると、ini_setは無効になります。さらに、コード内で ini_restore 関数が呼び出される場合、以前に ini_set を通じて設定された構成も無効になります。
各 php リクエストが実行されると、php_request_shutdown と php_request_startup が 2 つの対応するプロセスとしてトリガーされます。 php が apache/nginx でフックされている場合、http リクエストが処理されるたびに php_request_shutdown が呼び出されます。php が CLI モードで実行されている場合、スクリプトの実行後に php_request_shutdown も呼び出されます。php_request_shutdown では、ini の回復処理が確認できます。
リーリー
「zend_deactivate」と入力すると、zend_ini_deactivate 関数が呼び出され、zend_ini_deactivate が PHP 設定の復元を担当していることがわかります。リーリー
zend_ini_deactivate の実装を詳しく見てみましょう:リーリー
zend_hash_apply から、ini を復元する実際のタスクは最終的に zend_restore_ini_entry_wrapper コールバック関数に渡されます。リーリー
ロジックは非常に明確なので、読者は理解できると思います。 ini 構成の回復プロセスを要約すると、次のようになります:php_request_shutdown--->zend_deactivate--->zend_ini_deactivate--->zend_restore_ini_entry_wrapper--->zend_restore_ini_entry_cb
3. 構成の破壊
1. PHP はすべてのモジュールを順番に終了し、各モジュールの PHP_MSHUTDOWN_FUNCTION で UNREGISTER_INI_ENTRIES を呼び出します。 UNREGISTER_INI_ENTRIES は REGISTER_INI_ENTRIES に対応しますが、UNREGISTER_INI_ENTRIES はモジュールのグローバル領域を解放する役割はありません。XXX_globals のメモリは静的データ領域に配置されるため、手動でリサイクルする必要はありません。
UNREGISTER_INI_ENTRIES主要做的事情,是将某个模块的ini_entry配置从EG(ini_directives)表中删除。删除之后,ini_entry本身的空间会被回收,但是ini_entry->value不一定会被回收。
当所有模块的PHP_MSHUTDOWN_FUNCTION都调用UNREGISTER_INI_ENTRIES一遍之后,EG(ini_directives)中只剩下了Core模块的ini配置。此时,就需要手动调用UNREGISTER_INI_ENTRIES,来完成对Core模块配置的删除工作。
<span>void</span><span> php_module_shutdown(TSRMLS_D) { ... </span><span>//</span><span> zend_shutdown会依次关闭除了Core之外的所有php模块 </span><span>//</span><span> 关闭时会调用各个模块的PHP_MSHUTDOWN_FUNCTION</span> <span> zend_shutdown(TSRMLS_C); ... </span><span>//</span><span> 至此,EG(ini_directives)中只剩下了Core模块的配置 </span><span>//</span><span> 这里手动清理一下</span> <span> UNREGISTER_INI_ENTRIES(); </span><span>/</span><span>/ 回收configuration_hash</span><span> php_shutdown_config(); <br /></span>
<span> <span>/<span>/ 回收EG(ini_directives)<br /> </span></span>zend_ini_shutdown(TSRMLS_C);<br /> ... }</span>
当手动调用UNREGISTER_INI_ENTRIES完成之后,EG(ini_directives)已经不包含任何的元素,理论上讲,此时的EG(ini_directives)是一张空的hash表。
2,configuration_hash的回收发生在EG(ini_directives)之后,上面贴出的代码中有关于php_shutdown_config的函数调用。php_shutdown_config主要负责回收configuration_hash。
<span>int</span> php_shutdown_config(<span>void</span><span>) { </span><span>//</span><span> 回收configuration_hash</span> zend_hash_destroy(&<span>configuration_hash); ... </span><span>return</span><span> SUCCESS; }</span>
注意zend_hash_destroy并不会释放configuration_hash本身的空间,同XXX_G访问的模块全局空间一样,configuration_hash也是一个全局变量,无需手动回收。
3,当php_shutdown_config完成时,只剩下EG(ini_directives)的自身空间还没被释放。因此最后一步调用zend_ini_shutdown。zend_ini_shutdown用于释放EG(ini_directives)。在前文已经提到,此时的EG(ini_directives)理论上是一张空的hash表,因此该HashTable本身所占用的空间需要被释放。
ZEND_API <span>int</span><span> zend_ini_shutdown(TSRMLS_D) { </span><span>//</span><span> EG(ini_directives)是动态分配出的空间,需要回收</span> <span> zend_hash_destroy(EG(ini_directives)); free(EG(ini_directives)); </span><span>return</span><span> SUCCESS; }</span>
用一张图大致描述一下和ini配置相关的流程:
直接编辑php目录下的php.ini文件即可
有一个“register_globals = Off”值,这个值是用来打开全局变量的,比如表单送过来的值,如果这个值设为“Off”,就只能用“$_POST['变量名']、$_GET['变量名 ']”等来取得送过来的值,如果设为“On”,就可以直接使用“$变量名”来获取送过来的值,当然,设为“Off”就比较安全,不会让人轻易将网页间传送 的数据截取。这个值是否改成“On”就看自己感觉了,是安全重要还是方便重要?
要用mysql,就要把“;extension= php_mysql.dll”前的“;”去掉。所有的模块文件都放在php解压缩目录的“ext”之下,用什么就把前面的“;”去掉就行了。
これはあなたの要件を満たしていると思いますか?
';// すべてのキーを走査 foreach($keys[0] as $key ) { // If value は OK ですが、2 番目の ini ファイルには存在しません。display ok if($values[0][$key]==='OK' AND !isset($values[1][ $key])) { echo '