Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
±äÁ¿ÔÚ PHP7 ÄÚ²¿µÄʵÏÖ£¨¶þ£©
 
À´Ô´£º²®ÀÖÔÚÏß ·¢²¼ÓÚ 2016-1-13
  5091  次浏览      29
 

ÒªÀí½â±¾ÎÄ£¬ÄãÓ¦¸Ã¶Ô PHP5 ÖбäÁ¿µÄʵÏÖÓÐÁËһЩÁ˽⣬±¾ÎÄÖØµãÔÚÓÚ½âÊÍ PHP7 ÖÐ zval µÄ±ä»¯¡£

µÚÒ»²¿·Ö½²ÁË PHP5 ºÍ PHP7 ÖйØÓÚ±äÁ¿×î»ù´¡µÄʵÏֺͱ仯¡£ÕâÀïÔÙÖØ¸´Ò»Ï£¬Ö÷ÒªµÄ±ä»¯¾ÍÊÇ zval ²»ÔÙµ¥¶À·ÖÅäÄڴ棬²»×Ô¼º´æ´¢ÒýÓüÆÊý¡£ÕûÐ͸¡µãÐ͵ȼòµ¥ÀàÐÍÖ±½Ó´æ´¢ÔÚ zval ÖС£¸´ÔÓÀàÐÍÔòͨ¹ýÖ¸ÕëÖ¸ÏòÒ»¸ö¶ÀÁ¢µÄ½á¹¹Ìå¡£

¸´Ô zval Êý¾ÝÖµÓÐÒ»¸ö¹²Í¬µÄÍ·£¬Æä½á¹¹ÓÉ zend_refcounted ¶¨Ò壺

struct _zend_refcounted {
uint32_t refcount;
union {
struct {
ZEND_ENDIAN_LOHI_3(
zend_uchar type,
zend_uchar flags,
uint16_t gc_info)
} v;
uint32_t type_info;
} u;
};

Õâ¸öÍ·´æ´¢ÓÐ refcount£¨ÒýÓüÆÊý£©£¬ÖµµÄÀàÐÍ type ºÍÑ­»·»ØÊÕµÄÏà¹ØÐÅÏ¢ gc_info ÒÔ¼°ÀàÐͱê־λ flags¡£

½ÓÏÂÀ´»á¶ÔÿÖÖ¸´ÔÓÀàÐ͵ÄʵÏÖµ¥¶À½øÐзÖÎö²¢ºÍ PHP5 µÄʵÏÖ½øÐбȽϡ£ÒýÓÃËäȻҲÊôÓÚ¸´ÔÓÀàÐÍ£¬µ«ÊÇÉÏÒ»²¿·ÖÒѾ­½éÉܹýÁË£¬ÕâÀï¾Í²»ÔÙ׸Êö¡£ÁíÍâÕâÀïÒ²²»»á½²µ½×ÊÔ´ÀàÐÍ£¨ÒòΪ×÷Õß¾õµÃ×ÊÔ´ÀàÐÍûʲôºÃ½²µÄ£©¡£

×Ö·û´®

PHP7 Öж¨ÒåÁËÒ»¸öеĽṹÌå zend_string ÓÃÓÚ´æ´¢×Ö·û´®±äÁ¿£º

struct _zend_string {
zend_refcounted gc;
zend_ulong h;
/* hash value */
size_t len;
char val[1];
};

³ýÁËÒýÓüÆÊýµÄÍ·ÒÔÍ⣬×Ö·û´®»¹°üº¬¹þÏ£»º´æ h£¬×Ö·û´®³¤¶È len ÒÔ¼°×Ö·û´®µÄÖµ val¡£¹þÏ£»º´æµÄ´æÔÚÊÇΪÁË·ÀֹʹÓÃ×Ö·û´®×öΪ hashtable µÄ key ÔÚ²éÕÒʱÐèÒªÖØ¸´¼ÆËãÆä¹þÏ£Öµ£¬ËùÒÔÕâ¸öÔÚʹÓÃ֮ǰ¾Í¶ÔÆä½øÐгõʼ»¯¡£

Èç¹ûÄã¶Ô C ÓïÑÔÁ˽âµÄ²»ÊǺÜÉîÈëµÄ»°£¬¿ÉÄÜ»á¾õµÃ val µÄ¶¨ÒåÓÐÐ©Ææ¹Ö£ºÕâ¸öÉùÃ÷Ö»ÓÐÒ»¸öÔªËØ£¬µ«ÊÇÏÔÈ»ÎÒÃÇÏë´æ´¢µÄ×Ö·û´®³¥¸¶¿Ï¶¨´óÓÚÒ»¸ö×Ö·ûµÄ³¤¶È¡£ÕâÀïÆäʵʹÓõÄÊǽṹÌåµÄÒ»¸ö¡ººÚ¡»·½·¨£ºÔÚÉùÃ÷Êý×éʱֻ¶¨ÒåÒ»¸öÔªËØ£¬µ«ÊÇʵ¼Ê´´½¨ zend_string ʱÔÙ·ÖÅä×ã¹»µÄÄÚ´æÀ´´æ´¢Õû¸ö×Ö·û´®¡£ÕâÑùÎÒÃÇ»¹ÊÇ¿ÉÒÔͨ¹ý val ·ÃÎÊÍêÕûµÄ×Ö·û´®¡£

