<?php /** * 这是一个自动化部署的类, 非常简单,思想就是压缩,上传,然后解压覆盖,所以请小心使用. * @author liuchao <249757247@qq.com> * @date 2019-07-10 */ /** * 配置 */ $SECRET_KEY = 'whatthefuck'; $config = array( 'upload_url' => 'http://tmp.szydweixin.com/deploy_110.php?key=' . $SECRET_KEY, 'folders' => array( #'../application/controllers/', #'../application/libraries/', #'../application/models/' // '../application/config/api.php', // '../application/services/wx_user_service.php', // '../application/config/constants.php', // '../application/controllers/scene_code.php', // '../application/libraries/Strategy/BOSS/SZ/Balance_Strategy.php', '../t.php', // '../application/libraries/AES.php', // '../application/libraries/Scenes_code.php' // '../application/controllers/h5/auto_login.php', // '../application/controllers/schedule/contact_marketing_worker.php', // '../application/libraries/Strategy/Event/Subscribe_Strategy.php', // '../application/libraries/Strategy/Event/Scan_Strategy.php', // '../application/views/scene_code/add.php', // '../application/views/scene_code/index.php', // '../application/views/scene_code/scan_record.php', // '../application/views/second_marketing/edit_act.php', // '../application/views/wx_bind_setting/change_data.php', // '../application/views/wx_bind_setting/change_detail.php', // '../application/views/wx_bind_setting/reset_data.php', // '../application/views/h5/mobi/bind2.php', // '../static/js/h5_mobi/bind.js', ), ); // 开始干活 if ($_FILES) { if (!isset($_GET['key']) || $_GET['key'] != $SECRET_KEY) { die('invalid request.'); } $deploy = new DeployServer(); $deploy->deploy($_FILES); } else if (isset($_SERVER["argv"][1]) && $_SERVER["argv"][1] == 'start'){ $deploy = new DeployClient($config); $deploy->deploy(); } else { die('you know. I am here...'); } /** * 部署客户端类 */ class DeployClient { private $config; public function __construct($config) { $this->config = $config; } public function deploy() { $tmp_dir = __DIR__ . '/' . md5(time()) . '.zip'; // 生成压缩文件 $zip = new ZipHelper(); $zip->zip($this->config['folders'], $tmp_dir); echo $this->_post($this->config['upload_url'], $tmp_dir); unlink($tmp_dir); } private function _post($url, $file) { $file = array("file" => "@" . $file); //文件路径,前面要加@,表明是文件上传. $curl = curl_init($url); curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false); //php5.6默认是true,即禁用了使用@文件上传。php7.0废弃了CURLOPT_SAFE_UPLOAD,建议用curl_file_create函数或CURLFile类 curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $file); return curl_exec($curl); } } /** * 部署服务器类 */ class DeployServer { public function deploy($files) { // step 1: 保存文件 $tmp_dir = "tools/" . $_FILES["file"]["name"]; move_uploaded_file($files["file"]["tmp_name"], $tmp_dir); // step 2: 解压并覆盖文件 $zip = new ZipHelper(); $zip->unzip($tmp_dir, __DIR__ . '/'); // step 3: 删除临时文件 unlink($tmp_dir); return true; } } /** * 压缩文件,解压文件类 */ class ZipHelper { private $_zip; public function __construct() { $this->_zip = new ZipArchive(); } function unzip($unzip, $dst) { $res = $this->_zip->open($unzip); if ($res === true) { if (!$this->_zip->extractTo($dst)) { echo 'extract fail to ' . $dst; } $this->_zip->close(); } else { echo 'failed, code:' . $res; } } function zip($dirs, $dst) { $res = $this->_zip->open($dst, ZipArchive::CREATE); if ($res === true) { if (is_array($dirs)) { foreach ($dirs as $dir) { $this->_zip($dir, $this->_zip); } } else { $this->_zip($dirs, $this->_zip); } $this->_zip->close(); } else { echo 'failed'; } } private function _zip($dir, &$zip) { if (!is_dir($dir)) { $zip->addFile($dir); return; } $dh = opendir($dir); while (($file = readdir($dh)) !== false) { if ($file == '.' || $file == '..') { continue; } if (filetype($dir . $file) == 'dir') { $this->_zip($dir . $file . '/', $zip); } else { $zip->addFile($dir . $file); } } } }
用curl_file_create函数配合curl实现文件上传,增强代码的健壮性
<?php if (!function_exists('curl_file_create')) { function curl_file_create($filename, $mimetype = '', $postname = '') { return "@$filename;filename=" . ($postname ?: basename($filename)) . ($mimetype ? ";type=$mimetype" : ''); } } $ch = curl_init(); $filename1 = 'E:/html/pim/php_weili_activities/uploads/activity_13_1547717462.jpg'; $filename2 = 'E:/html/pim/php_weili_activities/uploads/activity_13_1546510239_thumb.jpg'; $minetype1 = 'image/jpeg'; $minetype2 = 'image/jpeg'; $curl_file1 = curl_file_create($filename1,$minetype1,pathinfo($filename1,PATHINFO_BASENAME)); $curl_file2 = curl_file_create($filename2,$minetype2,pathinfo($filename2,PATHINFO_BASENAME)); $postData = [ 'file' => '111', 'text' => '666', //'file'=>$curl_file1, //单个文件上传 'file[0]'=>$curl_file1, //多个文件上传 'file[1]'=>$curl_file1, //多个文件上传 ]; curl_setopt($ch, CURLOPT_URL, 'http://localhost/phpinfo.php'); //curl结果不直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //发送post 请求 curl_setopt($ch, CURLOPT_POST, 1); // urlencoded 后的字符串,类似'para1=val1¶2=val2&...',也可以使用一个以字段名为键值,字段数据为值的数组 ,测试当值为数组时候 Content-Type头将会被设置成multipart/form-data 否则Content-Type 头会设置为 application/x-www-form-urlencoded curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); //数组时候,以multipart/form-data提交 //curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); //application/x-www-form-urlencoded提交 //允许 cURL 函数执行的最长秒数 curl_setopt($ch, CURLOPT_TIMEOUT, 50); //不输出header 头信息 curl_setopt($ch, CURLOPT_HEADER,0); //输出请求头 curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE); //输出请求头,用curl_getinfo获取请求头 //不验证证书 信任任何证书 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 检查证书中是否设置域名,0不验证 0:不检查通用名称(CN)属性 //1:检查通用名称属性是否存在 //2:检查通用名称是否存在,是否与服务器的主机名称匹配 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //设置 在HTTP请求中包含一个"User-Agent: "头的字符串 //curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); $res = curl_exec($ch); $error_no = curl_errno($ch); $info = curl_getinfo($ch); $err_msg = ''; if ($error_no) { $err_msg = curl_error($ch); } else { print_r($res); //var_dump($info); //CURLINFO_HEADER_OUT选项为true设置下,可获取请求头信息 } curl_close($ch);
curl_getinfo信息
Array
(
[url] => http://localhost/phpinfo.php
[content_type] => text/html; charset=utf-8
[http_code] => 200
[header_size] => 237
[request_size] => 191
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 1.547
[namelookup_time] => 0.016
[connect_time] => 0.016
[pretransfer_time] => 0.437
[size_upload] => 30066
[size_download] => 837
[speed_download] => 541
[speed_upload] => 19435
[download_content_length] => -1
[upload_content_length] => 30066
[starttransfer_time] => 0.453
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => ::1
[certinfo] => Array
(
)
[primary_port] => 80
[local_ip] => ::1
[local_port] => 63148
[request_header] => POST /phpinfo.php HTTP/1.1
Host: localhost
Accept: */*
Content-Length: 30066
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------c7de087ef011a0f8
)
$_FILES, $_POST
Array ( [file] => 111 [text] => 666 ) Array ( [file] => Array ( [name] => Array ( [0] => activity_13_1547717462.jpg [1] => activity_13_1547717462.jpg ) [type] => Array ( [0] => image/jpeg [1] => image/jpeg ) [tmp_name] => Array ( [0] => C:\Windows\phpD6C8.tmp [1] => C:\Windows\phpD6D8.tmp ) [error] => Array ( [0] => 0 [1] => 0 ) [size] => Array ( [0] => 14753 [1] => 14753 ) ) )
说明:$content =
file_get_contents
(
"php://input"
) 不可以获取multipart/form-data的数据,可以获取application/x-www-form-urlencoded的数据