This is a web service which is implemented as an action to take screenshot of a website & return the file content to web service consumer.
For those of you who do not know how to use phantomjs to take screenshot of a web page dynamically, please refer to this article (the "Rendering" example).
Let's assume you have phantomjs installed on server A to take screenshot of a web site. Now you are implementing 2 web applications that need the functionality that server A does. These 2 applications are going to be deployed on server B & C. So, instead of installing phantomjs on server B & C again, a web service is implemented on server A so that you can use this functionality from anywhere. This web service is implemented as a Yii action and will return the content of the screenshot which then can be saved as a jpg image. This web service is going to be called using curl.
Requirements ¶
Yii 1.1 or above
Usage ¶
Copy & paste the extension into protected/extension. Then create an action to set up the web service & another action to call this web service. I implement these 2 actions in 1 controller for simplicity.
<?php
class TestPhantomController extends CController {
public function actions(){
return array(
"takeScreenshot" => array(
"class" => "ext.phantomjs.EWebScreenshotAction",
"username" => "username", // username to use this web service
"password" => "password", // password to use this web service
"allowedIps" => array(), // restricted to some IPs only, leave blank for any IP
)
);
}
public function actionTestScreenshot() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->createAbsoluteUrl("/test/takeScreenshot"));
$fields = array(
"username" => "username",
"password" => "password",
"webUrl" => "http://www.google.com",
);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpStatus == 200 && ! empty($result)) {
file_put_contents("C:/test.jpg", $result);
} else { // Error occurred
echo $result;
}
}
}
?>
Nice feature
Good to know there is phantomjs library! I have never heard about this....
Great Extensión, i give my experience
We are running a project in a Linux Server we have some problems using the Web Service solution, and we don't have time to fix this probem, meanwhile we created a Class into the Extension
//***** / Put this class into the phantomjs extension directory //***** <?php class PDFmaker { // The command to run phantomjs public $phantomjsCommand = "phantomjs"; /** * Make a PDF from URL of File Path * @param string $webUrl URL or File Path * @return string PDF File Content */ public function saveFromPath($webUrl) { $tempFolder = Yii::getPathOfAlias("application"). "/runtime"; $screenshotFileName = $tempFolder . "/" . uniqid() . ".pdf"; $phantomjsCommand = $this->phantomjsCommand . " " . dirname(__FILE__) . "/js/rasterize.js " . $webUrl . " " . $screenshotFileName; exec($phantomjsCommand); $status = false; $fileContent = ""; if (file_exists($screenshotFileName)) { $status = true; $fileContent = file_get_contents($screenshotFileName); // Remove file unlink($screenshotFileName); } return $fileContent; } /** * Make a PDF from String Content * @param string $htmlContent URL or File Path * @return string PDF File Content */ public function saveFromContent($htmlContent) { $tempFolder = Yii::getPathOfAlias("application"). "/runtime"; $screenshotFileName = $tempFolder . "/" . uniqid() . ".pdf"; $tempContentFile = $tempFolder . "/" . uniqid() . ".tmp"; $fh = fopen($tempContentFile, 'w') or die("can't open file"); fwrite($fh, $htmlContent); fclose($fh); $phantomjsCommand = $this->phantomjsCommand . " " . dirname(__FILE__) . "/js/rasterize.js " . $tempContentFile . " " . $screenshotFileName; exec($phantomjsCommand); $status = false; $fileContent = ""; if (file_exists($screenshotFileName)) { $status = true; $fileContent = file_get_contents($screenshotFileName); // Remove file unlink($tempContentFile); unlink($screenshotFileName); } return $fileContent; } } ?> /***** /Register the class into the project (protect/main.php) -- Section "import" 'import'=>array( 'OTHER FILES YYY', 'OTHER FILES ZZZ', 'ext.phantomjs.PDFmaker' ), //***** //**************** //Example of usage //**************** public funtion actionExport() { $htmlContent = '<p>Hello World</p>'; $pdf = new PDFmaker(); $str = $pdf->saveFromContent($htmlContent); $outputFileName = 'pairwise_comparison_'.date('YmdH').'.pdf'; header('Content-Type: application/pdf'); header('Content-Length: '.strlen($str)); header('Content-Disposition: inline; filename="'.$outputFileName.'"'); header('Cache-Control: private, max-age=0, must-revalidate'); header('Pragma: public'); ini_set('zlib.output_compression','0'); die($str); }
Bye
Reliability in Production?
Luckas,
Thanks for your post! Has this been deployed in a production environment? We are needing to do exactly what you are doing, with a few charting/graphing libraries. Have you experienced and reliability problems using this method?
Reply: Reliability in Production?
Hi w00tw00t111, we are using the class into production environment, the software is not public, but i can say that's working great, with the example that i have wrote you can convert any html (with img, flash, svg) into pdf, we have have some problems with the height of the page, but it's a problem of webkit engine that we are using, the server it's a windows server 2008. if you have any problem post it and we can help you
Bye
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.