Thinkphp5.1模拟登录并提交form表单

远程登录 curl登录 php curl PHP模拟登录 curl模拟form

最近项目需要,要远程登录别人的系统,并且在对方的系统中提交表单,所以写了一个类。

<?php

namespace app\api\controller;


use think\Db;


use think\Controller;


use think\facade\Env;


use think\facade\Request;


class Offline extends Controller

{

//域名

public $baseUrl = 'http://localhost:8080';

//登录错误返回的链接

public $loginErrorUrl = '/login';

//登录验证

public $loginUrl = '/check';

//登录成功跳转

public $loginSuccessUrl = '/loginSuccess';

//提交表单

public $orderUrl = '/save';

//提交表单返回页面URL

public $formUrl = '/proposal';

    //下载URL

    public $downloadUrl             = '/downloads';

    //记录登录返回的cookie

    public $cookieFile;

    //日志

    public $logFile;


    protected function initialize()

    {

        parent::initialize();

        $this->cookieFile            = Env::get('root_path') .'runtime/success_cookie.txt';

        $this->logFile               = Env::get('root_path') .'runtime/offline_log.txt';

    }

/**

     * @function    online

     * @intro        模拟form提交表单

     * @return  string

     */

    public function online()

    {

    $ch                   = curl_init($this->baseUrl.$this->formUrl);

        curl_setopt($ch,CURLOPT_COOKIEFILE, $this->cookieFile); //同时发送Cookie

        curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);

        $headers                    = curl_getinfo($ch);

        curl_close($ch);

        //通过返回的header里的url来判断登录状态

        if(strpos($this->loginErrorUrl, $headers['url'])){

        return 'login_fail';

        }

        //跟进传过来的ID去查询订单内容

        $orderId                             = input('id');

        //订单信息

        $order                                          = db('order')->where(['id'=>$orderId])->find();

        $form     = [];

        $form['name']                             = $order['title'];

        $form['type']                             = 1;

        //提交表单

        $headersandcontent                              = $this->curlPostForm($this->baseUrl.$this->orderUrl, $this->cookieFile, $form);

        $headers = $headersandcontent['header'];

        $content = strip_tags($headersandcontent['content']);//过滤html标签

        $content = preg_replace("/<(script.*?)>(.*?)<(\/script.*?)>/si","",$content);//过滤script标签

        $content = preg_replace("/\s+/", " ", $content);//过滤回车

        $content = str_replace('&nbsp;', '', $content);//过滤空格

        $this->log(json_encode($headers));

        $this->log($content);

        //对返回的内容进行判断

        if(strpos($headers['url'], $this->orderUrl)){

            return 'success';

        }else{

            return 'fail';

        }

    }

    //下载PDF

    public function downloadpdf($no){

        $url    = $this->baseUrl.$this->downloadUrl.'?no='.$no;

        $save_path                                  = Env::get('root_path').'public/uploads/pdf/';

        $filename                                   = $no.'.pdf';

        $content                                    = $this->curlDownloadFile($url,$this->cookieFile);

        // 保存文件到制定路径

        $length = file_put_contents($save_path.$filename, $content);

        if($length == 0){

            unlink($save_path.$filename);

            if(!empty($content)){

                $fp2 = @fopen($save_path . $filename, 'a');

                fwrite($fp2, $content);

                fclose($fp2);

            }

        }

        return true;

    }

    //模拟登录

    public function login(){

    $arr['username']  = '11111';

        $arr['password']  = 'aaaa';

        //模拟登录,抓取返回值里的URL

        $headers            = $this->curlPost($this->baseUrl.$this->loginUrl, $this->cookieFile, $arr);

        //登录成功

        if(strpos($headers['url'], $this->loginSuccessUrl)){

        return 'success';

        }else{

        return 'fail';

        }

    }

    //记录日志

    public function log($str){

        $fp = fopen($this->logFile, 'a+');

        fwrite($fp, date("Y-m-d H:i:s").' '.$str." \r\n");

        fclose($fp);

    }


    /**

* 模拟登录

* @param string $url 提交到的地址

* @param string $cookie 保存cookie的文件

* @param string $arr 提交时要post的参数

* @return string $headers 返回的内容

*/

public function curlPost($url, $cookie, $arr=''){

  $ch = curl_init();

  curl_setopt($ch, CURLOPT_URL, $url);

  curl_setopt($ch, CURLOPT_HEADER, 0);

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

  if(!empty($arr)){

    curl_setopt($ch, CURLOPT_POST, 1);

    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arr)); //提交查询信息

  }

  //若给定url自动跳转到新的url,有了下面参数可自动获取新url内容:302跳转

  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

  //设置cURL允许执行的最长秒数。

  curl_setopt($ch, CURLOPT_TIMEOUT, 300);

  curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36');

  curl_setopt($ch, CURLOPT_REFERER, $url);

  curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); //把返回来的cookie信息保存在$cookie文件中

  curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

  $content = curl_exec($ch);

  //获取请求返回码,请求成功返回200

  $code = curl_getinfo($ch,CURLINFO_HTTP_CODE);

  //获取一个cURL连接资源句柄的信息。

  //$headers 中包含跳转的url路径 

  $headers = curl_getinfo($ch);

  curl_close($ch);

  return $headers;

}

    /**

     * 提交表单

     * @param string $url 提交到的地址

     * @param string $cookie 保存cookie的文件

     * @param string $arr 提交时要post的参数

     * @return string $headers 返回的内容

     */

    public function curlPostForm($url, $cookie, $arr=''){

        $headers = array('Content-Type: application/x-www-form-urlencoded');

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_HEADER, 0);

        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); //同时发送Cookie

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_POST, 1);

        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arr)); //提交查询信息

        //若给定url自动跳转到新的url,有了下面参数可自动获取新url内容:302跳转

        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

        //设置cURL允许执行的最长秒数。

        curl_setopt($ch, CURLOPT_TIMEOUT, 300);

        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36');

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $headers    = curl_getinfo($ch);

        $content    = curl_exec($ch);

        curl_close($ch);

        return ['header'=>$headers,'content'=>$content];

    }

    /**

     * 下载

     * @param string $url 地址

     * @param string $cookie 保存cookie的文件

     * @return string $content 返回的内容

     */

    public function curlDownloadFile($url, $cookie){

        $headers = array('Content-Type: application/x-www-form-urlencoded');

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_HEADER, 0);

        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); //同时发送Cookie

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        //设置cURL允许执行的最长秒数。

        curl_setopt($ch, CURLOPT_TIMEOUT, 300);

        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36');

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $content    = curl_exec($ch);

        curl_close($ch);

        return $content;

    }

}

这里的返回值基本都是html内容所以我这边是判断的返回值里的URL是不是匹配,可以根据需要调整。