Slide 1

Slide 1 text

SWFEditor の PHP7対応 2015/11/22   “よや”  [email protected]

Slide 2

Slide 2 text

自己紹介 •  id:yoya     •  すっかり旬の終わった元  Flash  のバイナリ屋さん です   –  会社でやる事ないので辞めて実質無職     •  今でも要望を頂くのでメンテしてます   –  中国や東南アジアのとある界隈で流行りっぽい   –  ノセられてるっぽいけど、開発を続けるモチベーショ ンにはなるので嬉しい

Slide 3

Slide 3 text

SWFEditor  について •  昔流行った Flash  の動的バイナリ改変で、 ming 使うの面倒だったので作った  PHP拡張   – hBps://osdn.jp/projects/swfed/

Slide 4

Slide 4 text

SWFEditor のサンプル •  Flash  内画像入れ替え     •  詳しくはこちら   – hBp://www.slideshare.net/yoyayoya1/phpswf   $swfdata  =  fil_get_contents(“foo.swf”);   $jpegdata  =  file_get_contents(“baa.jpg”);   $swf  =  new  SWFEditor();   $swf-­‐>input($swfdata);   $swf-­‐>replaceJpegData($image_id,  $jpegdata);   echo  $swf-­‐>output();  

Slide 5

Slide 5 text

PHP7  化 •  この辺りを読んで覚悟を決める   – hBps://wiki.php.net/phpng-­‐upgrading   – hBp://qiita.com/hnw/items/ d615e0d4122f247d4c75   – hBps://github.com/pasindud/sing-­‐php/blob/ master/UPGRADING.INTERNALS   – hBp://www.sklar.com/soaware/php/2015/03/23/ converdng-­‐a-­‐php-­‐extension-­‐to-­‐php-­‐7/

Slide 6

Slide 6 text

MacOSX  Homebrew  の PHP7 •  これだけでPHP7が入る     •  こうすると便利   •  phpize7   $  brew  install  php7 $  cd  /usr/local/bin/   $  ln  –s  ../Cellar/php70/7.0.0-­‐rc.3_2/bin/php            (phpize  ,  php-­‐configも同様にリンク) $  phpize7   $  ./configure  –with-­‐php-­‐config=php7-­‐config

Slide 7

Slide 7 text

SWFEditor  のソース $  git  clone  git://git.osdn.jp/gitroot/swfed/swfed.git   $  ls  swfed/src   bitmap_udl.c      swf_object.c   bitmap_udl.h      swf_object.h   bitstream.c      swf_png.c   bitstream.h      swf_png.h   config-­‐lib.m4      swf_rect.c   config.m4      swf_rect.h   config.w32      swf_rgb.c   jpeg_segment.c    swf_rgb.h   jpeg_segment.h    swf_rgba.c   php_swfed.c      swf_rgba.h

Slide 8

Slide 8 text

SWFEditorの構造 •  php_swfed.c  が PHPóC  バインディング php_swfed.c swf_object.c swf_*.c,h   pure  C  library   PHPóC  binding   jpeg_*.c,g   php5  

Slide 9

Slide 9 text

PHP7対応 (ファイルを分ける) •  php_swfed.c  と php7_swfed.c  に分ける php_swfed.c swf_object.c swf_*.c,h   pure  C  library   PHPóC  binding   jpeg_*.c,g   php7_swfed.c #ifdef  は辛かったので   ファイルを分けました   php5   php7  

Slide 10

Slide 10 text

PHP7対応 (config.m4) •  php_swfed  切り替え config.m4 version-­‐lib.m4 PHP_NEW_EXTENSION(swfed,  \                  swf_object.c  swf_header.c  swf_tag.c  bitstream.c  swf_debug.c  \    <略>   ,  $ext_shared)      if  test  $PHP_MAJOR_VERSION  -­‐eq  5;  then          PHP_NEW_EXTENSION(swfed,  php_swfed.c,  $ext_shared)      else          PHP_NEW_EXTENSION(swfed,  php7_swfed.c,  $ext_shared)      fi   fi   sinclude(version-­‐lib.m4)  

Slide 11

Slide 11 text

とりあえず make •  20個   エラー?

Slide 12

Slide 12 text

-ferror-­‐limit •  エラーが多すぎて20個でとまってる   – 制限を外してみる  CFLAGS="-­‐ferror-­‐limit=9999"  ./configure  -­‐-­‐with-­‐php-­‐config=php7-­‐config  

Slide 13

Slide 13 text

実際のエラー •  50個   エラー     まぁ   大丈夫

Slide 14

Slide 14 text

ポイント(1/4) •  文字列周りが結構違う   – RETURN_STRINGL  の引数が変わった         – zend_string  を使わせたがるので注意   //  どこかで文字列を foo  に格納   RETURN_STRINGL(foo,  strlen(foo),  0)  //  <=  エラー    =>  RETVAL_STRINGL(foo,  strlen(foo),  4)    //  1 固定      free(free);  //  元々 dup:0  だったので自分で解放                return  ;   zend_hash_find(table,  “foo”,  strlen(“foo”),  &value);   ⇒ zend_string  *foo  =  zval_get_string(“foo”);            value  =  zend_hash_find(table,  foo);            zend_string_free(foo)   =>  value  =  zend_hash_str_find(table,  ZEND_STRL(“foo”));    

Slide 15

Slide 15 text