µ±È»ÕâÊôÓڷdz£¹æµÄʵÏÖÊֶΣ¬ÒòΪÎÒÃÇʵ¼ÊµÄ¶ÁºÍдµÄÄÚÈݶ¼³¬¹ýÁ˵¥×Ö·ûÊý×éµÄ±ß½ç¡£µ«ÊÇ C ÓïÑÔ±àÒëÆ÷È´²»ÖªµÀÄãÊÇÕâô×öµÄ¡£ËäÈ» C99 Ò²ÔøÃ÷È·¹æ¶¨¹ýÖ§³Ö¡ºÈáÐÔÊý×é¡»£¬µ«ÊǸÐлÎÒÃǵĺÃÅóÓÑ΢Èí£¬Ã»ÈËÄÜÔÚ²»Í¬µÄƽ̨Éϱ£Ö¤ C99 µÄÒ»ÖÂÐÔ£¨ËùÒÔÕâÖÖÊÖ¶ÎÊÇΪÁ˽â¾ö Windows ƽ̨ÏÂÈáÐÔÊý×éµÄÖ§³ÖÎÊÌ⣩¡£

еÄ×Ö·û´®ÀàÐ͵Ľṹ±ÈÔ­ÉúµÄ C ×Ö·û´®¸ü·½±ãʹÓ㺵ÚÒ»ÊÇÒòΪֱ½Ó´æ´¢ÁË×Ö·û´®µÄ³¤¶È£¬ÕâÑù¾Í²»ÓÃÿ´ÎʹÓÃʱ¶¼È¥¼ÆËã¡£µÚ¶þÊÇ×Ö·û´®Ò²ÓÐÒýÓüÆÊýµÄÍ·£¬ÕâÑùÒ²¾Í¿ÉÒÔÔÚ²»Í¬µÄµØ·½¹²Ïí×Ö·û´®±¾Éí¶øÎÞÐèʹÓà zval¡£Ò»¸ö¾­³£Ê¹Óõĵط½¾ÍÊǹ²Ïí hashtable µÄ key¡£

µ«ÊÇеÄ×Ö·û´®ÀàÐÍÒ²ÓÐÒ»¸öºÜ²»ºÃµÄµØ·½£ºËäÈ»¿ÉÒԺܷ½±ãµÄ´Ó zend_string ÖÐÈ¡³ö C ×Ö·û´®£¨Ê¹Óà str->val ¼´¿É£©£¬µ«·´¹ýÀ´£¬Èç¹û½« C ×Ö·û´®±ä³É zend_string ¾ÍÐèÒªÏÈ·ÖÅä zend_string ÐèÒªµÄÄڴ棬ÔÙ½«×Ö·û´®¸´ÖƵ½ zend_string ÖС£ÕâÔÚʵ¼ÊʹÓõĹý³ÌÖв¢²»ÊǺܷ½±ã¡£

×Ö·û´®Ò²ÓÐÒ»Ð©ÌØÓеıêÖ¾£¨´æ´¢ÔÚ GC µÄ±ê־λÖеģ©£º

#define IS_STR_PERSISTENT           (1
/* allocated using malloc */
#define IS_STR_INTERNED (1
/* interned string */
#define IS_STR_PERMANENT (1
/* interned string surviving request boundary */

³Ö¾Ã»¯µÄ×Ö·û´®ÐèÒªµÄÄÚ´æÖ±½Ó´Óϵͳ±¾Éí·ÖÅä¶ø²»ÊÇ zend ÄÚ´æ¹ÜÀíÆ÷£¨ZMM£©£¬ÕâÑùËü¾Í¿ÉÒÔÒ»Ö±´æÔÚ¶ø²»ÊÇÖ»ÔÚµ¥´ÎÇëÇóÖÐÓÐЧ¡£¸øÕâÖÖÌØÊâµÄ·ÖÅä´òÉϱê¼Ç±ãÓÚ zval ʹÓó־û¯×Ö·û´®¡£ÔÚ PHP5 Öв¢²»ÊÇÕâÑù´¦ÀíµÄ£¬ÊÇÔÚʹÓÃǰ¸´ÖÆÒ»·Ýµ½ ZMM ÖС£

±£Áô×Ö·û£¨interned strings£©ÓеãÌØÊ⣬Ëü»áÒ»Ö±´æÔÚÖ±µ½ÇëÇó½áÊøÊ±²ÅÏú»Ù£¬ËùÒÔÒ²¾ÍÎÞÐè½øÐÐÒýÓüÆÊý¡£±£Áô×Ö·û´®Ò²²»¿ÉÖØ¸´£¨duplicate£©£¬ËùÒÔÔÚ´´½¨Ðµı£Áô×Ö·ûʱҲ»áÏȼì²éÊÇ·ñÓÐͬÑù×Ö·ûµÄÒѾ­´æÔÚ¡£ËùÓÐ PHP Ô´ÂëÖв»¿É±äµÄ×Ö·û´®¶¼ÊDZ£Áô×Ö·û£¨°üÀ¨×Ö·û´®³£Á¿¡¢±äÁ¿Ãûº¯ÊýÃûµÈ£©¡£³Ö¾Ã»¯×Ö·û´®Ò²ÊÇÇëÇó¿ªÊ¼Ö®Ç°ÒѾ­´´½¨ºÃµÄ±£Áô×Ö·û¡£µ«ÆÕͨµÄ±£Áô×Ö·ûÔÚÇëÇó½áÊøºó»áÏú»Ù£¬³Ö¾Ã»¯×Ö·û´®È´Ê¼ÖÕ´æÔÚ¡£

Èç¹ûʹÓÃÁË opcache µÄ»°±£Áô×Ö·û»á±»´æ´¢ÔÚ¹²ÏíÄڴ棨SHM£©ÖÐÕâÑù¾Í¿ÉÒÔÔÚËùÓÐ PHP ½ø³ÌÖʼ칲Ïí¡£ÕâÖÖÇé¿öϳ־û¯×Ö·û´®Ò²¾ÍûÓдæÔÚµÄÒâÒåÁË£¬ÒòΪ±£Áô×Ö·ûÒ²ÊDz»»á±»Ïú»ÙµÄ¡£

Êý×é

