LoginSignup
4
6

More than 5 years have passed since last update.

PHP Phantom JS で任意のスクリプトを走らせる

Last updated at Posted at 2017-02-13

2018/03/26 追記

現在 Phantom JS の開発は止まっています

これからやるなら Headless Chrome を Node.js から操作する、というのが王道でしょうか。

この記事でわかること

  • 自分で書いた Phantom JS スクリプトを PHP から実行する方法
  • PHP から Phantom JS スクリプトにパラメータを渡す方法

概要

PHP Phantom JS ではスクリプトのテンプレートが予め準備されており、「URL指定で特定のページにアクセスし、特定の要素を取り出す」のような用途ではパラメータを渡すだけで簡単に目的を実現できます。

その一方で、自分で作成した Phantom JS スクリプトを実行したり、PHP からパラメータを渡したりする仕組みも備えており、割と自由自在に使うことができます。

この記事ではその方法を説明します。

インストール

公式ページの記述に従って、Composer を使ってインストールします。
一緒に Phantom JS 自体の実行ファイルもついてきます。

composer.json
    // ...
    "scripts": {
        "post-install-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ],
        "post-update-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ]
    },
    // ...
    "config": {
        "bin-dir": "bin"
    },
    // ...
bash
composer require "jonnyw/php-phantomjs:4.*"

任意のスクリプトを実行

実行したいスクリプト( .js )の拡張子を .proc に変えておきます。
また、実行権限を付与します。

bash
cp your_script.js /path/to/directory/your_script.proc
chmod 755 /path/to/directory/your_script.proc

以下のように PHP から Phantom JS を実行することができます。

<?php

use JonnyW\PhantomJs\Client;
use JonnyW\PhantomJs\DependencyInjection\ServiceContainer;

// スクリプトファイル(.proc)が設置してあるディレクトリ
$location = '/path/to/directory';

$serviceContainer = ServiceContainer::getInstance();
$procedureLoader = $serviceContainer->get('procedure_loader_factory')->createProcedureLoader($location);

$client = Client::getInstance();

// スクリプトファイル名を指定(拡張子は除く)
$client->setProcedure('your_script');
$client->getProcedureLoader()->addLoader($procedureLoader);

$request = $client->getMessageFactory()->createRequest();
$response = $client->getMessageFactory()->createResponse();

// スクリプト実行
$client->send($request, $response);

// 結果を取得(Phantom JS の標準出力)
$result = $response->getContent();

PHP からパラメータを渡す

PHP から Phantom JS スクリプトにパラメータを渡したい場合、まず JonnyW\PhantomJs\Http\Request を継承したクラスを作成します。
※公式ドキュメントでは JonnyW\PhantomJs\Messages\Request を継承するように書かれていますが、JonnyW\PhantomJs\Http\Request を継承しましょう。

パラメータを設定する際には getter に対応した setter メソッドを作るのが無難でしょう。

CustomRequest.php
<?php

use JonnyW\PhantomJs\Http\Request;

class CustomRequest extends Request
{
    // パラメータを格納するプロパティ
    protected $hoge;

    // パラメータを設定するメソッド
    public function setHoge($hoge)
    {
        $this->hoge = $hoge;
    }

    // パラメータにアクセスするメソッド(スクリプト側で呼び出す)
    public function getHoge()
    {
       return $this->hoge;
    }
}

上記クラスを作成後、先程の PHP ソースを次のように書き換えます。

<?php

use JonnyW\PhantomJs\Client;
use JonnyW\PhantomJs\DependencyInjection\ServiceContainer;

// スクリプトファイル(.proc)が設置してあるディレクトリ
$location = '/path/to/directory';

$serviceContainer = ServiceContainer::getInstance();
$procedureLoader = $serviceContainer->get('procedure_loader_factory')->createProcedureLoader($location);

$client = Client::getInstance();

// スクリプトファイル名を指定(拡張子は除く)
$client->setProcedure('your_script');
$client->getProcedureLoader()->addLoader($procedureLoader);

// createRequest() の代わりに CustomRequest インスタンスを生成
$request = new CustomRequest();
// hoge パラメータに 1 を設定
$request->setHoge(1);

$response = $client->getMessageFactory()->createResponse();

// スクリプト実行
$client->send($request, $response);

// 結果を取得(Phantom JS の標準出力)
$result = $response->getContent();

これで、Phantom JS スクリプトからパラメータにアクセスする準備が整いました。

Phantom JS スクリプトでパラメータにアクセス

スクリプトファイルの先頭と末尾に次の記述を追加します。

your_script.proc
[% autoescape false %]
{% autoescape false %}

/* ... スクリプト本体 */

{% endautoescape %}
[% endautoescape %]

スクリプトでパラメータにアクセスしたい部分で次のように記述します。

your_script.proc
/* ...(略) */

var hoge = {{ input.getHoge() }};

/* ...(略) */

{{ }}の中身がそのまま入れ替わる形なので、hoge パラメータが文字列であるなら var hoge = '{{ input.getHoge() }}'; のように書く必要があります。

気をつけるべきこと

  • スクリプトは、エラーが起きても phantom.exit() が呼ばれるようにしておく必要がある
    • そうしないといつまでたってもスクリプトの実行が終了しない
  • スクリプトファイルのコメントは/* */ 形式にしないといけない
    • // 形式のコメントがあると構文エラーになる模様

参考にしたURL

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6