ポイント(2/4) •  IS_BOOL  がなくなった   – IS_TRUE,  IS_FALSE     がある   – (TRUE型とFALSE型     のイメージ)   if  (Z_TYPE_P(arg4)  ==  IS_TRUE)  {          without_converdng  =  1;   }  else  if  (Z_TYPE_P(arg4)  ==  IS_FALSE)  {          without_converdng  =  0;   }  else  {     convert_to_boolean(arg4);          without_converdng  =  (int)  Z_LVAL_P(arg4);   }   if  (Z_TYPE_P(arg4)  !=  IS_BOOL)  {          convert_to_boolean(arg4);   }   without_converdng  =  (int)  Z_LVAL_P(arg4);  

Slide 16

Slide 16 text

ポイント(3/4) •  zval  のポインタのレベルが違う   – 違うどころか int  が zval  *  になったりする int  ret  =  0;   ret  =  zend_list_insert(swf,  le_swfed  TSRMLS_CC);     zval  *ret  =  0;   ret  =  zend_list_insert(swf,  le_swfed  TSRMLS_CC);    

Slide 17

Slide 17 text

ポイント(4/4) •  zend_hash_get_current_data_ex  駄目   – ZEND_HASH_FOREACH_KEY_VAL  を使う   zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr),  &pos);   while  (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr),  (void  **)&entry,  &                                                                                    pos)  ==  SUCCESS)  {          ret  =  zend_hash_get_current_key_ex(Z_ARRVAL_P(arr),  &str_key,  &                                                                                        str_key_len,  &tmp,  0,  &pos);          <略>          zend_hash_move_forward_ex(Z_ARRVAL_P(arr),  &pos);   }   ZEND_HASH_FOREACH_KEY_VAL(arr_hash,  str_key_len,  key,  value)  {   <略>   }  ZEND_HASH_FOREACH_END();   すっきり

Slide 18

Slide 18 text

はまった罠 PHP_MINIT_FUNCTION(swfed)  {   zend_declare_property_stringl(swfeditor_ce,                                                                  "swf_object",  strlen("swf_object"),                                                                  "",  0,  ZEND_ACC_PUBLIC  TSRMLS_CC);   PHP_METHOD(swfed,  __construct)  {   ret  =  zend_list_insert(swf,  le_swfed  TSRMLS_CC);    object_init_ex(getThis(),  swfeditor_ce);          add_property_resource(getThis(),  "swfed",  ret);          zend_list_addref(ret);   …   if  (zend_hash_find(Z_OBJPROP_P(obj),  "swfed",  strlen("swfed")  +  1,                                                (void  **)&tmp)  ==  FAILURE)  {                  return  NULL;          }          id  =  Z_LVAL_PP(tmp);          swf  =  (swf_object_t  *)  zend_list_find(id,  &type);     PHP5では動く

Slide 19

Slide 19 text

はまった罠  (PHP7  対応してみた) PHP_MINIT_FUNCTION(swfed)  {   zend_declare_property_stringl(swfeditor_ce,                                                                  "swf_object",  strlen("swf_object"),                                                                  "",  0,  ZEND_ACC_PUBLIC  TSRMLS_CC);   PHP_METHOD(swfed,  __construct)  {   ret  =  zend_list_insert(swf,  le_swfed  TSRMLS_CC);    object_init_ex(getThis(),  swfeditor_ce);          add_property_resource(getThis(),  "swfed",  ret);          zend_list_addref(ret);   …   if  ((tmp  =  zend_hash_str_find(Z_OBJPROP_P(obj),  ZEND_STRL("swfed”)))  ==  NULL)  {                  return  NULL;          }          id  =  Z_LVAL_PP(tmp);          swf  =  (swf_object_t  *)  zend_list_find(id,  &type);     NULLが返る!

Slide 20

Slide 20 text

はまった罠  (PHP7  対応してみた) PHP_MINIT_FUNCTION(swfed)  {   zend_declare_property_stringl(swfeditor_ce,                                                                  "swf_object",  strlen("swf_object"),                                                                  "",  0,  ZEND_ACC_PUBLIC  TSRMLS_CC);   PHP_METHOD(swfed,  __construct)  {   ret  =  zend_list_insert(swf,  le_swfed  TSRMLS_CC);    object_init_ex(getThis(),  swfeditor_ce);          add_property_resource(getThis(),  “swf_object”,  ret);  // 前は “swfed”          zend_list_addref(ret);   …   if  ((tmp  =  zend_hash_str_find(Z_OBJPROP_P(obj),  ZEND_STRL("swf_object”)))  ==  NULL)  {                  return  NULL;          }          id  =  Z_LVAL_PP(tmp);          swf  =  (swf_object_t  *)  zend_list_find(id,  &type);     全部合わせないと駄目

Slide 21

Slide 21 text

はまった罠解説 •  PHP4,5 では declare_property  した文字列 (swf_object)と、無関係に add_property  して、 (read_property    や)  zend_hash_find  で拾えた   – お行儀悪い   •  PHP7  では合わせないと駄目

Slide 22

Slide 22 text

動作デモ

Slide 23

Slide 23 text

課題 •  終了処理で落ちるのでデバッグする   •  エラーを直しただけなので、一通り見直す   •  RETURN_STRINGL  の dup:0  対応 (freeする)

Slide 24

Slide 24 text

      ありがとうございました