ÒòΪ֮ǰµÄÎÄÕÂÓн²¹ýеÄÊý×éʵÏÖ£¬ËùÒÔÕâÀï¾Í²»ÔÙÏêϸÃèÊöÁË¡£ËäÈ»×î½üÓÐЩ±ä»¯µ¼ÖÂ֮ǰµÄÃèÊö²»ÊÇÊ®·Ö׼ȷÁË£¬µ«ÊÇ»ù±¾µÄ¸ÅÄÊÇÒ»Öµġ£

ÕâÀïҪ˵µÄÊÇ֮ǰµÄÎÄÕÂÖÐûÓÐÌáµ½µÄÊý×éÏà¹ØµÄ¸ÅÄ²»¿É±äÊý×é¡£Æä±¾ÖÊÉϺͱ£Áô×Ö·ûÀàËÆ£ºÃ»ÓÐÒýÓüÆÊýÇÒÔÚÇëÇó½áÊøÖ®Ç°Ò»Ö±´æÔÚ£¨Ò²¿ÉÄÜÔÚÇëÇó½áÊøÖ®ºó»¹´æÔÚ£©¡£

ÒòΪijЩÄÚ´æ¹ÜÀí·½±ãµÄÔ­Òò£¬²»¿É±äÊý×éÖ»»áÔÚ¿ªÆô opcache ʱ»áʹÓõ½¡£ÎÒÃÇÀ´¿´¿´Êµ¼ÊʹÓõÄÀý×Ó£¬ÏÈ¿´ÒÔϵĽű¾£º

for ($i = 0; $i  1000000; ++$i) {
$array[] = ['foo'];
}
var_dump(memory_get_usage());

¿ªÆô opcache ʱ£¬ÒÔÉÏ´úÂë»áʹÓà 32MB µÄÄڴ棬²»¿ªÆôµÄÇé¿öÏÂÒòΪ $array ÿ¸öÔªËØ¶¼»á¸´ÖÆÒ»·Ý ['foo'] £¬ËùÒÔÐèÒª 390MB¡£ÕâÀï»á½øÐÐÍêÕûµÄ¸´Öƶø²»ÊÇÔö¼ÓÒýÓüÆÊýÖµµÄÔ­ÒòÊÇ·ÀÖ¹ zend ÐéÄâ»ú²Ù×÷·ûÖ´ÐеÄʱºò³öÏÖ¹²ÏíÄÚ´æ³ö´íµÄÇé¿ö¡£ÎÒÏ£Íû²»Ê¹Óà opcache ʱÄڴ汩ÔöµÄÎÊÌâÒÔºóÄܵõ½¸ÄÉÆ¡£

PHP5 ÖеĶÔÏó

ÔÚÁ˽â PHP7 ÖеĶÔÏóʵÏÖÖ±ÏßÎÒÃÇÏÈ¿´Ò»Ï PHP5 µÄ²¢ÇÒ¿´Ò»ÏÂÓÐʲôЧÂÊÉϵÄÎÊÌâ¡£PHP5 ÖÐµÄ zval »á´æ´¢Ò»¸ö zend_object_value ½á¹¹£¬Æä¶¨ÒåÈçÏ£º

typedef struct _zend_object_value {
zend_object_handle handle;
const zend_object_handlers *handlers;
} zend_object_value;

handle ÊǶÔÏóµÄΨһ ID£¬¿ÉÒÔÓÃÓÚ²éÕÒ¶ÔÏóÊý¾Ý¡£handles ÊDZ£´æ¶ÔÏó¸÷ÖÖÊôÐÔ·½·¨µÄÐ麯Êý±íÖ¸Õ롣ͨ³£Çé¿öÏ PHP ¶ÔÏó¶¼ÓÐ×ÅͬÑùµÄ handler ±í£¬µ«ÊÇ PHP À©Õ¹´´½¨µÄ¶ÔÏóÒ²¿ÉÒÔͨ¹ý²Ù×÷·ûÖØÔØµÈ·½Ê½¶ÔÆäÐÐΪ×Ô¶¨Òå¡£

¶ÔÏó¾ä±ú£¨handler£©ÊÇ×÷ΪË÷ÒýÓÃÓÚ¡º¶ÔÏó´æ´¢¡»£¬¶ÔÏó´æ´¢±¾ÉíÊÇÒ»¸ö´æ´¢ÈÝÆ÷£¨bucket£©µÄÊý×飬bucket ¶¨ÒåÈçÏ£º

typedef struct _zend_object_value {
zend_object_handle handle;
const zend_object_handlers *handlers;
} zend_object_value;

Õâ¸ö½á¹¹Ìå°üº¬Á˺ܶණÎ÷¡£Ç°Èý¸ö³ÉÔ±Ö»ÊÇЩÆÕͨµÄÔªÊý¾Ý£¨¶ÔÏóµÄÎö¹¹º¯ÊýÊÇ·ñ±»µ÷Óùý¡¢bucke ÊÇ·ñ±»Ê¹ÓùýÒÔ¼°¶ÔÏ󱻵ݹéµ÷Óùý¶àÉٴΣ©¡£½ÓÏÂÀ´µÄÁªºÏÌåÓÃÓÚÇø·Ö bucket ÊÇ´¦ÓÚʹÓÃÖеÄ״̬»¹ÊÇ¿ÕÏÐ״̬¡£ÉÏÃæµÄ½á¹¹ÖÐ×îÖØÒªµÄÊÇ struct _store_object ×ӽṹÌ壺

