当前位置: 首页 > news >正文

PHP中的curl详细解析和常见大坑

这篇文章主要介绍了 PHP 中使用 CURL 之 php curl 详细解析和常见大坑 ,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧。好啦,长话短说再长说,祭出今天的工具——CURL(Client URL Library),当然今天以 PHP 的方式来使用这件工具。

前言:curl 是个什么东西

PHP supports libcurl, a library created by Daniel Stenberg, that allows you to connect and communicate to many different types of servers with many different types of protocols. libcurl currently supports the http, https, ftp, gopher, telnet, dict, file, and ldap protocols. libcurl also supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading (this can also be done with PHP’s ftp extension), HTTP form based upload, proxies, cookies, and user+password authentication.

这是 PHP 对于 curl 的一个解释,简单地说就是,curl 是一个库,能让你通过 URL 和许多不同种的服务器进行勾搭、搭讪和深入交流,并且还支持许多协议。并且人家还说了 curl 可以支持 https 认证、http post、ftp 上传、代理、cookies、简单口令认证等等功能啦。

说了那么多其实没什么感觉吧,在应用中才有感觉,我起初也是需要在服务器端向另一个服务器发起一个 POST 请求才开始接触 curl 的,然后才有了感觉。

在正式讲怎么用之前啊,先提一句,你得先在你的 PHP 环境中安装和启用 curl 模块,具体方式我就不讲了,不同系统不同安装方式,可以 google 查一下,或者查阅 PHP 官方的文档,还挺简单的。

1. 拿来先试试手

工具到手,先要把玩,试试顺不顺手,不然一拿来就用,把你自己的代码搞得乌烟瘴气还怎么去撩服务器呢?

比如我们以著名的 “测试网络是否连接” 的网站——百度为例,来尝试下 curl

    // create curl resource$ch = curl_init();// set urlcurl_setopt($ch, CURLOPT_URL, "baidu.com");//return the transfer as a stringcurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// $output contains the output string$output = curl_exec($ch);//echo outputecho $output;// close curl resource to free up system resourcescurl_close($ch);

当你在本地环境浏览器打开这个 php 文件时,页面出现的是百度的首页,特么我刚才输入的 “localhost” 呢?

上面的代码和注释已经充分说明了这段代码在干啥。

$ch = curl_init(),创建了一个 curl 会话资源,成功返回一个句柄;
curl_setopt($ch, CURLOPT_URL, "baidu.com"),设置 URL,不用说;

上面两句可以合起来变一句$ch = curl_init("baidu.com")

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0)这是设置是否将响应结果存入变量,1 是存入,0 是直接 echo 出;

$output = curl_exec($ch)执行,然后将响应结果存入$output变量,供下面 echo;

curl_close($ch)关闭这个 curl 会话资源。

PHP 中使用 curl 大致就是这么一个形式,其中第二步,通过curl_setopt方法来设置参数是最复杂也是最重要的,感兴趣可以去看官方的关于可设置参数的详细参考,长地让你看得想吐,还是根据需要熟能生巧吧。

小结一下,php 中 curl 用法就是:创建 curl 会话 -> 配置参数 -> 执行 -> 关闭会话。

下面我们来看一些常用的情景,我们需要如何 “打扮自己”(配置参数)才能正确 “撩妹”(正确撩到服务器)。

2. GET 和 POST 请求以及 HTTPS 协议处理

先和服务器打个招呼吧,给服务器发个 Hello 看她怎么回,这里最方便的方式就是向服务器发出 GET 请求,当然 POST 这种小纸条也 OK 咯。

2.1 GET 请求

我们以 “在某著名同性交友网站 github 中搜索关键词” 为例

// 通过curl进行GET请求的案例
// create curl resource
$ch = curl_init();// set url
curl_setopt($ch, CURLOPT_URL, "https://github.com/search?q=react");//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// $output contains the output string
$output = curl_exec($ch);//echo output
echo $output;// close curl resource to free up system resources
curl_close($ch);

好像和之前那个例子没啥差别,但这里有 2 个可以提的点:

  1. 默认请求方式是 GET,所以不需要显式指定 GET 方式;
  2. https 请求,非 http 请求,可能有人在各个地方看到过 HTTPS 请求需要加几行代码绕过 SSL 证书的检查等方式来成功请求到资源,但是这里好像并不需要,原因是什么?

The two Curl options are defined as:

CURLOPT_SSL_VERIFYPEER - verify the peer's SSL certificate 
CURLOPT_SSL_VERIFYHOST - verify the certificate's name against host

