- 記事一覧 >
- ブログ記事
php→pythonのトランスパイル
はじめに
詳細は、別記事にありますが、ラズパイでBME280センサから取得した温湿度気圧をWeb画面に表示する wiringpi-php-bme280(GitHub) というのを作りました。
こちらは、phpのプログラムですが、同じことがpythonでもできるはずです。
そこで、まず、ツールでphp→pythonの変換をして、それを元に開発することにしました。今回は、変換ツール(トランスパイラ)の選定と試した結果を書きたいと思います。
【 トランスパイル(transpile) 】
トランスパイル(transpile)とは、あるプログラミング言語から他のプログラミング言語へと変換(翻訳)することです。変換ツールをトランスパイラと呼びます。JavaScriptのBabelが有名です。
・結果総評
・変換元プログラムについて
・nicolasrod/php2python
・danleyb2/php2python
・taichino/php2py
・おまけ php→js
特に言及が無いところでは、root権限で作業していますので、sudoは省略しています。
結果総評
ツールのインストールの仕方、実行方法の前に、結果を先出ししますと、以下になります。
リポジトリ | 結果 |
---|---|
nicolasrod/php2python | 良いかもしれないが、変換後もツールに依存してしまい、今回の用途で求めていた結果と違う。※変換結果の動作は未検証 |
danleyb2/php2python | 変換の正確性がいまいち。インストールは簡単。 |
taichino/php2py | preg_matchなど関数は変換されない。インストールが難しい。関数以外完璧かというとそうでもない。 |
インストールに難儀しましたが、 taichino/php2py が良いかなという印象です。 phpの関数がそのままになるので、 nicolasrod/php2python と見比べながら変換していくと良いかもしれません。 ただ、これをもってしても結局かなりの人力が必要という印象です。正直 wiringpi-php-bme280 の場合、規模が小さいため、全部人力の方が早かったです。
変換元プログラムについて
以下のphpプログラムで試します。動作内容は、特に意味は無いです。
<?php
echo "hello\n";
$dir = "/path/to";
if( !preg_match( "/\/$/", $dir ) ) $dir .= "/";
echo $dir . "\n";
$a[] = "1";
$a[] = "2";
$a[] = "3";
$x = array();
foreach ( $a as $b ) {
$x[] = $b . "b";
}
print_r( $x );
$i = 1;
if ($i == 0) {
echo "i=0";
} elseif ($i == 1) {
echo "i=1";
} elseif ($i == 2) {
echo "i=2";
}
echo "\n";
switch ($i) {
case 0:
echo "i=0";
break;
case 1:
echo "i=1";
break;
case 2:
echo "i=2";
break;
}
echo "\n";
class User
{
public $name;
private $nickname;
public function __construct($name,$nickname){
$this->name = $name;
$this->nickname = $nickname;
}
}
$user = new User('foo','bar');
echo $user->name;
これを変換した場合、以下のようになるのが期待されます。(人力変換です。試したツールでは実現しませんでした。)
#!/usr/bin/python
#-*- coding: utf-8 -*-
import re
print("hello\n", end='')
dir = "/path/to"
if not re.match("\/$", dir):
dir+="/"
print(dir+"\n", end='')
a = []
a.append("1")
a.append("2")
a.append("3")
x = []
for b in a:
x.append(b + "b")
print(x)
i = 1
if i==0:
print("i=0", end='')
elif i==1:
print("i=1", end='')
elif i==2:
print("i=2", end='')
print("\n", end='')
if i==0:
print("i=0", end='')
elif i==1:
print("i=1", end='')
elif i==2:
print("i=2", end='')
print("\n", end='')
class User:
name=0
nickname=0
def __init__(self, name, nickname):
self.name = name
self.nickname = nickname
user = User("foo", "bar")
print(user.name, end='')
[実行結果]
# php sample.php
hello
/path/to/
Array
(
[0] => 1b
[1] => 2b
[2] => 3b
)
i=1
i=1
# python3 sample.py
hello
/path/to/
['1b', '2b', '3b']
i=1
i=1
nicolasrod/php2python
ラズベリーパイOSに nicolasrod/php2python をインストールして使ってみます。
検証環境は、
Raspbian GNU/Linux 10 (buster)
Python 3.7.3
PHP 7.3.29-1
になります。
インストール
GitHubから php2python-master.zip をダウンロードします。
※ここでは、/home/pi に置くものとします。
phpインストール
phpをインストールします。
# apt update
# apt upgrade
※以降基本的にYのため、-yを付けます。-y は、? [Y/n]: のようなときに自動的に y とするオプションです。
# apt install -y php
apt update
とapt upgrade
は必要無いかもしれませんが、
apt install -y php
でE: いくつかのアーカイブを取得できません。apt-get update を実行するか --fix-missing オプションを付けて試してみてください。
のエラーになり、今回は必要でした。
※pythonは最初から入っていました。
Composerインストール
Composerをインストールします。
【 Composer 】
Composerとはphpのライブラリ管理システムです。Node.jsで言うnpm, yarn、Pythonで言うpipのようなものです。
https://getcomposer.org/download/ から composer.phar をダウンロードして、php2python-masterに配置し、インストールします。
※piユーザーで作業するものとします。
# su - pi
$ unzip php2python-master.zip
$ cp composer.phar php2python-master/
$ cd php2python-master
$ php composer.phar install
piユーザー(一般ユーザー)としている理由は、
php composer.phar install
で以下のようにroot権限でやらない方が良いと怒られるからです。(root権限でインストールはできます。)Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?
php2pythonインストール
README.mdに書かれている通りで特に問題無かったです。
$ python3 -m pip install -r requirements.txt
動作確認結果
サンプルプログラム
/home/pi/php2python-master/sample/sample.php
があるとします。
$ python3 php2py.py --keep-ast ./sample
[+] Converting ./sample/sample.php...
[*] Done!
【 AST 】
--keep-astとすると、変換後の.pyファイルとともに、.astファイルも作成されます。ASTとは、Abstract syntax tree=抽象構文木、つまり、構文解析結果のことです。
変換結果を見てみます。
#!/usr/bin/env python3
# coding: utf-8
if '__PHP2PY_LOADED__' not in globals():
import os, os.path, sys
__compat_layer = os.getenv('PHP2PY_COMPAT', 'php_compat.py')
if not os.path.exists(__compat_layer):
sys.exit(f'[-] Compatibility layer not found in file {__compat_layer}. Aborting.')
# end if
with open(__compat_layer) as f:
exec(compile(f.read(), '<string>', 'exec'))
# end with
globals()['__PHP2PY_LOADED__'] = True
# end if
import inspect
php_print("hello\n")
dir_ = "/path/to"
if (not php_preg_match("/\\/$/", dir_)):
dir_ += "/"
# end if
php_print(dir_ + "\n")
a_[-1] = "1"
a_[-1] = "2"
a_[-1] = "3"
x_ = Array()
for b_ in a_:
x_[-1] = b_ + "b"
# end for
print_r(x_)
i_ = 1
if i_ == 0:
php_print("i=0")
elif i_ == 1:
php_print("i=1")
elif i_ == 2:
php_print("i=2")
# end if
php_print("\n")
for case in Switch(i_):
if case(0):
php_print("i=0")
break
# end if
if case(1):
php_print("i=1")
break
# end if
if case(2):
php_print("i=2")
break
# end if
# end for
php_print("\n")
class User():
name = Array()
nickname = Array()
def __init__(self, name_=None, nickname_=None):
self.name = name_
self.nickname = nickname_
# end def __init__
# end class User
user_ = php_new_class("User", lambda : User("foo", "bar"))
php_print(user_.name)
文法も関数も置き換わっています。
ただ独自定義の関数に置き換わっていて、nicolasrod/php2python
一式必要なようです。
今回の用途ではやりすぎ感があるかなと思いました。
ちなみに、作法があるようで、エラーになり、実行はできませんでした。(実行できるようにする方法は調べていません。)
$ python3 sample/sample.py
Traceback (most recent call last):
File "sample/sample.py", line 10, in <module>
exec(compile(f.read(), '<string>', 'exec'))
File "<string>", line 335, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'sample/php_compat.ini'
danleyb2/php2python
ラズベリーパイOSに danleyb2/php2python をインストールして使ってみます。
検証環境は、
Raspbian GNU/Linux 10 (buster)
Python 3.7.3
PHP 7.3.29-1
になります。
インストール
phpインストール
phpをインストールします。
# apt update
# apt upgrade
※以降基本的にYのため、-yを付けます。-y は、? [Y/n]: のようなときに自動的に y とするオプションです。
# apt install -y php
※pythonは最初から入っていました。
php2pythonインストール
以下のエラーになり、README.mdに書かれている通りではうまくいきませんでした。
# pip install convert2php
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting convert2php
Downloading https://files.pythonhosted.org/packages/30/ba/afea59e34b8493c3318251a299c4fbb4aa132981b1f1a29478a9b5f69183/convert2php-0.0.1.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-install-AFkqGP/convert2php/setup.py", line 9, in <module>
with open(os.path.join(os.path.dirname(__file__), 'README.md')) as readme:
IOError: [Errno 2] No such file or directory: '/tmp/pip-install-AFkqGP/convert2php/README.md'
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-AFkqGP/convert2php/
Ubuntu 20.04.2, pip 20.3.4(python 2.7) でも同じでした。
# curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
# python2 get-pip.py
# pip install convert2php
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Collecting convert2php
Using cached convert2php-0.0.1.tar.gz (3.8 kB)
ERROR: Command errored out with exit status 1:
command: /usr/bin/python2 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-ro3dH9/convert2php/setup.py'"'"'; __file__='"'"'/tmp/pip-install-ro3dH9/convert2php/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-Uyfch2
cwd: /tmp/pip-install-ro3dH9/convert2php/
Complete output (5 lines):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-install-ro3dH9/convert2php/setup.py", line 9, in <module>
with open(os.path.join(os.path.dirname(__file__), 'README.md')) as readme:
IOError: [Errno 2] No such file or directory: '/tmp/pip-install-ro3dH9/convert2php/README.md'
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
danleyb2/php2python/issuesに情報がありましたが、自動でダウンロードしているconvert2php-0.0.1.tar.gz
内にREADME.mdが存在しないのが原因のようです。
以下が正解になります。
# pip install https://github.com/danleyb2/php2python/archive/master.zip
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting https://github.com/danleyb2/php2python/archive/master.zip
Downloading https://github.com/danleyb2/php2python/archive/master.zip
\ 20kB 5.4MB/s
Building wheels for collected packages: convert2php
Running setup.py bdist_wheel for convert2php ... done
Stored in directory: /tmp/pip-ephem-wheel-cache-VnJSCL/wheels/ec/a1/26/3518603e2419732350d90abad491b052d62a58a7b5a3266859
Successfully built convert2php
Installing collected packages: convert2php
Successfully installed convert2php-0.0.1
動作確認結果
サンプルプログラム
sample.php
があるとします。
# convert2php -s sample.php
INFO - Converting: sample.php. Output file will be: sample.py
INFO - # Remove opening and closing <?php
INFO - # convert $this-> to self.
INFO - # convert :: to .
INFO - # Process if statements
INFO - # Process else statements
INFO - # Process try statements
INFO - # Process catch statements
INFO - # delete all }
INFO - # delete namespace|require_once|include_once
INFO - # convert protected $var to self.var = None then move into __init__
INFO - # convert public|protected function to def
INFO - # add `self` to function signatures
INFO - # classes not children to extend `object`
INFO - # process child classes
INFO - # convert $ to ''
INFO - # convert ; to ''
INFO - # convert new to ''
INFO - # process foreach
INFO - Converted: sample.php. to: sample.py. { Go on, Proof Check :) }
エラー無く、変換されました。変換結果を見てみます。
echo "hello\n"
dir = "/path/to"
if( !preg_match( "/\//", dir ) ) dir .= "/"
echo dir . "\n"
a[] = "1"
a[] = "2"
a[] = "3"
x = array()
for b in a :
x[] = b . "b"
print_r( x )
i = 1
if i == 0:
echo "i=0"
echo "i=1"
echo "i=2"
echo "\n"
switch (i) {
case 0:
echo "i=0"
break
case 1:
echo "i=1"
break
case 2:
echo "i=2"
break
echo "\n"
class User(object):
private nickname
def __init__(self,name,nickname):
self.name = None
self.name = name
self.nickname = nickname
user = User('foo','bar')
echo user->name
文法は置き換わっていますが、関数はそのままでした。
他、文字列を繋げるドットがそのままだったり、switch文がそのままだったりします。基本的なところしか変換しないようです。
当然エラーになり、実行はできませんでした。
# python sample.py
python sample.py
File "sample.py", line 2
echo "hello\n"
^
SyntaxError: invalid syntax
taichino/php2py
CentOSに taichino/php2py をインストールして使ってみます。
検証環境は、
CentOS 7.6.1810
boost_1_55_0
PHP 5.4.45
になります。
検証環境について
Raspbian GNU/Linux 10 (buster)
、Ubuntu 20.04.2
にてインストールを実施しましたが、phc (php compiler)
のビルドで以下のエラーになり、やや古い環境のCentOS 7.6でやりなおしたら、最後まで行きました。
・Raspbian GNU/Linux 10 (buster)の場合
# cd /home/pi/phc
# ./configure
configure: error: cannot find Boost headers version >= 1.55.0
# apt install -y libboost-all-dev
# ./configure
checking for gc/gc_cpp.h... no
configure: error: in `/home/pi/phc':
configure: error: libgc required
See `config.log' for more details
# apt install -y libgc-dev
# ./configure
# make
./src/lib/Map.h:11:10: fatal error: boost/tr1/unordered_map.hpp: そのようなファイルやディレクトリはありません
#include <boost/tr1/unordered_map.hpp>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [Makefile:2734: src/ast_to_hir/AST_annotate.lo] エラー 1
make[2]: ディレクトリ '/home/pi/phc' から出ます
make[1]: *** [Makefile:3094: all-recursive] エラー 1
make[1]: ディレクトリ '/home/pi/phc' から出ます
make: *** [Makefile:1607: all] エラー 2
・Ubuntu 20.04.2の場合
# cd phc
# touch src/generated/* Makefile.in configure Makefile libltdl/aclocal.m4 libltdl/Makefile.in libltdl/configure libltdl/Makefile
# ./configure
configure: error: C compiler cannot create executable
⇒Boostが無い以前の問題。めんどくさそうな気がして中止。
インストール
GitHubから php2py-master.zip をダウンロードします。その他、php-5.4.45.tar.gz、boost_1_55_0.tar.gzを配置します。
※ここでは、/home/admin に置くものとします。
READMEにある
http://www.phpcompiler.org/
へアクセスしないでください。無くなっていて、変なサイトに繋がります。phcは、GitHubのpbiggar/phcに有りますが、ウィルスが検出されて、ダウンロードできませんでした。(手順中では
git clone
で取得しています。)
phpインストール
phpをインストールします。
# tar zxf php-5.4.45.tar.gz
# cd php-5.4.45
# yum install libxml2-devel
# ./configure --enable-embed
# make && make install
php-5.4.45にしたのは、taichino/php2pyのリリース日時からphp5系だろうと推測しただけでどのバージョンが正解なのかは良く分かりません。また、phcのconfigure時、以下のように--enable-embedを付けてインストールするように促されるため、ソースコードをビルドすることにしました。
configure: WARNING: ******************************************************************************* * It seems the PHP embed SAPI has not been installed. * * * * You will be able to compile and run phc, but you will not be able to * * compile PHP scripts with phc. * * * * To install the PHP embed SAPI, follow the PHP installation instructions, * * but make sure to pass the --enable-embed option to the PHP configure * * script. * *******************************************************************************
Boostインストール
Boostをインストールします。
【 Boost 】
Boostとは、C++のライブラリ集になります。phcのビルドに必要です。
# cd /home/admin
# tar zxf boost_1_55_0.tar.gz
# cd boost_1_55_0
# ./bootstrap.sh --prefix=/usr/
# ./b2 install
phcのビルドで
/usr/include/boost/tr1
が必要なようで、最新のboost_1_76_0
ではインストールされませんでした。また、boost_1_55_0
より古い場合は、phcのconfigureでエラーになります。
phcインストール
phc (php compiler)
をビルドします。いろいろエラーになりましたので、省略せず、直しながらの手順になります。
# cd /home/admin/
# git clone https://github.com/pbiggar/phc.git
# cd phc
# touch src/generated/* Makefile.in configure Makefile libltdl/aclocal.m4 libltdl/Makefile.in libltdl/configure libltdl/Makefile
# ./configure
configure: error: cannot find the flags to link with Boost regex
# vi m4/php-embed.m4
LIBS="-lphp5 -L${PHP_INSTALL_PATH}/lib -R${PHP_INSTALL_PATH}/lib $LIBS"
↓
LIBS="-lphp5 -L${PHP_INSTALL_PATH}/lib ${wl}-R${PHP_INSTALL_PATH}/lib $LIBS"
# ./autogen.sh
configure.ac:20: error: require Automake 1.15, but have 1.13.4
⇒configureの作り直しには成功したので、無視。
# ./configure
checking for gc/gc_cpp.h... no
configure: error: in `/home/admin/phc':
configure: error: libgc required
⇒--disable-gcを付けてconfigureやり直し。
# ./configure --disable-gc
# make
src/embed/optimize.cpp: 静的メンバ関数 ‘static Method_info* PHP::get_method_info(String*)’ 内:
src/embed/optimize.cpp:223:63: エラー: ‘zend_fcall_info* {aka _zend_fcall_info*}’ から ‘uint {aka unsigned int}’ への無効な変換です [-fpermissive]
int result = zend_fcall_info_init (&fn, &fci, &fcic TSRMLS_CC);
^
src/embed/optimize.cpp:223:63: エラー: cannot convert ‘zend_fcall_info_cache* {aka _zend_fcall_info_cache*}’ to ‘zend_fcall_info* {aka _zend_fcall_info*}’ for argument ‘3’ to ‘int zend_fcall_info_init(zval*, uint, zend_fcall_info*, zend_fcall_info_cache*, char**, char**)’
src/embed/optimize.cpp: メンバ関数 ‘virtual bool Internal_method_info::return_by_ref()’ 内:
src/embed/optimize.cpp:248:22: エラー: ‘struct _zend_function::<anonymous>’ has no member named ‘return_reference’
return func->common.return_reference;
^
src/embed/optimize.cpp:249:1: 警告: 制御が非 void 関数の終りに到達しました [-Wreturn-type]
}
^
大域スコープ:
cc1plus: 警告: 認識できないコマンドラインオプション "-Wno-unused-local-typedef" です [デフォルトで有効]
make[2]: *** [src/embed/optimize.lo] エラー 1
make[2]: ディレクトリ `/home/admin/phc' から出ます
make[1]: *** [all-recursive] エラー 1
make[1]: ディレクトリ `/home/admin/phc' から出ます
make: *** [all] エラー 2
# vi src/embed/optimize.cpp
223行目
int result = zend_fcall_info_init (&fn, &fci, &fcic TSRMLS_CC);
↓
int result = zend_fcall_info_init (&fn, 0, &fci, &fcic, NULL, NULL TSRMLS_CC);
# make
src/embed/optimize.cpp: メンバ関数 ‘virtual bool Internal_method_info::return_by_ref()’ 内:
src/embed/optimize.cpp:248:22: エラー: ‘struct _zend_function::<anonymous>’ has no member named ‘return_reference’
return func->common.return_reference;
^
src/embed/optimize.cpp:249:1: 警告: 制御が非 void 関数の終りに到達しました [-Wreturn-type]
}
^
大域スコープ:
cc1plus: 警告: 認識できないコマンドラインオプション "-Wno-unused-local-typedef" です [デフォルトで有効]
make[2]: *** [src/embed/optimize.lo] エラー 1
make[2]: ディレクトリ `/home/admin/phc' から出ます
make[1]: *** [all-recursive] エラー 1
make[1]: ディレクトリ `/home/admin/phc' から出ます
make: *** [all] エラー 2
# vi src/embed/optimize.cpp
248行目
return func->common.return_reference;
↓
#ifdef ZEND_ENGINE_2
return (func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE);
#else
return func->common.return_reference;
#endif
# make
# make install
これでインストール完了ですが、まだ問題があり、phcコマンドを起動するとエラーになります。
# phc
phc: error while loading shared libraries: libboost_regex.so.1.55.0: cannot open shared object file: No such file or directory
シンボリックリンクを作成します。
# ln -s /usr/lib/libboost_regex.so.1.55.0 /usr/local/lib/libboost_regex.so.1.55.0
ようやく問題がなくなりました。
動作確認結果
サンプルプログラム
/home/admin/php2py-master.zip
/home/admin/sample.php
があるとします。
# cd /home/admin
# unzip php2py-master.zip
# cd php2py-master
# cp ../sample.php .
# phc --dump-xml=ast sample.php > sample.xml
# chmod 755 ./php2py.php
# vi php2py.php
#!/usr/bin/php
↓
#!/usr/local/bin/php
# ./php2py.php sample.xml > sample.py
エラー無く、変換されました。変換結果を見てみます。
#!/usr/bin/python
#-*- coding: utf-8 -*-
print("hello\n")
dir = "/path/to"
if !preg_match("/\/$/", dir):
dir+="/"
print(dir+"\n")
a[] = "1"
a[] = "2"
a[] = "3"
x = []
for b in a:
x[] = b+"b"
print_r(x)
i = 1
if i==0:
print("i=0")
elif i==1:
print("i=1")
elif i==2:
print("i=2")
print("\n")
if i==0:
print("i=0")
elif i==1:
print("i=1")
elif i==2:
print("i=2")
print("\n")
class User:
name=0
nickname=0
def __init__(name, nickname):
self.name = name
self.nickname = nickname
user = User("foo", "bar")
print(user.name)
文法が書き換わり、echo
がprint
に変わりました。ただ、preg_match
、print_r
関数はそのままでした。
また、配列のa[] = "1"
のところはそのままでは動作しません。
他、文字列を繋げるドットがプラス記号に変わっていたり、switch文がif文に変わっていたりするので、先ほどの、danleyb2/php2python
よりは良いような気がします。
当然エラーになり、実行はできませんでした。
# python sample.py
File "sample.py", line 5
if !preg_match("/\/$/", dir):
^
SyntaxError: invalid syntax
おまけ php→js
Node.jsのnpmで babel-preset-php というphp→jsのトランスパイラがあります。pythonに変換では無いですが、こちらは、どうなのか、やってみました。
検証環境は、
Raspbian GNU/Linux 10 (buster)
node v10.24.0
npm 5.8.0
6.26.0 (babel-core 6.26.3)
になります。
# apt update
# apt install nodejs
# apt install npm
# mkdir sample
# cd sample
# npm init -y
# npm i -S babel-preset-php
# vi .babelrc
{
"presets": ["php"]
}
# npm i -g babel-cli
# cp ../sample.php .
# babel sample.php -o sample.js
Error: Plugin 0 specified in "/home/pi/sample/node_modules/babel-preset-php/src/index.js" provided an invalid property of "default" (While processing preset: "/home/pi/sample/node_modules/babel-preset-php/src/index.js")
at Plugin.init (/usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/plugin.js:131:13)
at Function.normalisePlugin (/usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/options/option-manager.js:152:12)
at /usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/options/option-manager.js:184:30
at Array.map (<anonymous>)
at Function.normalisePlugins (/usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
at OptionManager.mergeOptions (/usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
at /usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/options/option-manager.js:265:14
at /usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/options/option-manager.js:323:22
at Array.map (<anonymous>)
at OptionManager.resolvePresets (/usr/local/lib/node_modules/babel-cli/node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
エラーになりました。 babel6系の場合、babel-preset-php 1.* 系を使わないといけないようです。(参考)
# vi package.json
"babel-preset-php": "^2.0.0",
↓
"babel-preset-php": "^1.0.0",
# rm -rf node_modules package-lock.json
# npm install
# babel sample.php -o sample.js
変換できましたので、sample.jsを見てみます。
echo("hello\n");
var dir = "/path/to";
if (!preg_match("/\\/$/", dir)) dir += "/";
echo(dir + "\n");
a.push("1");
a.push("2");
a.push("3");
var x = Array();
for (var b of Object.values(a)) {
x.push(b + "b");
}
console.log(x);
var i = 1;
if (i == 0) {
echo("i=0");
} else if (i == 1) {
echo("i=1");
} else if (i == 2) {
echo("i=2");
}
echo("\n");
switch (i) {
case 0:
echo("i=0");
break;
case 1:
echo("i=1");
break;
case 2:
echo("i=2");
break;
}
echo("\n");
class User {
constructor(name, nickname) {
this.name = name;
this.nickname = nickname;
}
};
var user = new User("foo", "bar");
echo(user.name);
文法は置き換わりましたが、echo
がecho
のままで、preg_match
がそのままです。関数の置き換えまでは、各言語で微妙な挙動の違いもありますし、厳しいと思われます。
実行すると、以下のエラーになりました。
↓
# node sample.js
/home/pi/sample/sample.js:1
echo("hello\n");
^
ReferenceError: echo is not defined
at Object.<anonymous> (/home/pi/sample/sample.js:1:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。