µÚÒ»¸ö³ÉÔ± object ÊÇÖ¸Ïòʵ¼Ê¶ÔÏó£¨Ò²¾ÍÊǶÔÏó×îÖÕ´æ´¢µÄλÖ㩵ÄÖ¸Õë¡£¶ÔÏóʵ¼Ê²¢²»ÊÇÖ±½ÓǶÈëµ½¶ÔÏó´æ´¢µÄ bucket Öеģ¬ÒòΪ¶ÔÏó²»ÊǶ¨³¤µÄ¡£¶ÔÏóÖ¸ÕëÏÂÃæÊÇÈý¸öÓÃÓÚ¹ÜÀí¶ÔÏóÏú»Ù¡¢ÊÍ·ÅÓë¿Ë¡µÄ²Ù×÷¾ä±ú£¨handler£©¡£ÕâÀïҪעÒâµÄÊÇ PHP Ïú»ÙºÍÊͷŶÔÏóÊDz»Í¬µÄ²½Ö裬ǰÕßÔÚijЩÇé¿öÏÂÓпÉÄÜ»á±»Ìø¹ý£¨²»ÍêÈ«ÊÍ·Å£©¡£¿Ë¡²Ù×÷ʵ¼ÊÉϼ¸ºõ¼¸ºõ²»»á±»Óõ½£¬ÒòΪÕâÀï°üº¬µÄ²Ù×÷²»ÊÇÆÕͨ¶ÔÏó±¾ÉíµÄÒ»²¿·Ö£¬ËùÒÔ£¨ÈκÎʱºò£©ËûÃÇÔÚÿ¸ö¶ÔÏóÖÐËûÃǶ¼»á±»µ¥¶À¸´ÖÆ£¨duplicate£©Ò»·Ý¶ø²»Êǹ²Ïí¡£

ÕâЩ¶ÔÏó´æ´¢²Ù×÷¾ä±úºóÃæÊÇÒ»¸öÆÕͨµÄ¶ÔÏó handlers Ö¸Õë¡£´æ´¢Õ⼸¸öÊý¾ÝÊÇÒòΪÓÐʱºò¿ÉÄÜ»áÔÚ zval δ֪µÄÇé¿öÏÂÏú»Ù¶ÔÏó£¨Í¨³£Çé¿öÏÂÕâЩ²Ù×÷¶¼ÊÇÕë¶Ô zval ½øÐеģ©¡£

bucket Ò²°üº¬ÁË refcount µÄ×ֶΣ¬²»¹ýÕâÖÖÐÐΪÔÚ PHP5 ÖÐÏÔµÃÓÐÐ©Ææ¹Ö£¬ÒòΪ zval ±¾ÉíÒѾ­´æ´¢ÁËÒýÓüÆÊý¡£ÎªÊ²Ã´»¹ÐèÒªÒ»¸ö¶àÓàµÄ¼ÆÊýÄØ£¿ÎÊÌâÔÚÓÚËäȻͨ³£Çé¿öÏ zval µÄ¡º¸´ÖÆ¡»ÐÐΪ¶¼ÊǼòµ¥µÄÔö¼ÓÒýÓüÆÊý¼´¿É£¬µ«ÊÇż¶ûÒ²»áÓÐÉî¶È¸´ÖƵÄÇé¿ö³öÏÖ£¬±ÈÈç´´½¨Ò»¸öÈ«Ð嵀 zval µ«ÊDZ£´æÍ¬ÑùµÄ zend_object_value¡£ÕâÖÖÇé¿öÏÂÁ½¸ö²»Í¬µÄ zval ¾ÍÓõ½ÁËͬһ¸ö¶ÔÏó´æ´¢µÄ bucket£¬ËùÒÔ bucket ×ÔÉíÒ²ÐèÒª½øÐÐÒýÓüÆÊý¡£ÕâÖÖ¡ºË«ÖؼÆÊý¡»µÄ·½Ê½ÊÇ PHP5 µÄʵÏÖÄÚÔÚµÄÎÊÌâ¡£GC ¸ù»º³åÇøÖÐµÄ buffered Ö¸ÕëÒ²ÊÇÓÉÓÚͬÑùµÄÔ­Òò²ÅÐèÒª½øÐÐÍêÈ«¸´ÖÆ£¨duplicate£©¡£

ÏÖÔÚ¿´¿´¶ÔÏó´æ´¢ÖÐÖ¸ÕëÖ¸ÏòµÄʵ¼ÊµÄ object µÄ½á¹¹£¬Í¨³£Çé¿öÏÂÓû§²ãÃæµÄ¶ÔÏó¶¨ÒåÈçÏ£º

typedef struct _zend_object {
zend_class_entry *ce;
HashTable *properties;
zval **properties_table;
HashTable *guards;
} zend_object;

zend_class_entry Ö¸ÕëÖ¸ÏòµÄÊǶÔÏóʵÏÖµÄÀàÔ­ÐÍ¡£½ÓÏÂÀ´µÄÁ½¸öÔªËØÊÇʹÓò»Í¬µÄ·½Ê½´æ´¢¶ÔÏóÊôÐÔ¡£¶¯Ì¬ÊôÐÔ£¨ÔËÐÐʱÌí¼ÓµÄ¶ø²»ÊÇÔÚÀàÖж¨ÒåµÄ£©È«²¿´æÔÚ properties ÖУ¬²»¹ýÖ»ÊÇÊôÐÔÃûºÍÖµµÄ¼òµ¥Æ¥Åä¡£

²»¹ýÕâÀïÓÐÕë¶ÔÒѾ­ÉùÃ÷µÄÊôÐÔµÄÒ»¸öÓÅ»¯£º±àÒëÆÚ¼äÿ¸öÊôÐÔ¶¼»á±»Ö¸¶¨Ò»¸öË÷Òý²¢ÇÒÊôÐÔ±¾ÉíÊÇ´æ´¢ÔÚ properties_table µÄË÷ÒýÖС£ÊôÐÔÃû³ÆºÍË÷ÒýµÄÆ¥Åä´æ´¢ÔÚÀàÔ­Ð굀 hashtable ÖС£ÕâÑù¾Í¿ÉÒÔ·Àֹÿ¸ö¶ÔÏóʹÓõÄÄڴ泬¹ý hashtable µÄÉÏÏÞ£¬²¢ÇÒÊôÐÔµÄË÷Òý»áÔÚÔËÐÐʱÓжദ»º´æ¡£