They both default to true in Curl, and shouldn’t be disabled unless you’ve got a good reason. Disabling them is generally only needed if you’re sending requests to servers with invalid or self-signed certificates, which is only usually an issue in development. Any publicly-facing site should be presenting a valid certificate, and by disabling these options you’re potentially opening yourself up to security issues.

即,除非用了非法或者自制的证书,这大多数出现在开发环境中,你才将这两行设置为false以避开 ssl 证书检查,否者不需要这么做,这么做是不安全的做法。

2.2 POST 请求

那如何进行 POST 请求呢?为了测试,先在某个测试服务器传了一个接收 POST 的脚本:

//testRespond.php
$phpInput=file_get_contents('php://input');
echo urldecode($phpInput);

发送普通数据

然后在本地写一个请求:

$data=array("name" => "Lei","msg" => "Are you OK?"
);$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://测试服务器的IP马赛克/testRespond.php");
curl_setopt($ch, CURLOPT_POST, 1);//The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_POSTFIELDS , http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);
echo $output;
curl_close($ch);

浏览器运行结果是:

name=Lei&msg=Are you OK?

这里我们是构造了一个数组作为 POST 数据传给服务器:

  • curl_setopt($ch, CURLOPT_POST, 1)表明是 POST 请求;

  • curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60)设置一个最长的可忍受的连接时间,秒为单位,总不能一直等下去变成木乃伊吧;

  • curl_setopt($ch, CURLOPT_POSTFIELDS , http_build_query($data))设置 POST 的数据域,因为这里是数组数据形式的(等会来讲 json 格式),所以用http_build_query处理一下。

对于 json 数据呢,又怎么进行 POST 请求呢?

$data='{"name":"Lei","msg":"Are you OK?"}';$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://测试服务器的IP马赛克/testRespond.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length:' . strlen($data)));
curl_setopt($ch, CURLOPT_POSTFIELDS , $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);
echo $output;
curl_close($ch);

浏览器执行,显示:

{"name":"Lei","msg":"Are you OK?"}

3. 如何上传和下载文件

已经和服务器勾搭上了,这时候得要个照片来看一看了吧,你也得把自己的照片发上去让人看一看了,虽然两个人在一起外貌不重要,但是男俊女靓总是最棒的。

3.1 POST 上传文件

同样远程服务器端我们先传好一个接收脚本, 接收图片并且保存到本地,注意文件和文件夹权限问题,需要有写入权限:

