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;
}
}
}
?>

User Contributed Notes 4
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
Leave a comment
If you have any questions, please ask in the forum instead.
Join the conversation to share a note.