guards µÄ¹þÏ£±íÊÇÓÃÓÚʵÏÖħÊõ·½·¨µÄµÝ¹éÐÐΪµÄ£¬±ÈÈç __get£¬ÕâÀïÎÒÃDz»ÉîÈëÌÖÂÛ¡£

³ýÁËÉÏÎÄÌáµ½¹ýµÄË«ÖØ¼ÆÊýµÄÎÊÌ⣬ÕâÖÖʵÏÖ»¹ÓÐÒ»¸öÎÊÌâÊÇÒ»¸ö×îСµÄÖ»ÓÐÒ»¸öÊôÐԵĶÔÏóÒ²ÐèÒª 136 ¸ö×Ö½ÚµÄÄڴ棨Õ⻹²»Ëã zval ÐèÒªµÄÄڴ棩¡£¶øÇÒÖÐ¼ä´æÔںܶà¼ä½Ó·ÃÎʶ¯×÷£º±ÈÈçÒª´Ó¶ÔÏó zval ÖÐÈ¡³öÒ»¸öÔªËØ£¬ÏÈÐèҪȡ³ö¶ÔÏó´æ´¢ bucket£¬È»ºóÊÇ zend object£¬È»ºó²ÅÄÜͨ¹ýÖ¸ÕëÕÒµ½¶ÔÏóÊôÐÔ±íºÍ zval¡£ÕâÑùÕâÀïÖÁÉÙ¾ÍÓÐ 4 ²ã¼ä½Ó·ÃÎÊ£¨²¢ÇÒʵ¼ÊʹÓÃÖпÉÄÜ×îÉÙÐèÒªÆß²ã£©¡£

PHP7 ÖеĶÔÏó

PHP7 µÄʵÏÖÖÐÊÔͼ½â¾öÉÏÃæÕâЩÎÊÌ⣬°üÀ¨È¥µôË«ÖØÒýÓüÆÊý¡¢¼õÉÙÄÚ´æÊ¹ÓÃÒÔ¼°¼ä½Ó·ÃÎÊ¡£Ð嵀 zend_object ½á¹¹ÌåÈçÏ£º

struct _zend_object {
zend_refcounted gc;
uint32_t handle;
zend_class_entry *ce;
const zend_object_handlers *handlers;
HashTable *properties;
zval properties_table[1];
};

¿ÉÒÔ¿´µ½ÏÖÔÚÕâ¸ö½á¹¹Ì弸ºõ¾ÍÊÇÒ»¸ö¶ÔÏóµÄÈ«²¿ÄÚÈÝÁË£ºzend_object_value ÒѾ­±»Ìæ»»³ÉÒ»¸öÖ±½ÓÖ¸Ïò¶ÔÏóºÍ¶ÔÏó´æ´¢µÄÖ¸Õ룬ËäȻûÓÐÍêÈ«ÒÆ³ý£¬µ«ÒѾ­ÊǺܴóµÄÌáÉýÁË¡£

³ýÁË PHP7 ÖйßÓÃµÄ zend_refcounted Í·ÒÔÍ⣬handle ºÍ ¶ÔÏóµÄ handlers ÏÖÔÚÒ²±»·Åµ½ÁË zend_object ÖС£ÕâÀïµÄ properties_table ͬÑùÓõ½ÁË C ½á¹¹ÌåµÄС¼¼ÇÉ£¬ÕâÑù zend_object ºÍÊôÐÔ±í¾Í»áµÃµ½Ò»Õû¿éÄÚ´æ¡£µ±È»£¬ÏÖÔÚÊôÐÔ±íÊÇÖ±½ÓǶÈëµ½ zval ÖеĶø²»ÊÇÖ¸Õë¡£

ÏÖÔÚ¶ÔÏó½á¹¹ÌåÖÐûÓÐÁË guards ±í£¬ÏÖÔÚÈç¹ûÐèÒªµÄ»°Õâ¸ö×ֶεÄÖµ»á±»´æ´¢ÔÚ properties_table µÄµÚһλÖУ¬Ò²¾ÍÊÇʹÓà __get µÈ·½·¨µÄʱºò¡£²»¹ýÈç¹ûûÓÐʹÓÃħÊõ·½·¨µÄ»°£¬guards ±í»á±»Ê¡ÂÔ¡£

dtor¡¢free_storage ºÍ clone Èý¸ö²Ù×÷¾ä±ú֮ǰÊÇ´æ´¢ÔÚ¶ÔÏó²Ù×÷ bucket ÖУ¬ÏÖÔÚÖ±½Ó´æÔÚ handlers ±íÖУ¬Æä½á¹¹Ì嶨ÒåÈçÏ£º

struct _zend_object_handlers {

/* offset of real object header (usually zero) */
int offset;

/* general object functions */
zend_object_free_obj_t free_obj;
zend_object_dtor_obj_t dtor_obj;
zend_object_clone_obj_t clone_obj;

/* individual object functions */

// ... rest is about the same in PHP 5
};

handler ±íµÄµÚÒ»¸ö³ÉÔ±ÊÇ offset£¬ºÜÏÔÈ»Õâ²»ÊÇÒ»¸ö²Ù×÷¾ä±ú¡£Õâ¸ö offset ÊÇÏÖÔÚµÄʵÏÖÖбØÐë´æÔڵģ¬ÒòΪËäÈ»ÄÚ²¿µÄ¶ÔÏó×ÜÊÇǶÈëµ½±ê×¼µÄ zend_object ÖУ¬µ«ÊÇÒ²×Ü»áÓÐÌí¼ÓһЩ³ÉÔ±½øÈ¥µÄÐèÇó¡£ÔÚ PHP5 Öнâ¾öÕâ¸öÎÊÌâµÄ·½·¨ÊÇÌí¼ÓһЩÄÚÈݵ½±ê×¼µÄ¶ÔÏóºóÃæ£º

