| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- Advanced
- ========
- - `PhantomJS command line options <#phantomjs-command-line-options>`__
- - `Custom PhantomJS scripts <#custom-phantom-js-scripts>`__
- - `Writing a custom script <#writing-a-custom-script>`__
- - `Using custom request parameters in your
- script <#using-custom-request-parameters-in-your-script>`__
- - `Loading your script <#loading-your-script>`__
- PhantomJS command line options
- ------------------------------
- The PhantomJS API contains a range of command line options that can be
- passed when executing the PhantomJS executable. These can also be passed
- in via the client before a request:
- .. code:: php
- <?php
- use JonnyW\PhantomJs\Client;
-
- $client = Client::getInstance();
- $client->addOption('--load-images=true');
- $client->addOption('--ignore-ssl-errors=true');
-
- $request = $client->getMessageFactory()->createRequest('http://google.com');
- $response = $client->getMessageFactory()->createResponse();
- $client->send($request, $response);
- You can also set a path to a JSON configuration file that contains
- multiple PhantomJS options:
- .. code:: php
- <?php
- use JonnyW\PhantomJs\Client;
-
- $client = Client::getInstance();
- $client->addOption('--config=/path/to/config.json');
-
- $request = $client->getMessageFactory()->createRequest('http://google.com');
- $response = $client->getMessageFactory()->createResponse();
- $client->send($request, $response);
- See the `PhantomJS
- Documentation <http://phantomjs.org/api/command-line.html>`__ for a full
- list of command line options.
- Custom PhantomJS scripts
- ------------------------
- In most instances you shouldn't need to worry about the javascript files
- that run the PHP PhantomJS library but there may be times when you want
- to execute your own custom PhantomJS scripts through the client. This
- can be easily achieved by using the built in script loader.
- Script files or 'procedures' as they are referred to in the application
- are closely mapped to requests. When you create a default request
- instance, you are essentially running the default javascript procedure
- that comes bundled with the application. When you create a capture
- request you are running the capture procedure.
- .. code:: php
- <?php
- use JonnyW\PhantomJs\Client;
-
- $client->getMessageFactory()->createRequest(); // ~/Resources/procedures/default.proc
- $client->getMessageFactory()->createCaptureRequest(); // ~/Resources/procedures/capture.proc
- Writing a custom script
- ~~~~~~~~~~~~~~~~~~~~~~~
- The first step in creating your script is to create a procedure file
- somewhere. For the purpose of this guide we will refer to it as
- ``my_procedure.proc`` but in reality it can be called anything you like.
- The only requirement is that the file extension must be ``.proc``.
- Create the file somewhere and make sure it can be read by your
- application. Make a note of the path to the directory where your file is
- created as you will need this when loading your script which is
- explained later in this guide.
- .. code:: shell
-
- #bash
-
- $ touch my_procedure.proc
- $ chmod 755 my_procedure.proc
-
- Next open your procedure file in your text editor and write your
- PhantomJS script. The `PhantomJS
- documentation <http://phantomjs.org/quick-start.html>`__ has more
- detailed information on writing custom scripts.
- .. code:: javascript
-
- // my_procedure.proc
- var page = require('webpage').create();
-
- page.open ('{{ request.getUrl() }}', '{{ request.getMethod() }}', '{{ request.getBody() }}', function (status) {
-
- // It is important that you exit PhantomJS
- // when your script has run or when you
- // encounter an error
- phantom.exit(1);
- });
-
- ...
-
- Important
- ^^^^^^^^^
- Make sure that ``phantom.exit(1);`` is always called after your
- script has run or if you encounter an error. This requires you to
- take care when handling PhantomJS errors to ensure that you exit the
- PhantomJS script, whether the script was successfully executed or
- not. If you do not call ``phantom.exit(1);`` then PhantomJS will
- continue to run until your PHP script times out. If you find that
- your custom script is hanging then this is most likely the cause.
- It is a good practice to create a global error handler in your script
- that exits PhantomJS:
- .. code:: javascript
- // my_procedure.proc
- phantom.onError = function(msg, trace) {
-
- phantom.exit(1);
- };
-
- ...
- Using custom request parameters in your script
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Before a procedure is executed by the application it is parsed through a
- template parser. The PHP PhantomJS library uses the popular `Twig
- templating engine <https://github.com/fabpot/Twig>`__. This gives you
- access to all the `Twig
- niceness <http://twig.sensiolabs.org/doc/templates.html>`__ which you
- can use in your custom scripts.
- You may have noticed in the example above that we have used some Twig
- template tags referencing a request object e.g.
- ``{{ request.getUrl() }}``. This is in fact the PHP request instance
- that you created and passed to the client when sending your request,
- which is injected into the Twig template parser. As a result you gain
- full access to all the data contained within the request instance, via
- the data accessor methods.
- A default request instance contains the following accessors:
- +--------------------------+-----------------------------------------------+------------------------------------+
- | Accessor | Description | Twig example |
- +==========================+===============================================+====================================+
- | getMethod() | The request method e.g. GET. | {{ request.getMethod() }} |
- +--------------------------+-----------------------------------------------+------------------------------------+
- | getTimeout() | The request timeout period in milliseconds. | {{ request.getTimeout() }} |
- +--------------------------+-----------------------------------------------+------------------------------------+
- | getDelay() | The page render delay in seconds. | {{ request.getDelay() }} |
- +--------------------------+-----------------------------------------------+------------------------------------+
- | getUrl() | The request URL. | {{ request.getUrl() }} |
- +--------------------------+-----------------------------------------------+------------------------------------+
- | getBody() | The request body (POST, PUT). | {{ request.getBody() }} |
- +--------------------------+-----------------------------------------------+------------------------------------+
- | getHeaders(\ *format*) | The request headers. | {{ request.getHeaders('json') }} |
- +--------------------------+-----------------------------------------------+------------------------------------+
- A capture request contains a few additional ones:
- +--------------------+-------------------------------------------+----------------------------------+
- | Accessor | Description | Twig example |
- +====================+===========================================+==================================+
- | getRectTop() | The x coordinate of the capture region. | {{ request.getRectTop() }} |
- +--------------------+-------------------------------------------+----------------------------------+
- | getRectLeft() | The y coordinate of the capture region. | {{ request.getRectLeft() }} |
- +--------------------+-------------------------------------------+----------------------------------+
- | getRectWidth() | The width of the capture region. | {{ request.getRectWidth() }} |
- +--------------------+-------------------------------------------+----------------------------------+
- | getRectHeight() | The height of the capture region. | {{ request.getRectHeight() }} |
- +--------------------+-------------------------------------------+----------------------------------+
- | getCaptureFile() | The file to save the capture to. | {{ request.getCaptureFile() }} |
- +--------------------+-------------------------------------------+----------------------------------+
- If you would like to inject additional data into your script through
- custom accessors, simply extend the request class with your own:
- .. code:: php
- <?php
- use JonnyW\PhantomJs\Message\Request;
-
- class CustomRequest extends Request
- {
-
- public function getSomething()
- {
- return 'Something!';
- }
- }
- Now you will be able to access the data in your custom script when using
- your custom request:
- .. code:: javascript
-
- // my_procedure.proc
- var something = '{{ request.getSomething() }}'; // Get something
-
- ...
-
- And to use your custom request simply create a new instance of it and
- pass it to the client:
- .. code:: php
- <?php
- use JonnyW\PhantomJs\Client;
-
- $client = Client::getInstance();
-
- $response = $client->getMessageFactory()->createResponse();
-
- $request = new CustomRequest();
- $request->setMethod('GET');
- $request->setUrl('http://www.google.com');
-
- $client->send($request, $response);
- Loading your script
- ~~~~~~~~~~~~~~~~~~~
- Now that you have your custom script and you've added your custom
- request parameters, you may be wondering how to tell the client to
- actually load your script. This is done by creating a procedure loader
- and telling it where to find your script files.
- The service container has a factory that makes creating a new procedure
- loader easy:
- .. code:: php
- <?php
-
- use JonnyW\PhantomJs\Client;
- use JonnyW\PhantomJs\DependencyInjection\ServiceContainer;
-
- $location = '/path/to/your/procedure/directory';
-
- $serviceContainer = ServiceContainer::getInstance();
-
- $procedureLoader = $serviceContainer->get('procedure_loader_factory')
- ->createProcedureLoader($location);
-
- ...
- The client contains a chain procedure loader which lets you set multiple
- loaders at the same time. Ultimately this means that you can load your
- custom scripts while still maintaining the ability to load the default
- scripts if you choose.
- Now add your procedure loader to the chain loader:
- .. code:: php
- <?php
- ...
-
- $client = Client::getInstance();
- $client->getProcedureLoader()->addLoader($procedureLoader);
-
- ...
- The last thing you need to do is to tell the request which script you
- want to load for that request. This is done by setting the request type
- to the name of your procedure file, minus the extension:
- .. code:: php
- <?php
- ...
-
- $request = $client->getMessageFactory()->createRequest();
- $request->setType('my_procedure');
-
- ...
- Or if you are using a custom request as outlined in the `custom request
- parameters <#using-custom-request-parameters-in-your-script>`__ section,
- you can implement a ``getType()`` method which returns the name of your
- procedure, eliminating the need to set the request type for each
- request:
- .. code:: php
- <?php
- use JonnyW\PhantomJs\Message\Request;
-
- class CustomRequest extends Request
- {
-
- public function getType()
- {
- return 'my_procedure';
- }
- }
- Below is a full example for clarity:
- .. code:: php
- <?php
-
- use JonnyW\PhantomJs\Client;
- use JonnyW\PhantomJs\DependencyInjection\ServiceContainer;
-
- $location = '/path/to/your/procedure/directory';
-
- $serviceContainer = ServiceContainer::getInstance();
-
- $procedureLoader = $serviceContainer->get('procedure_loader_factory')
- ->createProcedureLoader($location);
-
- $client = Client::getInstance();
- $client->getProcedureLoader()->addLoader($procedureLoader);
-
- $request = $client->getMessageFactory()->createRequest();
- $request->setType('my_procedure');
-
- $response = $client->getMessageFactory()->createResponse();
-
- $client->send($request, $response);
- Troubleshooting
- ^^^^^^^^^^^^^^^
- If you find that your script isn't running or that you are receiving
- a status of '0' back in the response, chances are you have a syntax
- error in you script. It pays to turn debugging on in the client
- ``$client->debug(true)`` which will then give you access to some log
- information through ``$client->getLog()``.
- See more detailed information about
- `debugging <{{%20site.BASE_PATH%20}}/debugging.html>`__.
|