背景
- 以前已經使用golang寫過調用phantomjs的文章
- CTO不讓我使用golang因此只好使用php調用phantomjs
- packagist上的composer包功能很冗餘,我只須要用到phantomjs的截圖功能
知識儲備
代碼(php 代碼環境爲yii2框架)
<?php
namespace weapp\library\phantomjs;
use weapp\library\BizException;
class ScreenShot
{
/** @var string 獲取phantomjs 參數中 js文件的決定路徑 */
private $js_path;
/** @var bool|string 獲取php 有777權限的臨時文件目錄 */
private $temp_dir;
function __construct()
{
$dir = __DIR__;
$this->js_path = "{$dir}/script.js";
/** @var bool|string 獲取php 有777權限的臨時文件目錄 */
$this->temp_dir = \Yii::getAlias('@runtime');
}
/**
* 截圖並上傳
* @param string $url
* @param string $filename
* @return string
* @throws BizException
*/
public function screenShotThenSaveToOss(string $url, string $filename = 'temp.jpg')
{
//輸出圖片的路徑
$outputFilePath = "{$this->temp_dir}/$filename";
//執行的phantomjs命令
//phantomjs 可執行文件必須是 絕對路徑 不然致使 exec 函數返回值127錯誤
$cmd = "\usr\local\bin\phantomjs {$this->js_path} '$url' '$outputFilePath'";
//捕捉不到phantomjs命令輸出結果
exec($cmd, $output);
//檢查截圖文件是否存在
$isShotImgaeExist = file_exists($outputFilePath);
if (!$isShotImgaeExist) {
throw new BizException(0, 'phantomjs截圖失敗', BizException::SELF_DEFINE);
}
//保存截圖到oss
$result = $this->postScreenShotImageToOss($outputFilePath);
//刪除臨時文件夾的截圖圖片
unlink($outputFilePath);
return $result;
}
/**
* 上傳截圖到阿里雲直傳oss
* @param string $screenshot_path
* @return string
*/
public function postScreenShotImageToOss(string $screenshot_path): string
{
$ossKey = 'raw_file_name';
$file = new \CURLFile($screenshot_path, 'image/jpeg', 'file');
$tokenArray = $this->getOssPolicyToken('fetch');
$url = $tokenArray->host;
$postData = [
'key' => "{$tokenArray->dir}/$ossKey",
'policy' => $tokenArray->policy,
'OSSAccessKeyId' => $tokenArray->accessid,
'success_action_status' => '200',
'signature' => $tokenArray->signature,
'callback' => $tokenArray->callback,
'file' => $file
];
$ch = curl_init();
//$data = array('name' => 'Foo', 'file' => '@/home/user/test.png');
curl_setopt($ch, CURLOPT_URL, $url);
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true); // required as of PHP 5.6.0
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
//curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: $mime_type"]);
$res = curl_exec($ch);
$res = json_decode($res);
curl_close($ch);
if (empty($res) || $res->code != 0) {
return '';
} else {
return $res->data->url;
}
}
/**
* 調用管理後臺阿里雲oss token接口
* @param null $url
* @return array
*/
public function getOssPolicyToken($url = null)
{
$url = \Yii::$app->params['oss_screen_shot_token_api'];
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL, $url);
// Execute
$result = curl_exec($ch);
// Closing
curl_close($ch);
$res = json_decode($result);
if (empty($res) || $res->code != 0) {
return [];
} else {
return $res->data;
}
}
}
phantomjs javascript腳本內容
"use strict";
var system = require('system');
var webPage = require('webpage');
var page = webPage.create();
//設置phantomjs的瀏覽器user-agent
page.settings.userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
//獲取php exec 函數的命令行參數
if (system.args.length !== 3) {
console.log(system.args);
console.log('參數錯誤');
console.log('第2個參數爲url地址 第3個參數爲截圖文件名稱');
phantom.exit(1);
}
//命令行 截圖網址參數
var url = system.args[1];
//圖片輸出路徑
var filePath = system.args[2];
console.log('-------');
console.log(url);
console.log('-------');
console.log(filePath);
console.log('-------');
//設置瀏覽器視口
page.viewportSize = {width: 480, height: 960};
//打開網址
page.open(url, function start(status) {
//1000ms以後開始截圖
setTimeout(function () {
//截圖格式爲jpg 80%的圖片質量
page.render(filePath, {format: 'jpg', quality: '80'});
console.log('success');
//退出phantomjs 避免phantomjs致使內存泄露
phantom.exit();
}, 1000);
});
php調用phantomjs目錄結構