if($_FILES){$filename = $_FILES['upload']['name'];$tmpname = $_FILES['upload']['tmp_name'];//保存图片到当前脚本所在目录if(move_uploaded_file($tmpname,dirname(__FILE__).'/'.$filename)){echo ('上传成功');}}

然后我们再来写我们本地服务器的php curl部分:

$data = array('name'=>'boy', "upload"=>"@boy.png");$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://远程服务器地址马赛克/testRespond.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_POSTFIELDS , $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);
echo $output;
curl_close($ch);

浏览器中运行一下,什么都米有,去看一眼远程的服务器,还是什么都没有,并没有上传成功。

为什么会这样呢?
上面的代码应该是大家搜索curl php POST图片最常见的代码,这是因为我现在用的是 PHP5.6 以上版本,@符号在PHP5.6之后就弃用了,PHP5.3依旧可以用,所以有些同学发现能执行啊,有些发现不能执行,大抵是因为 PHP 版本的不同,而且 curl 在这两版本中实现是不兼容的,上面是PHP5.3的实现。

下面来讲 PHP5.6 及以后的实现,:

$data = array('name'=>'boy', "upload"=>"");$ch = curl_init();
$data['upload']=new CURLFile(realpath(getcwd().'/boy.png'));curl_setopt($ch, CURLOPT_URL, "http://115.29.247.189/test/testRespond.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_POSTFIELDS , $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);
echo $output;
curl_close($ch);

这里引入了一个CURLFile对象进行实现,关于此的具体可查阅文档进行了解。这时候再去远程服务器目录下看看,发现有了一张图片了,而且确实是我们刚才上传的图片。

3.2 获取远程服务器妹子的照片 —— 抓取图片

服务器妹子也挺实诚的,看了照骗觉得我长得挺慈眉善目的,就大方得拿出了她自己的照片,但是有点害羞的是,她不愿意主动拿过来,得我们自己去取。

远程服务器在她自己的目录下存放了一个图片叫girl.jpg,地址是她的web服务器根目录/girl.jpg,现在我要去获取这张照片。

$ch = curl_init();$fp=fopen('./girl.jpg', 'w');
curl_setopt($ch, CURLOPT_URL, "http://远程服务器地址马赛克/girl.jpg");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_FILE, $fp);$output = curl_exec($ch);
$info = curl_getinfo($ch);fclose($fp);
$size = filesize("./girl.jpg");
if ($size != $info['size_download']) {echo "下载的数据不完整,请重新下载";
} else {echo "下载数据完整";
}curl_close($ch);

现在,在我们当前目录下就有了一张刚拿到的照片啦,是不是很激动呢!

这里值得一说的是curl_getinfo方法,这是一个获取本次请求相关信息的方法,对于调试很有帮助,要善用。

4. HTTP 认证怎么搞

这个时候呢,服务器的家长说这个我们女儿还太小,不能找对象,就将她女儿关了起来,并且上了一个密码锁,所谓的 HTTP 认证,服务器呢偷偷托信鸽将 HTTP 认证的用户名和密码给了你,要你去见她,带她私奔。

那么拿到了用户名和密码,我们怎么通过PHP CURL搞定 HTTP 认证呢?

PS: 这里偷懒就不去搭 HTTP 认证去试了,直接放一段代码,我们分析下。

function curl_auth($url,$user,$passwd){$ch = curl_init();curl_setopt_array($ch, [CURLOPT_USERPWD => $user.':'.$passwd,CURLOPT_URL     => $url,CURLOPT_RETURNTRANSFER => true]);$result = curl_exec($ch);curl_close($ch);return $result;
}$authurl = 'http://要请求HTTP认证的地址';
echo curl_auth($authurl,'vace','passwd');

这里有一个地方比较有意思:
curl_setopt_array 这个方法可以通过数组一次性地设置多个参数,防止有些需要多处设置的出现密密麻麻的curl_setopt方法。

5. 利用 cookie 模拟登陆

这时你成功见到了服务器妹子,想带她私奔,但是无奈没有盘缠走不远,服务器妹子说,她妈服务器上有金库,可以登陆上去搞一点下来。

首先我们先来分析一下,这个事情分两步,一是去登陆界面通过账号密码登陆,然后获取 cookie,二是去利用 cookie 模拟登陆到信息页面获取信息,大致的框架是这样的。

//设置post的数据 $post = array ('email' => '账户','pwd' => '密码');//登录地址 $url = "登陆地址"; //设置cookie保存路径 $cookie = dirname(__FILE__) . '/cookie.txt'; //登录后要获取信息的地址 $url2 = "登陆后要获取信息的地址"; //模拟登录login_post($url, $cookie, $post); //获取登录页的信息 $content = get_content($url2, $cookie); //删除cookie文件@unlink($cookie);var_dump($content);

然后我们思考下下面两个方法的实现:

  • login_post($url, $cookie, $post)

  • get_content($url2, $cookie)

//模拟登录
function login_post($url, $cookie, $post) {$curl = curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);curl_setopt($curl, CURLOPT_POST, 1);curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));curl_exec($curl);curl_close($curl);
}//登录成功后获取数据 function get_content($url, $cookie) {$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);$rs = curl_exec($ch);curl_close($ch);return $rs;
}

至此,总算是模拟登陆成功,一切顺利啦,通过php CURL“撩” 服务器就是这么简单。

当然,CURL的能力远不止于此,本文仅希望就后端 PHP 开发中最常用的几种场景做一个整理和归纳。最后一句话,具体问题具体分析。​​​​​​​

相关文章:

PHP中的curl详细解析和常见大坑

这篇文章主要介绍了 PHP 中使用 CURL 之 php curl 详细解析和常见大坑 ,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧。好啦,长话短说再长说,祭出今天的工具——CURL(Client URL Library),当然今天以 PHP…...

[python] 使用Jieba工具中文分词及文本聚类概念

前面讲述了很多关于Python爬取本体Ontology、消息盒InfoBox、虎扑图片等例子,同时讲述了VSM向量空间模型的应用。但是由于InfoBox没有前后文和语义概念,所以效果不是很好,这篇文章主要是爬取百度5A景区摘要信息,再利用Jieba分词工…...

常见程序搜索关键字转码

个别搜索类的网站因为用户恶意搜索出现误拦截情况,这类网站本身没有非法信息,只是因为把搜索关键字显示在网页中(如下图),可以参考下面方法对输出的关键字进行转码 DEDECMS程序 本文针对Dedecms程序进行搜索转码&…...