struct custom_object {
zend_object std;
uint32_t something;

// ...
};

ÕâÑùÈç¹ûÄã¿ÉÒÔÇáÒ׵Ľ« zend_object* Ìí¼Óµ½ struct custom_object* ÖС£ÕâÒ²ÊÇ C ÓïÑÔÖг£ÓõĽṹÌå¼Ì³ÐµÄ×ö·¨¡£µ«ÊÇÔÚ PHP7 ÖÐÕâÖÖʵÏÖ»áÓÐÒ»¸öÎÊÌ⣺ÒòΪ zend_object ÔÚ´æ´¢ÊôÐÔ±íʱÓÃÁ˽ṹÌå hack µÄ¼¼ÇÉ£¬zend_object β²¿´æ´¢µÄ PHP ÊôÐԻḲ¸ÇµôºóÐøÌí¼Ó½øÈ¥µÄÄÚ²¿³ÉÔ±¡£ËùÒÔ PHP7 µÄʵÏÖÖлá°Ñ×Ô¼ºÌí¼ÓµÄ³ÉÔ±Ìí¼Óµ½±ê×¼¶ÔÏó½á¹¹µÄÇ°Ãæ£º

struct custom_object {
uint32_t something;

// ...
zend_object std;
};

²»¹ýÕâÑùÒ²¾ÍÒâζ×ÅÏÖÔÚÎÞ·¨Ö±½ÓÔÚ zend_object* ºÍ struct custom_object* ½øÐмòµ¥µÄת»»ÁË£¬ÒòΪÁ½Õß¶¼Ò»¸öÆ«ÒÆ·Ö¸î¿ªÁË¡£ËùÒÔÕâ¸öÆ«ÒÆÁ¿¾ÍÐèÒª±»´æ´¢ÔÚ¶ÔÏó handler ±íÖеĵÚÒ»¸öÔªËØÖУ¬ÕâÑùÔÚ±àÒëʱͨ¹ý offsetof() ºê¾ÍÄÜÈ·¶¨¾ßÌåµÄÆ«ÒÆÖµ¡£

Ò²ÐíÄã»áºÃÆæ¼ÈÈ»ÏÖÔÚÒѾ­Ö±½Ó£¨ÔÚ zend_value ÖУ©´æ´¢ÁË zend_object µÄÖ¸Õ룬ÄÇÏÖÔھͲ»ÐèÒªÔÙµ½¶ÔÏó´æ´¢ÖÐÈ¥²éÕÒ¶ÔÏóÁË£¬ÎªÊ²Ã´ PHP7 µÄ¶ÔÏóÕß»¹±£Áô×Å handle ×Ö¶ÎÄØ£¿

ÕâÊÇÒòΪÏÖÔÚ¶ÔÏó´æ´¢ÈÔÈ»´æÔÚ£¬ËäÈ»µÃµ½Á˼«´óµÄ¼ò»¯£¬ËùÒÔ±£Áô handle ÈÔÈ»ÊÇÓбØÒªµÄ¡£ÏÖÔÚËüÖ»ÊÇÒ»¸öÖ¸Ïò¶ÔÏóµÄÖ¸ÕëÊý×é¡£µ±¶ÔÏó±»´´½¨Ê±£¬»áÓÐÒ»¸öÖ¸Õë²åÈëµ½¶ÔÏó´æ´¢Öв¢ÇÒÆäË÷Òý»á±£´æÔÚ handle ÖУ¬µ±¶ÔÏó±»ÊÍ·Åʱ£¬Ë÷ÒýÒ²»á±»ÒƳý¡£

ÄÇôΪʲôÏÖÔÚ»¹ÐèÒª¶ÔÏó´æ´¢ÄØ£¿ÒòΪÔÚÇëÇó½áÊøµÄ½×¶Î»áÔÚ´æÔÚij¸ö½Úµã£¬ÔÚÕâÖ®ºóÔÙÈ¥Ö´ÐÐÓû§´úÂë²¢ÇÒȡָÕëÊý¾Ýʱ¾Í²»°²È«ÁË¡£ÎªÁ˱ÜÃâÕâÖÖÇé¿ö³öÏÖ PHP »áÔÚ¸üÔçµÄ½ÚµãÉÏÖ´ÐÐËùÓжÔÏóµÄÎö¹¹º¯Êý²¢ÇÒÖ®ºó¾Í²»ÔÙÓдËÀà²Ù×÷£¬ËùÒÔ¾ÍÐèÒªÒ»¸ö»îÔ¾¶ÔÏóµÄÁÐ±í¡£

²¢ÇÒ handle ¶ÔÓÚµ÷ÊÔÒ²ÊǺÜÓÐÓõģ¬ËüÈÃÿ¸ö¶ÔÏó¶¼ÓÐÁËÒ»¸öΨһµÄ ID£¬ÕâÑù¾ÍºÜÈÝÒ×Çø·ÖÁ½¸ö¶ÔÏóÊÇͬһ¸ö»¹ÊÇÖ»ÊÇÓÐÏàͬµÄÄÚÈÝ¡£ËäÈ» HHVM ûÓжÔÏó´æ´¢µÄ¸ÅÄµ«ËüÒ²´æÁ˶ÔÏóµÄ handle¡£

ºÍ PHP5 Ïà±È£¬ÏÖÔÚµÄʵÏÖÖÐÖ»ÓÐÒ»¸öÒýÓüÆÊý£¨zval ×ÔÉí²»¼ÆÊý£©£¬²¢ÇÒÄÚ´æµÄʹÓÃÁ¿ÓÐÁ˺ܴóµÄËõ¼õ£º40 ¸ö×Ö½ÚÓÃÓÚ»ù´¡¶ÔÏó£¬Ã¿¸öÊôÐÔÐèÒª 16 ¸ö×Ö½Ú£¬²¢ÇÒÕ⻹ÊÇËãÁË zval Ö®ºóµÄ¡£¼ä½Ó·ÃÎʵÄÇé¿öÒ²ÓÐÁËÏÔÖøµÄ¸ÄÉÆ£¬ÒòΪÏÖÔÚÖмä²ãµÄ½á¹¹ÌåҪô±»È¥µôÁË£¬ÒªÃ´¾ÍÊÇÖ±½ÓǶÈëµÄ£¬ËùÒÔÏÖÔÚ¶Áȡһ¸öÊôÐÔÖ»ÓÐÒ»²ã·ÃÎʶø²»ÔÙÊÇËIJ㡣

