個人的にiPadが大好きです。 iPadはメディアを見たりやゲームをしたりするのにぴったりのガジェットで、電子書籍リーダーとしてもうまく機能します。ただ問題は、それほど使用する機会がないことです。Netflix、Twitch、YouTubeなどのメディアを利用するほとんどの時間、私は並行してコーディングをしています。
メディアの並行利用はMacBookではできますが、iPadではできた試しがありませんでした。しかし、次の2つのことによって可能になったのです。
- 最近、iOSには「ピクチャ・イン・ピクチャ」機能が追加された。ほかのことをしながらビデオアプリの再生ができるということ
- DraftCodeやWorking Copyのようなすばらしいアプリを使えば、iPadから直接PHPアプリのコーディングをしたり、実行したりでき、GitHubへ変更をプッシュできる
これからiPadでコーディングする方法を説明します。完全なワークフローだとは言いませんが、初めてデスクトップではなくラップトップを使ったときのような興奮を私は覚えました。
本記事はしばらく前に書き始めました。実を言えば、その当時、いまから説明するアプリが使えるようになっているとは思っていませんでした。両方とも、記事を書き始めてからアップデートがあったのです。まるで、アプリ開発者が私の心の声を聞き、喜ばせようとしたかのようです。
※GIFアニメーションが多量にあることでページのサイズが大きくなったことについてお詫びします。
ハードウェア
この実験でもっとも重要なことの1つは、コーディングにふさわしいキーボードを見つけることです。モバイルデバイス向けには低品質なハードウェアがあふれているからです。
お気に入りのキーボード「All-in-One Media Keyboard」にたどり着くまで、かなりの時間をかけて探しました。いまでは正しい選択をしたと言って間違いありません。
このキーボードはiPad mini 2の約2倍の長さで、重さはほぼ同じです。キーのスペースがたっぷりあってすばらしい使い心地です。そして静かです!
このキーボードにはトラックパッドもあります。私の知る限り、iOSはマウスやトラックパッドをサポートしていないので、トラックパッド付きのキーボードは必要ありません。個人的には、キーボードとトラックパッドを単一のUSBポートで接続できるので、Raspberry Piの入力デバイスを兼ねられるところが気に入っています。
Bluetoothキーボードを使わないなら、USBポートが必要になります。幸いなことにアップルは、本来デジタルカメラとの互換性のために作られたアダプターを製造しており、試用したすべてのUSBキーボードでうまく動作しました。
Windowsキーはコマンドキーを兼ね、Windows + z / Windows + x / Windows + c / Windows + vは、これまでと変わらず動作します。また、Windows + →とWindows + ←で行の先頭や末尾に移動できます。
All-in-One Media Keyboardは、マイクロソフトのWebサイトでは39.95ドルと記載されていますが、Amazonなら29.99ドルです(日本版編注:Amazon.co.jpでは11月15日現在、3671円で販売)。LightningのUSBアダプターは、アップルのWebサイトでは29.99ドルですが(日本版編注:同じく日本では3200円)、Amazonでは数ドル高い料金です。
アプリ
DraftCodeとWorking Copyの組み合わせについてはすでに触れましたが、実のところ必要なのはこの2つのアプリだけです。
コーディングにはどのようなツールを使っていますか? おそらくIDE、あるいは少なくともAtomのようなテキストエディターを利用しているはずです。ソースコードの整理や新バージョンの作成には、Gitなどを使用しているでしょう。
DraftCodeは構文の強調表示ができるテキストエディターです。IDEのようにコード補完や静的解析などの機能はサポートしていませんが、DraftCodeで書いたPHPスクリプトを実行する機能があります。
しかも、ファイルやフォルダーを管理できるファイルツリーが含まれています。このインターフェイスを使えば、PHPアプリケーション全体も(少し面倒ですが)構築できます。
PHPアプリケーションの実行方法を簡単に説明します。
Working CopyはGitクライアントです。無料版は、Github、Bitbucket、そのほかのGit URLソースをサポートしています。また、クローン作成、フェッチ、マージもサポートしています。私はいまのところプッシュ機能のみ試しました。
iPadでコーディングした変更をプッシュしたい場合は、エンタープライズ版を購入してください。無料版とエンタープライズ版の唯一の大きな違いは、エンタープライズ版のみコードをリモートでプッシュできることです。
DraftCodeの料金は10.99ドルで、Working Copy(エンタープライズ版)は14.99ドルです。記事を書いているときに、エクスポートに奇妙なバグがあると気がつきました(参照GIFはそれ以前に作成したものです)。無料版ではエクスポートできましたが、エンタープライズ版ではエクスポートできませんでした。現時点ではエンタープライズ版をいきなり購入せず、無料アプリ内から購入することをおすすめします(価格は同じです)。
最初のスクリプトを記述する
DraftCodeでPHPスクリプトを記述するプロセスを説明します。アプリを起動したあと、すべてのサンプルファイルを削除すると、シンプルでクリーンなインターフェイスが表示されます。
ファイルツリー(左パネル)の下部に、ボタンがあります。Cog(設定ボタン)はアプリに関する情報を表示していて、WordPressやphpLiteAdmin(SQLiteのphpMyAdminのクローン)をインストールするためのボタンが用意されています。
ファイルやフォルダーの作成、メディアファイルのインポート、ファイルを移動するためのボタンがあります。メディアインポーターはiPadのメディアライブラリーから取り出すもので、オーディオ、ビデオ、画像ファイルといったiPadで再生できるメディアをサポートしています。
それでは、スクリプトを書いてみましょう。PHPのバージョンと、アプリを使って利用可能なモジュールを知っておくと便利です。任意の名前をつけたファイルを作成します。といっても、この種のスクリプト名は一般的にindex.phpまたはphpinfo.phpを使います。
SQLiteを試す
phpinfoでMySQLについて少し触れていることに気づいたかもしれません。iPad上でMySQLデータベースを使い始められるという意味ではなく、パブリックにアクセス可能なMySQLサーバに接続できるだけです。
DraftCodeにはSQLite拡張モジュールがあります。SQLiteデータベースが使えるかどうか、DraftCodeとPDOを使ってテストします。
date_default_timezone_set("UTC");
$handle = new PDO("sqlite::memory:");
$handle->setAttribute(
PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION
);
$handle->exec("
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY,
message TEXT
)
");
$query = "
INSERT INTO messages (message) VALUES (:message)
";
$statement = $handle->prepare($query);
$statement->bindParam(":message", $message);
$message = "hello world";
$statement->execute();
見慣れないかもしれませんが、大半は単なる標準的なPDOのコード例です。いまはデータベース抽象化レイヤーとオブジェクト関係マッピングの時代です。
SQLiteのインメモリデータベースのハンドルを開き、例外を指摘するようにエラーモードを設定します。そのあと単一のmessageテキストフィールドでmessagesテーブルを作成します。
SQLクエリを準備し、用意された命令文へ:messageパラメーターを結合して追跡します。最後に用意した命令文を実行し、メッセージテーブルに単一の行が取り込まれていることを確認します。
次のコードを使って、この行をフェッチします。
$messages = $handle->query("
SELECT * FROM messages
");
foreach($messages as $message) {
print "message: " . $message["message"] . "<br>" . PHP_EOL;
}
SQLiteはほかの堅牢なデータベースに代わるものではありませんが、単一のユーザーにだけサービスを提供するアプリは開発できます。
Working Copyを使ってコードを取り出す
多くの場合、私は既存のコードベースをもとにコーディングに取り組みます。すべての作業ディレクトリを手作業で再構成するのは面倒ですが、幸いWorking Copyを使えばGitサーバーからソースコードを取り出せます。
Githubにコードのバックアップをプッシュしようと考えているなら、IDを設定してGithubに接続しましょう。
これは必ずしも必要ではありませんが(追加あるいは変更したコードをプッシュしたくても、その通りにはなりません)。
次のステップはリポジトリのクローンです。共有ダイアログを使用してDraftCodeにコードを送信します。Working Copyはリポジトリをアーカイブし、抽出するPHPコードをiOSクリップボードに保存します。DraftCode内でリポジトリを抽出するには、新しいファイルを作成し、クリップボードのコードを貼り付けて実行します。
Laravelのインストール
Laravelの最新バージョン(本記事の執筆時は5.3)は、PHP5.6とSQLiteデータベースをサポートしています。それ自体はすばらしいニュースですが、動作のためにはもう少し作業が必要です。
依存オブジェクトのコミット
ここまでに説明したとおり、実行したい任意のコードは、DraftCodeのサーバーを使って実行する必要があります。依存オブジェクトのインストールに、Composerを安易に使えません。スクリプトの作成は理論的には可能ですが、これについてはまた別の機会に説明します。
Laravelに必要な依存オブジェクトをすべて準備するもっとも簡単な方法は、Gitに格納することです。Gitリポジトリ全体を取り出し、DraftCodeの作業ディレクトリにデプロイできます。
vendorは、デフォルトではLaravelアプリに無視されます。リポジトリにコミットできるように、.gitignoreから削除する必要があります。
環境のカスタマイズ
.envは無視されているもうひとつのファイルです。Gitリポジトリを引き出すと、最初のところで意図的に.envをコミットしない限り、おそらく使用するLaravelアプリのバージョンは手に入りません。
いまのところ、最初に拡張子を.txtにすることなく.envまたは.env.exampleを作成、編集はできません。Laravelがセッションを作成する前に、有効なAPP_KEY値のある.envが必要です。
Iconv
PHP DraftCodeが提供するバージョンにはiconv_*関数セットがありません。patchwork/utf8ライブラリーを使用してこれらの関数をシムにできます。
Laravelの4.*には依存オブジェクトとしてpatchwork/utf8がありましたが、これは5.0で削除されてしまいました。
patchwork/utf8を追加するには次のコード使用します。
composer require patchwork/utf8
多くのPHPシムと同様に、追加に適したタイミングはComposerのオートローダーに従います。Laravelではpublic/index.phpが最初です。
public/index.phpのデフォルトの状態は次のとおりです。
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <[email protected]>
*/
/*
| ...
*/
require __DIR__.'/../bootstrap/autoload.php';
/*
| ...
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
/*
| ...
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
※コードはここです。
iconv_*関数にシムを追加するには次の行を加える必要があります。
require __DIR__.'/../bootstrap/autoload.php';
\Patchwork\Utf8\Bootup::initAll();
ランダムバイト
Laravelはparagonie/random_compat:~1.4|~2.0にも依存します。このライブラリーは言語の新しい暗号化改善のためのさまざまなシムを提供しています。重要なのは暗号化した安全な方法でランダムなデータを生成する機能です。
現在の状況を暗号化でよりセキュアにするのはエントロピーソースです。シムはここにあるようなさまざまなソースを使用します。
残念ながらPHPのDraftCodeバージョンでサポートされているソースはopenssl_random_pseudo_bytes関数だけです。そしてライブラリーは最後の手段としてopenssl_random_pseudo_bytesにフォールバックするとコメントされていますが、この機能は例外を指摘する関数と置き換えるためにバージョン1.3で削除されました。
Laravelは~1.4が必要です。これはComposerを取得することなくプロジェクトに^1.2を要求できないということです。唯一の選択肢は、paragonie/random_compatの1.2バージョンから実装し、Composerがオートローダーする前に取り込むことです。
なぜparagonie/random_compatを最初に取り込む必要があるかというと、paragonie/random_compatが例外を指摘するrandom_bytes関数を全体的に、そしてComposerで読み込まれるとすぐに登録するからです。これは1つのシムライブラリーが作業によりほかのすべてのシムの同じタイプのライブラリーを妨げてしまう状況を作ります。興味深い順番です。
paragonie/random_compatについてですが、このようなライブラリーを好まないとは考えないでください。ライブラリーはすばらしいもので、独自のシム実装に役立つことがあります。
openssl_random_pseudo_bytesの実装ソースは次のようになります。
function random_bytes($bytes)
{
try {
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
$secure = true;
$buf = openssl_random_pseudo_bytes($bytes, $secure);
if (
$buf !== false
&&
$secure
&&
RandomCompat_strlen($buf) === $bytes
) {
return $buf;
}
throw new Exception(
'Could not gather sufficient random data'
);
}
※コードはここです。
どこでも好きな場所に保存できますが、私はpath/to/project/compat-random.phpに保存しました。次のようにComposerオートローダより上に追加する必要があります。
if (!function_exists('random_bytes')) {
require_once __DIR__.'/../compat-random.php';
}
require __DIR__.'/../bootstrap/autoload.php';
\Patchwork\Utf8\Bootup::initAll();
このように、openssl_random_pseudo_bytesがrandom_bytesがまだ存在しない場合に実装され、paragonie/random_compatはexception-throwing random_bytesを登録しません。
これは明らかにparagonie/random_compat内部の代替シム機能ほど安全ではありません。このハックはプロダクトでは実行しないでください。
カスタムルート
カスタムルートについて説明する前に、Laravelアプリをそのまま実行します。
ここまでは順調ですね! ただしpublic/index.phpを実行している場合は、どのようにアプリ内でルートを移動させればよいでしょうか。それにはpublic/index.phpをもう一度変更する必要があります。
$_SERVER["REQUEST_URI"] = $_GET["url"];
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
各リクエストの前に、urlクエリ文字列パラメーターに指定したものでREQUEST_URIを上書きします。これが動作するのは、基本的なHTTPRequest::createFromGlobalsのSymfony実装へのRequest::capture()プロキシだからです。同じ実装はREQUEST_URIに基づいた各種URI状態を構築します。
これで次のように新しいルートを作成できます。
Route::get("/then", function() {
return "hello world";
});
そしてURL http://127.0.0.1/tutorial-coding-on-the-ipad/public/index.php?url=thenを使って移動します。
Working Copyを使ってコードをプッシュする
リポジトリに変更を加えたら、コミットしてプッシュしましょう。ルートリポジトリフォルダーまで移動して、フォルダー名をタップします。フォルダーを圧縮するオプションが表示されます。コードベースのサイズによっては、しばらく時間がかかります。完了するとWorking Copyでアーカイブを選択し共有できます。
Working Copyは、どのファイルが変更されたか識別し、リポジトリへのコミットを可能にします。
最後に
この記事ではiPadでPHPアプリケーションを開発するためのハードウェア、ソフトウェア、構成要件について説明しました。また、DraftCodeのPHPでサポートされる機能、制限について取り上げました。
最後に、iPadでのコーディングを試みた理由について説明します。楽しい試みではありますが、iPadがコーディングマシンとして選択肢に入るとは考えられません。アプリは過去数週間にわたり、劇的に改善されていますが、サンドボックスに制限があり、CLIスクリプトの実行ができないこともあって、実用には不足があります。
飛行機を頻繁に利用するなら、アプリの使用にはいくらか魅力があります。きちんとしたiPadケースが手に入るなら、キーボードやアダプターはMacBookと充電器よりもはるかに良いと思います。iPadは飛行機内で充電でき、タッチスクリーンは、時折のゲーム休憩の役に立ちます。
そうは言っても、Surfaceとキーボードの組み合わせの方が使い心地がよいです。Surfaceを使えば専門的なアプリをインストールする必要がなく、通常のIDEと使用に適したPHP 7.0環境をインストールできます。
だからといって、Surfaceを利用すべきだと言っているわけではありません。それは違います。
記事で説明したワークフローにかかる費用は次のとおりです。
- 必要なのはiPad、キーボード、USBコネクター。すでにiPadを持っているなら、コネクターとキーボードにかかる費用は29.99ドル。Bluetoothキーボードも使える
- 10.99ドルのDraftCodeが必要。リモートでプッシュしない場合、プロジェクトを電子メールで送信することに不満がない場合はWorking Copyの無料版を利用できる
これから揃えるなら、購入する必要があるものは次のとおりです。
- 269ドル → iPad mini 2(アップル)
- 29.99ドル → Lightning - USBカメラアダプタ(アップル)
- 29.99ドル → All-in-one Media keyboard(Amazon)
- 10.99ドル → DraftCode
- 14.99ドル → Working Copy
合計381.96ドル(iPadをすでに持っている場合は85.96ドル)です。マイクロソフトから購入できるもっとも安価なSurface 3は499ドルで、キーボードは付属していません(訳注:2016年10月26日、マイクロソフトの発表でSurfaceの構成、価格は変更になっています)。コーディングのことがなくても、個人的にはiPadが欲しいです。
現在のワークフローに取って代わることはなさそうですが、いざというときに役立ち、試すだけでも楽しいものです。
※本記事はClaudio Ribeiroが査読を担当しています。最高のコンテンツに仕上げるために尽力してくれたSitePointの査読担当者のみなさんに感謝します。
(原文:Is It Possible to Write and Run PHP Code on an iPad?)
[翻訳:柴田理恵/編集:Livit]