细谈商品详情API接口设计

一、引言 随着互联网技术的发展,商品详情信息的展示和交互变得越来越重要。为了提供更好的用户体验,我们需要设计一套高效、稳定且易于扩展的商品详情API接口。本文将详细探讨商品详情API接口的设计,包括接口的通用性、安全性和扩展性等方面…...

Go 1.21新增的内置函数(built-in functions)详解

Go 1.21新增的内置函数分别是 min、max 和 clear,接下来看下这几个函数的用途和使用示例。 在编程过程中,需要知道一组值中的最大或最小值的场景是很常见的,比如排序、统计等场景。之前都需要自己写代码来实现这个功能,现在 Go 1…...

【云原生,k8s】基于Helm管理Kubernetes应用

第四阶段 时 间:2023年8月18日 参加人:全班人员 内 容: 基于Helm管理Kubernetes应用 目录 一、Kubernetes部署方式 (一)minikube (二)二进制包 (三)Kubeadm …...

字符设备驱动分布注册

驱动文件: 脑图: 现象:...

在Gazebo中添加悬浮模型后,利用键盘控制其移动方法

前段时间写了文章,通过修改sdf、urdf模型的方法,在Gazebo中添加悬浮模型方法 / Gazebo中模型如何不因重力下落:在Gazebo中添加悬浮模型方法 / Gazebo中模型如何不因重力下落:修改sdf、urdf模型_sagima_sdu的博客-CSDN博客 今天讲…...

Java设计模式 (一) 模板方法设计模式

什么是模板方法设计模式? 模板方法设计模式是一种行为型设计模式,它定义了一个算法的骨架,并将一些步骤的具体实现延迟到子类中。模板方法模式可以帮助确保在算法的不同部分中保持一致性,同时也允许子类根据需要进行具体实现。 模板方法模式…...

PHP在线客服系统推荐

在当今数字化时代,企业客户服务的重要性不容忽视。为了提供卓越的客户体验,许多企业正在寻找PHP在线客服系统。这种系统不仅可以满足客户的需求,还能提升企业的形象。本文将深入探讨PHP在线客服系统的一些有趣话题。 理解PHP在线客服系统 PHP…...

(三)行为型模式:3、解释器模式(Interpreter Pattern)(C++示例)