¼ä½Ó zval

µ½ÏÖÔÚÎÒÃÇÒѾ­»ù±¾Ìáµ½¹ýÁËËùÓÐÕý³£µÄ zval ÀàÐÍ£¬µ«ÊÇÒ²ÓÐÒ»¶ÔÌØÊâÀàÐÍÓÃÓÚÄ³Ð©ÌØ¶¨µÄÇé¿öµÄ£¬ÆäÖÐÖ®Ò»¾ÍÊÇ PHP7 ÐÂÌí¼ÓµÄ IS_INDIRECT¡£

¼ä½Ó zval Ö¸µÄ¾ÍÊÇÆäÕæÕýµÄÖµÊÇ´æ´¢ÔÚÆäËûµØ·½µÄ¡£×¢ÒâÕâ¸ö IS_REFERENCE ÀàÐÍÊDz»Í¬µÄ£¬¼ä½Ó zval ÊÇÖ±½ÓÖ¸ÏòÁíÍâÒ»¸ö zval ¶ø²»ÊÇÏñ zend_reference ½á¹¹ÌåÒ»ÑùǶÈë zval¡£

ΪÁËÀí½âÔÚʲôʱºò»á³öÏÖÕâÖÖÇé¿ö£¬ÎÒÃÇÀ´¿´Ò»Ï PHP ÖбäÁ¿µÄʵÏÖ£¨Êµ¼ÊÉ϶ÔÏóÊôÐԵĴ洢ҲÊÇÒ»ÑùµÄÇé¿ö£©¡£

ËùÓÐÔÚ±àÒë¹ý³ÌÖÐÒÑÖªµÄ±äÁ¿¶¼»á±»Ö¸¶¨Ò»¸öË÷Òý²¢ÇÒÆäÖµ»á±»´æÔÚ±àÒë±äÁ¿£¨CV£©±íµÄÏàӦλÖÃÖС£µ«ÊÇ PHP Ò²ÔÊÐíÄ㶯̬µÄÒýÓñäÁ¿£¬²»¹ÜÊǾֲ¿±äÁ¿»¹ÊÇÈ«¾Ö±äÁ¿£¨±ÈÈç $GLOBALS£©£¬Ö»Òª³öÏÖÕâÖÖÇé¿ö£¬PHP ¾Í»áΪ½Å±¾»òÕߺ¯Êý´´½¨Ò»¸ö·ûºÅ±í£¬ÕâÆäÖаüº¬Á˱äÁ¿ÃûºÍËüÃǵÄÖµÖ®¼äµÄÓ³Éä¹ØÏµ¡£

µ«ÊÇÎÊÌâÔÚÓÚ£ºÔõôÑù²ÅÄÜʵÏÖÁ½¸ö±íµÄͬʱ·ÃÎÊÄØ£¿ÎÒÃÇÐèÒªÔÚ CV ±íÖÐÄܹ»·ÃÎÊÆÕͨ±äÁ¿£¬Ò²ÐèÒªÄÜÔÚ·ûºÅ±íÖзÃÎʱàÒë±äÁ¿¡£ÔÚ PHP5 ÖÐ CV ±íÓÃÁËË«ÖØÖ¸Õë zval**£¬Í¨³£ÕâЩָÕëÖ¸ÏòÖмäµÄ zval* µÄ±í£¬zval* ×îÖÕÖ¸ÏòµÄ²ÅÊÇʵ¼ÊµÄ zval:

+------ CV_ptr_ptr[0]
| +---- CV_ptr_ptr[1]
| | +-- CV_ptr_ptr[2]
| | |
| | +-> CV_ptr[0] --> some zval
| +---> CV_ptr[1] --> some zval
+-----> CV_ptr[2] --> some zval

µ±ÐèҪʹÓ÷ûºÅ±íʱ´æ´¢ zval* µÄÖмä±íÆäʵÊÇûÓÐÓõ½µÄ¶ø zval** Ö¸Õë»á±»¸üе½ hashtable buckets µÄÏìӦλÖÃÖС£ÎÒÃǼٶ¨ÓÐ $a¡¢$b ºÍ $c Èý¸ö±äÁ¿£¬ÏÂÃæÊǼòµ¥µÄʾÒâͼ£º

CV_ptr_ptr[0] --> SymbolTable["a"].pDataPtr --> some zval
CV_ptr_ptr[1] --> SymbolTable["b"].pDataPtr --> some zval
CV_ptr_ptr[2] --> SymbolTable["c"].pDataPtr --> some zval

µ«ÊÇ PHP7 µÄÓ÷¨ÖÐÒѾ­Ã»ÓÐÕâ¸öÎÊÌâÁË£¬ÒòΪ PHP7 ÖÐµÄ hashtable ´óС·¢Éú±ä»¯Ê± hashtable bucket ¾ÍʧЧÁË¡£ËùÒÔ PHP7 ÓÃÁËÒ»¸öÏà·´µÄ²ßÂÔ£ºÎªÁË·ÃÎÊ CV ±íÖд洢µÄ±äÁ¿£¬·ûºÅ±íÖд洢 INDIRECT À´Ö¸Ïò CV ±í¡£CV ±íÔÚ·ûºÅ±íµÄÉúÃüÖÜÆÚÄÚ²»»áÖØÐ·ÖÅ䣬ËùÒÔÒ²¾Í²»»á´æÔÚÓÐÎÞЧָÕëµÄÎÊÌâÁË¡£

