Hallo dedlfix,
Nein. $_SERVER und $HTTP_SERVER_VARS liegen nur einmal im Speicher und zeigen auf das gleiche. Der zusätzliche Speicherverbrauch durch $HTTP_SERVER_VARS ist *immer* höchstens ein paar Bytes für das Vorhandensein des Variablennamens in der globalen Symboltabelle.
Anfänglich ist das auch so. PHP legt bei einer Kopie nicht sofort die Daten doppelt an. Erst wenn die Werte in den Variablen "auseinanderlaufen" wird kopiert. Das passiert beispielsweise im Falle der GPC-Arrays, wenn man die Auswirkungen der Magic Quotes beseitigen will, und das erst im Script machen kann.
Ich habe das jetzt mit folgendem Testscript und Breakpoints beim echo-Sprachkonstrukt nochmal durchexerziert:
<?php
session_start ();
echo $_SESSION;
echo $HTTP_SESSION_VARS;
$_SESSION['a'] = 'b';
echo $_SESSION;
echo $HTTP_SESSION_VARS;
?>
Meine komplette Debugging-Sitzung:
------------------------------------- schnipp ------------------------------
GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
seUsing host libthread_db library "/lib/libthread_db.so.1".
(gdb) set args sessiseq.php
(gdb) break ZEND_ECHO_SPEC_CV_HANDLER
Breakpoint 1 at 0x837b871: file /home/christian/dev/php5.2/Zend/zend_vm_execute.h, line 19340.
(gdb) break ZEND_ECHO_SPEC_VAR_HANDLER
Breakpoint 2 at 0x8355b4e: file /home/christian/dev/php5.2/Zend/zend_vm_execute.h, line 7050.
(gdb) run
Starting program: /home/christian/dev/php5.2/sapi/cli/php sessiseq.php
[Thread debugging using libthread_db enabled]
[New Thread 0xb76dc6e0 (LWP 18413)]
[Switching to Thread 0xb76dc6e0 (LWP 18413)]
Breakpoint 2, ZEND_ECHO_SPEC_VAR_HANDLER (execute_data=0xbfea97a4)
at /home/christian/dev/php5.2/Zend/zend_vm_execute.h:7050
7050 zend_op *opline = EX(opline);
(gdb) n
7053 zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
(gdb) n
7055 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
(gdb) print z
$1 = (zval *) 0xa44fb5c
(gdb) c
Continuing.
Array
Breakpoint 1, ZEND_ECHO_SPEC_CV_HANDLER (execute_data=0xbfea97a4)
at /home/christian/dev/php5.2/Zend/zend_vm_execute.h:19340
19340 zend_op *opline = EX(opline);
(gdb) n
19343 zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
(gdb) n
19345 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
(gdb) print z
$2 = (zval *) 0xa44fb5c
(gdb) c
Continuing.
Array
Breakpoint 2, ZEND_ECHO_SPEC_VAR_HANDLER (execute_data=0xbfea97a4)
at /home/christian/dev/php5.2/Zend/zend_vm_execute.h:7050
7050 zend_op *opline = EX(opline);
(gdb) n
7053 zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
(gdb) n
7055 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
(gdb) print z
$3 = (zval *) 0xa44fb5c
(gdb) c
Continuing.
Array
Breakpoint 1, ZEND_ECHO_SPEC_CV_HANDLER (execute_data=0xbfea97a4)
at /home/christian/dev/php5.2/Zend/zend_vm_execute.h:19340
19340 zend_op *opline = EX(opline);
(gdb) n
19343 zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
(gdb) n
19345 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
(gdb) print z
$4 = (zval *) 0xa44fb5c
(gdb) c
Continuing.
Array
Program exited normally.
(gdb) quit
------------------------------------- schnapp ------------------------------
Wie man sehen kann, zeigen beide Variablen vor- und nach der Änderung auf die gleiche Speicheradresse und sind somit identisch.
Und ja, PHP kennt copy-on-write, aber das ist hier irrelevant, da die Variablen sowieso immer die gleichen sind.
Viele Grüße,
Christian