目录 1、解释器模式(Interpreter Pattern)含义 2、解释器模式的UML图学习 3、解释器模式的应用场景 4、解释器模式的优缺点 5、C实现解释器模式的实例 1、解释器模式(Interpreter Pattern)含义 解释器模式(Interp…...

Zookeeper 启动闪退

常见的大概这两种情况 1.找不到zoo.cfg文件 在下载zookeeper后,在 %zookeeper安装目录%/conf 目录下有一个zoo.sample.cfg 文件,把 zoo.sample.cfg 文件改名为 zoo.cfg 再重启zkServer.cmd echo off REM Licensed to the Apache Software Foundation …...

jenkins 安装nodejs 14

参考: jenkins容器安装nodejs-前端问答-PHP中文网...

K8S核心组件etcd详解(上)

1 介绍 https://etcd.io/docs/v3.5/ etcd是一个高可用的分布式键值存储系统,是CoreOS(现在隶属于Red Hat)公司开发的一个开源项目。它提供了一个简单的接口来存储和检索键值对数据,并使用Raft协议实现了分布式一致性。etcd广泛应用…...

STM32存储左右互搏 I2C总线FATS读写EEPROM ZD24C1MA

STM32存储左右互搏 I2C总线FATS读写EEPROM ZD24C1MA 在较低容量存储领域,EEPROM是常用的存储介质,可以通过直接或者文件操作方式进行读写。不同容量的EEPROM的地址对应位数不同,在发送字节的格式上有所区别。EEPROM是非快速访问存储&#xf…...

微服务—远程调用(RestTemplate)

在微服务的所有框架中,SpringCloud脱颖而出,它是目前国内使用的最广泛的微服务框架 (官网地址),它集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱…...

Fine tune简介

目录 Intro Related work Example .1 重新训练 .2 使用新的数据集进行fine tune .3 修改net结构 References 移学习不是一种算法而是一种机器学习思想,应用到深度学习就是微调(Fine-tune)。通过修改预训练网络模型结构(如修改样本类别输出个数),选择性载入预训练网络…...

centos nginx配置ipv4和ipv6的地址都可以访问同一个网站

标题centos nginx配置ipv4和ipv6的地址都可以访问同一个网站 在 Nginx 中配置使 IPv4 和 IPv6 地址都可以访问同一个网站相对简单。只需要确保 Nginx 配置文件正确地配置了监听 IPv4 和 IPv6 地址的监听器即可。 打开你的 Nginx 配置文件,通常位于 /etc/nginx/nginx…...

高教杯数学建模2020C题总结

🧡1. 前言🧡 跟队友花了三天模拟2020C题,现在整理一下一些数据处理的代码,以及在模拟中没有解决的问题。方便以后回溯笔记。 🧡2. 数据处理🧡 2.1 导入数据,并做相关预处理 import pandas a…...

Swagger

目录 简介 使用方式: 常用注解 简介 使用Swagger你只需要按照他的规范去定义接口及接口相关信息再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,以及在线接口调试页面等等。 官网:https://swagger…...

Android 13像Settings一样获取热点和网络共享

一.背景 由于客户定制的Settings里面需要获取到热点和网络共享状态,所以需要实现此功能。 目录 一.背景 二.前提条件 三.调用api 二.前提条件 首先应用肯定要是系统应用,并且导入framework.jar包,具体可以参考: Android 应用自动开启辅助(无障碍)功能并使用辅助(无障碍…...

操作系统搭建相关知识

文章目录 系统篇netstat命令systemctl命令Systemd系统资源分类(12类) 网络篇ifconfig命令操作系统配置动态IP脚本dhcp服务的安装与配置防火墙相关知识 操作系统常用配置文件 系统篇 netstat命令 netstat指路 systemctl命令 常用于重启系统的每个服务…...

【校招VIP】前端校招考点之vue底层特性

考点介绍: 大家在面试途中遇到的相对多的问题,也是难点的问题,一般都有vue底层原理。对于只会用但是不懂的小白来说真是太痛苦了,仅仅能说出来 一些 数据劫持,双向数据绑定,虚拟dom树的名词来说远远不够。 …...

vue3+vite配置vantUI主题

❓在项目中统一配置UI主题色,各个组件配色统一修改 vantUI按需安装 参考vantUI文档 创建vantVar.less文件夹进行样式编写 vantVar.less :root:root{//导航--van-nav-bar-height: 44px;//按钮--van-button-primary-color: #ffffff;--van-button-primary-backgr…...

C++基础语法——继承

1.继承是什么? 继承是一种面向对象编程的概念,它允许一个类(称为子类或派生类)从另一个类(称为基类或父类)继承属性和方法。继承使得子类能够使用基类已有的代码,并且可以在此基础上进行扩展或修…...

vim配置之spf13-vim

文章目录 vim配置:spf13-vim什么是spf13-vim安装*nix and os x安装 spf13-vim使用技巧或快捷键spf13的vim默认没有启用剪切板,需要在vimrc中设置 vim配置:spf13-vim 什么是spf13-vim 官网:http://vim.spf13.com/ 它是一个完全跨平台发布,保持vim的感觉…...

Azure如何启用网络观察应用程序

文章目录 基础概念介绍实操 基础概念介绍 Azure中的网络观察应用程序是一种用于监视和诊断Azure网络的工具。它提供了一种集中管理和监控网络流量、连接性和性能的方式。网络观察应用程序能够提供网络流量分析、连接监视、性能监视和故障诊断等功能,用于帮助管理员…...

分步注册方式 编写驱动

作业&#xff1a;通过分步注册方式&#xff0c;编写LED灯驱动&#xff1a;&#xff08;驱动文件mycdev.c 测试文件test.c 头文件head.h) mycdev.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/io.h> …...

repmgr出现双主,并且时间线分叉,删除了最新的时间线节点

遇到的问题如下&#xff1a; 2023-08-17 20:24:21.566 CST [1556001] LOG: database system was interrupted; last known up at 2023-08-17 20:21:41 CST 2023-08-17 20:24:21.770 CST [1556001] LOG: restored log file "00000009.history" from archive cp: 无法…...

ThinkPHP中实现IP地址定位

在网站开发中&#xff0c;我们经常需要获取用户的地理位置信息以提供个性化的服务。一种常见的方法是通过IP地址定位。在本文中&#xff0c;我们将介绍如何在ThinkPHP框架中实现IP地址定位。 一、IP地址定位的基本原理 IP地址是Internet上的设备在网络中的标识符。每个设备都有…...