ËùÒÔ¼ÓÈëÄãÓÐÒ»¸öº¯Êý²¢ÇÒÔÚ CV ±íÖÐÓÐ $a¡¢$b ºÍ $c£¬Í¬Ê±»¹ÓÐÒ»¸ö¶¯Ì¬·ÖÅäµÄ±äÁ¿ $d£¬·ûºÅ±íµÄ½á¹¹¿´ÆðÀ´´ó¸Å¾ÍÊÇÕâ¸öÑù×Ó£º

SymbolTable["a"].value = INDIRECT --> CV[0] = LONG 42
SymbolTable["b"].value = INDIRECT --> CV[1] = DOUBLE 42.0
SymbolTable["c"].value = INDIRECT --> CV[2] = STRING --> zend_string("42")
SymbolTable["d"].value = ARRAY --> zend_array([4, 2])

¼ä½Ó zval Ò²¿ÉÒÔÊÇÒ»¸öÖ¸Ïò IS_UNDEF ÀàÐÍ zval µÄÖ¸Õ룬µ± hashtable ûÓкÍËü¹ØÁªµÄ key ʱ¾Í»á³öÏÖÕâÖÖÇé¿ö¡£ËùÒÔµ±Ê¹Óà unset($a) ½« CV[0] µÄÀàÐͱê¼ÇΪ UNDEF ʱ¾Í»áÅж¨·ûºÅ±í²»´æÔÚ¼üֵΪ a µÄÊý¾Ý¡£

³£Á¿ºÍ AST

»¹ÓÐÁ½¸öÐèҪ˵һϵÄÔÚ PHP5 ºÍ PHP7 Öж¼´æÔÚµÄÌØÊâÀàÐÍ IS_CONSTANT ºÍ IS_CONSTANT_AST¡£ÒªÁ˽âËûÃÇÎÒÃÇ»¹ÊÇÏÈ¿´ÒÔϵÄÀý×Ó£º

function test($a = ANSWER,
$b = ANSWER * ANSWER) {
return $a + $b;
}

define('ANSWER', 42);
var_dump(test());
// int(42 + 42 * 42)¡¤

test() º¯ÊýµÄÁ½¸ö²ÎÊýµÄĬÈÏÖµ¶¼ÊÇÓɳ£Á¿ ANSWER¹¹³É£¬µ«ÊǺ¯ÊýÉùÃ÷ʱ³£Á¿µÄÖµÉÐ䶨Òå¡£³£Á¿µÄ¾ßÌåÖµÖ»ÓÐͨ¹ý define() ¶¨Òåʱ²ÅÖªµÀ¡£

ÓÉÓÚÒÔÉÏÎÊÌâµÄ´æÔÚ£¬²ÎÊýºÍÊôÐÔµÄĬÈÏÖµ¡¢³£Á¿ÒÔ¼°ÆäËû½ÓÊÜ¡º¾²Ì¬±í´ïʽ¡»µÄ¶«Î÷¶¼Ö§³Ö¡ºÑÓʱ°ó¶¨¡»Ö±µ½Ê×´ÎʹÓÃʱ¡£

³£Á¿£¨»òÕßÀàµÄ¾²Ì¬ÊôÐÔ£©ÕâЩÐèÒª¡ºÑÓʱ°ó¶¨¡»µÄÊý¾Ý¾ÍÊÇ×î³£ÐèÒªÓõ½ IS_CONSTANT ÀàÐÍ zval µÄµØ·½¡£Èç¹ûÕâ¸öÖµÊDZí´ïʽ£¬¾Í»áʹÓà IS_CONSTANT_AST ÀàÐ굀 zval Ö¸Ïò±í´ïʽµÄ³éÏóÓï·¨Ê÷£¨AST£©¡£

µ½ÕâÀïÎÒÃǾͽáÊøÁË¶Ô PHP7 ÖбäÁ¿ÊµÏֵķÖÎö¡£ºóÃæÎÒ¿ÉÄÜ»¹»áдÁ½ÆªÎÄÕÂÀ´½éÉÜһЩÐéÄâ»úÓÅ»¯¡¢ÐµÄÃüÃûÔ¼¶¨ÒÔ¼°Ò»Ð©±àÒëÆ÷»ù´¡½á¹¹µÄÓÅ»¯µÄÄÚÈÝ£¨ÕâÊÇ×÷ÕßÔ­»°£©¡£

   
5091 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕ Ïà¹ØÎĵµ Ïà¹Ø¿Î³Ì



Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

AndroidÊÖ»ú¿ª·¢£¨Ò»£©
Àí½âJavascript
·ÇµäÐÍajaxʵ¼ù
³¹µ×µÄAjax
javascript ʹÓÃCookies
ʹÓà jQuery ¼ò»¯ Ajax ¿ª·¢

Struts+Spring+Hibernate
»ùÓÚJ2EEµÄWeb 2.0Ó¦Óÿª·¢
J2EEÉè¼ÆÄ£Ê½ºÍÐÔÄܵ÷ÓÅ
Java EE 5ÆóÒµ¼¶¼Ü¹¹Éè¼Æ
Javaµ¥Ôª²âÊÔ·½·¨Óë¼¼Êõ
Java±à³Ì·½·¨Óë¼¼Êõ

ijº½¿Õ¹«Ë¾IT²¿ JavaScriptʵ¼ù
ijµçÊÓÈí¼þ HTML5ºÍJavaScript
Öк½ÐÅ JavaScript¸ß¼¶Ó¦Óÿª·¢
´óÇìÓÍÌï web½çÃæAjax¿ª·¢¼¼Êõ
ºÍÀûʱ ʹÓÃAJAX½øÐÐWEBÓ¦Óÿª·¢