基于PHP的cURL快速入门教程 (小偷采集程序)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等。很多小偷程序都是使用这个函数。 最爽的是,PHP也支持 cURL 库。本文将介绍 cURL 的一些高级特性,以及在PHP中如何运用它。

cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等。很多小偷程序都是使用这个函数。

最爽的是,PHP也支持 cURL 库。本文将介绍 cURL 的一些高级特性,以及在PHP中如何运用它。

为什么要用 cURL?

是的,我们可以通过其他办法获取网页内容。大多数时候,我因为想偷懒,都直接用简单的PHP函数:

 

content=filegetcontents("http://www.jb51.net");//orlines = file("http://www.jb51.net");
// or
readfile(http://www.jb51.net);

 

不过,这种做法缺乏灵活性和有效的错误处理。而且,你也不能用它完成一些高难度任务——比如处理coockies、验证、表单提交、文件上传等等。

引用:
cURL 是一种功能强大的库,支持很多不同的协议、选项,能提供 URL 请求相关的各种细节信息。

基本结构

在学习更为复杂的功能之前,先来看一下在PHP中建立cURL请求的基本步骤:

  1. 初始化
  2. 设置变量
  3. 执行并获取结果
  4. 释放cURL句柄

 

// 1. 初始化
ch=curlinit();//2.URLcurlsetopt(ch, CURLOPT_URL, "http://www.jb51.net");
curl_setopt(ch,CURLOPTRETURNTRANSFER,1);curlsetopt(ch, CURLOPT_HEADER, 0);
// 3. 执行并获取HTML文档内容
output=curlexec(ch);
// 4. 释放curl句柄
curl_close($ch);

 

第二步(也就是 curl_setopt() )最为重要,一切玄妙均在此。有一长串cURL参数可供设置,它们能指定URL请求的各个细节。要一次性全部看完并理解可能比较困难,所以今天我们只试一下那些更常用也更有用的选项。

检查错误

你可以加一段检查错误的语句(虽然这并不是必需的):

 

// ...
output=curlexec(ch);
if (output === FALSE) {     echo "cURL Error: " . curl_error(ch);
}
// ...

 

请注意,比较的时候我们用的是“=== FALSE”,而非“== FALSE”。因为我们得区分 空输出 和 布尔值FALSE,后者才是真正的错误。

获取信息

这是另一个可选的设置项,能够在cURL执行后获取这一请求的有关信息:

 

// ...
curl_exec(ch);info = curl_getinfo(ch);echo.info['url'] . '耗时'. $info['total_time'] . '秒';
// ...

 

返回的数组中包括了以下信息:

  • “url” //资源网络地址
  • “content_type” //内容编码
  • “http_code” //HTTP状态码
  • “header_size” //header的大小
  • “request_size” //请求的大小
  • “filetime” //文件创建时间
  • “ssl_verify_result” //SSL验证结果
  • “redirect_count” //跳转技术  
  • “total_time” //总耗时
  • “namelookup_time” //DNS查询耗时
  • “connect_time” //等待连接耗时
  • “pretransfer_time” //传输前准备耗时
  • “size_upload” //上传数据的大小
  • “size_download” //下载数据的大小
  • “speed_download” //下载速度
  • “speed_upload” //上传速度
  • “download_content_length”//下载内容的长度
  • “upload_content_length” //上传内容的长度  
  • “starttransfer_time” //开始传输的时间
  • “redirect_time”//重定向耗时

基于浏览器的重定向

在第一个例子中,我们将提供一段用于侦测服务器是否有基于浏览器的重定向的代码。例如,有些网站会根据是否是手机浏览器甚至用户来自哪个国家来重定向网页。

我们利用 CURLOPT_HTTPHEADER 选项来设定我们发送出的HTTP请求头信息(http headers),包括user agent信息和默认语言。然后我们来看看这些特定网站是否会把我们重定向到不同的URL。

 

// 测试用的URL
urls=array("http://www.cnn.com","http://www.mozilla.com","http://www.facebook.com");//browsers = array(
    "standard" => array (
        "user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)",
        "language" => "en-us,en;q=0.5"
        ),
    "iphone" => array (
        "user_agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3",
        "language" => "en"
        ),
    "french" => array (
        "user_agent" => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)",
        "language" => "fr,fr-FR;q=0.5"
        )
);
foreach (urlsasurl) {
    echo "URL: url\n";foreach(browsers as testname=>browser) {
        ch=curlinit();//urlcurlsetopt(ch, CURLOPT_URL, url);//headercurlsetopt(ch, CURLOPT_HTTPHEADER, array(
                "User-Agent: {browser['user_agent']}",                 "Accept-Language: {$browser['language']}"             ));         // 页面内容我们并不需要         curl_setopt(ch, CURLOPT_NOBODY, 1);
        // 只需返回HTTP header
        curl_setopt(ch,CURLOPTHEADER,1);//curlsetopt(ch, CURLOPT_RETURNTRANSFER, 1);
        output=curlexec(ch);
        curl_close(ch);//HTTP?if(pregmatch("!Location:(.)!",output, matches)) {             echo "test_name: redirects to matches[1]\n";         } else {             echo "test_name: no redirection\n";
        }
    }
    echo "\n\n";
}

 

首先,我们建立一组需要测试的URL,接着指定一组需要测试的浏览器信息。最后通过循环测试各种URL和浏览器匹配可能产生的情况。

因为我们指定了cURL选项,所以返回的输出内容则只包括HTTP头信息(被存放于 $output 中)。利用一个简单的正则,我们检查这个头信息中是否包含了“Location:”字样。

运行这段代码应该会返回如下结果:

用POST方法发送数据

当发起GET请求时,数据可以通过“查询字串”(query string)传递给一个URL。例如,在google中搜索时,搜索关键即为URL的查询字串的一部分:

http://www.google.com/search?q=nettuts

这种情况下你可能并不需要cURL来模拟。把这个URL丢给“file_get_contents()”就能得到相同结果。

不过有一些HTML表单是用POST方法提交的。这种表单提交时,数据是通过 HTTP请求体(request body) 发送,而不是查询字串。例如,当使用CodeIgniter论坛的表单,无论你输入什么关键字,总是被POST到如下页面:

http://codeigniter.com/forums/do_search/

你可以用PHP脚本来模拟这种URL请求。首先,新建一个可以接受并显示POST数据的文件,我们给它命名为post_output.php:

print_r($_POST);

接下来,写一段PHP脚本来执行cURL请求:

 

url="http://localhost/postoutput.php";post_data = array (
    "foo" => "bar",
    "query" => "Nettuts",
    "action" => "Submit"
);
ch=curlinit();curlsetopt(ch, CURLOPT_URL, url);curlsetopt(ch, CURLOPT_RETURNTRANSFER, 1);
// 我们在POST数据哦!
curl_setopt(ch,CURLOPTPOST,1);//postcurlsetopt(ch, CURLOPT_POSTFIELDS, postdata);output = curl_exec(ch);curlclose(ch);
echo $output;

 

执行代码后应该会得到以下结果:

这段脚本发送一个POST请求给 post_output.php ,这个页面 $_POST 变量并返回,我们利用cURL捕捉了这个输出。

文件上传

上传文件和前面的POST十分相似。因为所有的文件上传表单都是通过POST方法提交的。

首先新建一个接收文件的页面,命名为 upload_output.php:

print_r($_FILES);

以下是真正执行文件上传任务的脚本:

 

url="http://localhost/uploadoutput.php";post_data = array (
    "foo" => "bar",
    // 要上传的本地文件地址
    "upload" => "@C:/wamp/www/test.zip"
);
ch=curlinit();curlsetopt(ch, CURLOPT_URL, url);curlsetopt(ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(ch,CURLOPTPOST,1);curlsetopt(ch, CURLOPT_POSTFIELDS, postdata);output = curl_exec(ch);curlclose(ch);
echo $output;

 

如果你需要上传一个文件,只需要把文件路径像一个post变量一样传过去,不过记得在前面加上@符号。执行这段脚本应该会得到如下输出:

cURL批处理(multi cURL)

cURL还有一个高级特性——批处理句柄(handle)。这一特性允许你同时或异步地打开多个URL连接。

下面是来自来自php.net的示例代码:

 

// 创建两个cURL资源
ch1=curlinit();ch2 = curl_init();
// 指定URL和适当的参数
curl_setopt(ch1,CURLOPTURL,"http://lxr.php.net/");curlsetopt(ch1, CURLOPT_HEADER, 0);
curl_setopt(ch2,CURLOPTURL,"http://www.php.net/");curlsetopt(ch2, CURLOPT_HEADER, 0);
// 创建cURL批处理句柄
mh=curlmultiinit();//curlmultiaddhandle(mh,ch1);curlmultiaddhandle(mh,ch2);//active = null;
// 执行批处理
do {
    mrc=curlmultiexec(mh, active); } while (mrc == CURLM_CALL_MULTI_PERFORM);
while (active &&mrc == CURLM_OK) {
    if (curl_multi_select(mh) != -1) {         do {             $mrc = curl_multi_exec($mh, $active);         } while ($mrc == CURLM_CALL_MULTI_PERFORM);     } } // 关闭各个句柄 curl_multi_remove_handle(mh, ch1);curlmultiremovehandle(mh, ch2);curlmulticlose(mh);

 

这里要做的就是打开多个cURL句柄并指派给一个批处理句柄。然后你就只需在一个while循环里等它执行完毕。

这个示例中有两个主要循环。第一个 do-while 循环重复调用 curl_multi_exec() 。这个函数是无隔断(non-blocking)的,但会尽可能少地执行。它返回一个状态值,只要这个值等于常量 CURLM_CALL_MULTI_PERFORM ,就代表还有一些刻不容缓的工作要做(例如,把对应URL的http头信息发送出去)。也就是说,我们需要不断调用该函数,直到返回值发生改变。

而接下来的 while 循环,只在 $active 变量为 true 时继续。这一变量之前作为第二个参数传给了 curl_multi_exec() ,代表只要批处理句柄中是否还有活动连接。接着,我们调用 curl_multi_select() ,在活动连接(例如接受服务器响应)出现之前,它都是被“屏蔽”的。这个函数成功执行后,我们又会进入另一个 do-while 循环,继续下一条URL。

还是来看一看怎么把这一功能用到实处吧:

WordPress 连接检查器

想象一下你有一个文章数目庞大的博客,这些文章中包含了大量外部网站链接。一段时间之后,因为这样那样的原因,这些链接中相当数量都失效了。要么是被和谐了,要么是整个站点都被功夫网了...

我们下面建立一个脚本,分析所有这些链接,找出打不开或者404的网站/网页,并生成一个报告。

请注意,以下并不是一个真正可用的WordPress插件,仅仅是一段独立功能的脚本而已,仅供演示,谢谢。

好,开始吧。首先,从数据库中读取所有这些链接:

 

// CONFIG
dbhost=localhost;db_user = 'root';
dbpass=;db_name = 'wordpress';
excludeddomains=array(localhost,www.mydomain.com);max_connections = 10;
// 初始化一些变量
urllist=array();working_urls = array();
deadurls=array();not_found_urls = array();
active=null;//MySQLif(!mysqlconnect(db_host, dbuser,db_pass)) {
    die('Could not connect: ' . mysql_error());
}
if (!mysql_select_db(dbname))die(Couldnotselectdb:.mysqlerror());//q = "SELECT post_content FROM wp_posts
    WHERE post_content LIKE '%href=%'
    AND post_status = 'publish'
    AND post_type = 'post'";
r=mysqlquery(q) or die(mysql_error());
while (d=mysqlfetchassoc(r)) {
    // 用正则匹配链接
    if (preg_match_all("!href=\"(.*?)\"!", d[postcontent],matches)) {
        foreach (matches[1]asurl) {
            // exclude some domains
            tmp=parseurl(url);
            if (in_array(tmp[host],excluded_domains)) {
                continue;
            }
            // store the url
            urllist[]=url;
        }
    }
}
// 移除重复链接
urllist=arrayvalues(arrayunique(url_list));
if (!$url_list) {
    die('No URL to check');
}

 

我们首先配置好数据库,一系列要排除的域名(excludeddomainsmax_connections)。然后,连接数据库,获取文章和包含的链接,把它们收集到一个数组中($url_list)。

下面的代码有点复杂了,因此我将一小步一小步地详细解释:

 

// 1. 批处理器
mh=curlmultiinit();//2.URLfor(i = 0; i<max_connections; i++)addurltomultihandle($mh,$urllist);//3.do$mrc=curlmultiexec($mh,$active);while(mrc == CURLM_CALL_MULTI_PERFORM);
// 4. 主循环
while (active &&mrc == CURLM_OK) {
    // 5. 有活动连接
    if (curl_multi_select(mh) != -1) {         // 6. 干活         do {             $mrc = curl_multi_exec($mh, $active);         } while ($mrc == CURLM_CALL_MULTI_PERFORM);         // 7. 有信息否?         if ($mhinfo = curl_multi_info_read($mh)) {             // 意味着该连接正常结束             // 8. 从curl句柄获取信息             $chinfo = curl_getinfo($mhinfo['handle']);             // 9. 死链么?             if (!$chinfo['http_code']) {                 $dead_urls []= $chinfo['url'];             // 10. 404了?             } else if ($chinfo['http_code'] == 404) {                 $not_found_urls []= $chinfo['url'];             // 11. 还能用             } else {                 $working_urls []= $chinfo['url'];             }             // 12. 移除句柄             curl_multi_remove_handle($mh, $mhinfo['handle']);             curl_close($mhinfo['handle']);             // 13. 加入新URL,干活             if (add_url_to_multi_handle($mh, $url_list)) {                 do {                     $mrc = curl_multi_exec($mh, $active);                 } while ($mrc == CURLM_CALL_MULTI_PERFORM);             }         }     } } // 14. 完了 curl_multi_close(mh);
echo "==Dead URLs==\n";
echo implode("\n",deadurls)."\n\n";echo"==404URLs==\n";echoimplode("\n",not_found_urls) . "\n\n";
echo "==Working URLs==\n";
echo implode("\n",workingurls);//15.urlfunctionaddurltomultihandle(mh, url_list) {     staticindex = 0;
    // 如果还剩url没用
    if (urllist[index]) {
        // 新建curl句柄
        ch=curlinit();//urlcurlsetopt(ch, CURLOPT_URL, urllist[index]);
        // 不想输出返回的内容
        curl_setopt(ch,CURLOPTRETURNTRANSFER,1);//curlsetopt(ch, CURLOPT_FOLLOWLOCATION, 1);
        // 不需要内容体,能够节约带宽和时间
        curl_setopt(ch,CURLOPTNOBODY,1);//curlmultiaddhandle(mh, ch);//urlindex++;
        return true;
    } else {
        // 没有新的URL需要处理了
        return false;
    }
}

 

下面解释一下以上代码。列表的序号对应着代码注释中的顺序数字。

  1. 新建一个批处理器。Created a multi handle.
  2. 稍后我们将创建一个把URL加入批处理器的函数 add_url_to_multi_handle() 。每当这个函数被调用,就有一个新url被加入批处理器。一开始,我们给批处理器添加了10个URL(这一数字由 $max_connections 所决定)。
  3.   运行 curl_multi_exec()  进行初始化工作是必须的,只要它返回 CURLM_CALL_MULTI_PERFORM 就还有事情要做。这么做主要是为了创建连接,它不会等待完整的URL响应。
  4. 只要批处理中还有活动连接主循环就会一直持续。
  5. curl_multi_select() 会一直等待,直到某个URL查询产生活动连接。
  6. cURL的活儿又来了,主要是获取响应数据。
  7. 检查各种信息。当一个URL请求完成时,会返回一个数组。
  8. 在返回的数组中有一个 cURL 句柄。我们利用其获取单个cURL请求的相应信息。
  9. 如果这是一个死链或者请求超时,不会返回http状态码。
  10. 如果这个页面找不到了,会返回404状态码。
  11. 其他情况我们都认为这个链接是可用的(当然,你也可以再检查一下500错误之类...)。
  12. 从该批次移除这个cURL句柄,因为它已经没有利用价值了,关了它!
  13. 很好,现在可以另外加一个URL进来了。再一次地,初始化工作又开始进行...
  14. 嗯,该干的都干了。关闭批处理器,生成报告。
  15. 回过头来看给批处理器添加新URL的函数。这个函数每调用一次,静态变量 $index 就递增一次,这样我们才能知道还剩多少URL没处理。

我把这个脚本在我的博客上跑了一遍(测试需要,有一些错误链接是故意加上的),结果如下:

 

<img border="0" src="http://files.jb51.net/upload/201106/20110602225008534.png" />

 

共检查约40个URL,只耗费两秒不到。当需要检查更加大量的URL时,其省心省力的效果可想而知!如果你同时打开10个连接,还能再快上10倍!另外,你还可以利用cURL批处理的无隔断特性来处理大量URL请求,而不会阻塞你的Web脚本。

另一些有用的cURL 选项

HTTP 认证

如果某个URL请求需要基于 HTTP 的身份验证,你可以使用下面的代码:
复制内容到剪贴板代码:

 

url="http://www.somesite.com/members/";ch = curl_init();
curl_setopt(ch,CURLOPTURL,url);
curl_setopt(ch,CURLOPTRETURNTRANSFER,1);//curlsetopt(ch, CURLOPT_USERPWD, "myusername:mypassword");
// 你可以允许其重定向
curl_setopt(ch,CURLOPTFOLLOWLOCATION,1);//cURL//curlsetopt(ch, CURLOPT_UNRESTRICTED_AUTH, 1);
output=curlexec(ch);
curl_close($ch);

 

FTP 上传

PHP 自带有 FTP 类库, 但你也能用 cURL:

 

// 开一个文件指针
file=fopen("/path/to/file","r");//urlurl = "ftp://username:password@mydomain.com:21/path/to/new/file";
ch=curlinit();curlsetopt(ch, CURLOPT_URL, url);curlsetopt(ch, CURLOPT_RETURNTRANSFER, 1);
// 上传相关的选项
curl_setopt(ch,CURLOPTUPLOAD,1);curlsetopt(ch, CURLOPT_INFILE, fp);curlsetopt(ch, CURLOPT_INFILESIZE, filesize("/path/to/file"));
// 是否开启ASCII模式 (上传文本文件时有用)
curl_setopt(ch,CURLOPTFTPASCII,1);output = curl_exec(ch);curlclose(ch);

 

FQ术

你可以用代理发起cURL请求:

 

ch=curlinit();curlsetopt(ch, CURLOPT_URL,'http://www.example.com');
curl_setopt(ch,CURLOPTRETURNTRANSFER,1);//curlsetopt(ch, CURLOPT_PROXY, '11.11.11.11:8080');
// 如果需要的话,提供用户名和密码
curl_setopt(ch,CURLOPTPROXYUSERPWD,user:pass);output = curl_exec(ch);curlclose(ch);

 

回调函数

可以在一个URL请求过程中,让cURL调用某指定的回调函数。例如,在内容或者响应下载的过程中立刻开始利用数据,而不用等到完全下载完。

 

ch=curlinit();curlsetopt(ch, CURLOPT_URL,'http://net.tutsplus.com');
curl_setopt(ch,CURLOPTWRITEFUNCTION,"progressfunction");curlexec(ch);
curl_close (ch);functionprogressfunction(ch,str) {     echostr;
    return strlen($str);
}

 

这个回调函数必须返回字串的长度,不然此功能将无法正常使用。

在URL响应接收的过程中,只要收到一个数据包,这个函数就会被调用。

小结

今天我们一起学习了cURL库的强大功能和灵活的扩展性。希望你喜欢。下一次要发起URL请求时,考虑下cURL吧!

原文:基于PHP的cURL快速入门

英文原文:http://net.tutsplus.com/tutorial%20...%20for-mastering-curl/

如何联系我:【万里虎】www.bravetiger.cn 【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起) 【博客】http://www.cnblogs.com/kenshinobiy/
目录
打赏
0
0
0
0
24
分享
相关文章
新手教程:PHP入门教程
《PHP入门教程》涵盖PHP简介、环境搭建、第一个PHP脚本、基本语法、表单处理、函数定义及进一步学习方向。PHP是一种开源脚本语言,适合Web开发。环境搭建可使用XAMPP/WAMP/MAMP或手动安装Apache、PHP和MySQL。通过编写简单代码和处理表单,逐步掌握变量、字符串、数组、条件语句和循环等基础语法。最后介绍数据库操作、会话管理和面向对象编程等高级特性。
199 70
|
3月前
|
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
111 20
为什么PHP爬虫抓取失败?解析cURL常见错误原因
豆瓣电影评分是电影市场的重要参考,通过网络爬虫技术可以高效采集评分数据,帮助电影制作和发行方优化策略。本文介绍使用PHP cURL库和代理IP技术抓取豆瓣电影评分的方法,解决反爬机制、网络设置和数据解析等问题,提供详细代码示例和优化建议。
215 0
为什么PHP爬虫抓取失败?解析cURL常见错误原因
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
Tengine、Nginx安装PHP命令教程
要在阿里云Linux上安装PHP,请先更新YUM源并启用PHP 8.0仓库,然后安装PHP及相关扩展。通过`php -v`命令验证安装成功后,需修改Nginx配置文件以支持PHP,并重启服务。最后,创建`phpinfo.php`文件测试安装是否成功。对于CentOS系统,还需安装EPEL源和Remi仓库,其余步骤类似。完成上述操作后,可通过浏览器访问`http://IP地址/phpinfo.php`测试安装结果。
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
thinkPhP6.0安装教程图解--PHP框架安装
本文是一篇关于ThinkPHP 6.0安装教程的图解,包括环境检查、安装Composer、修改Composer镜像地址、安装ThinkPHP框架以及启动运行ThinkPHP的步骤。文章详细描述了每个步骤的操作方法,并提供了相应的命令和截图,帮助用户理解并顺利完成ThinkPHP 6.0的安装和运行。
thinkPhP6.0安装教程图解--PHP框架安装
如何使用 PHP 将天气跟踪集成到 Web 应用程序中
如何使用 PHP 将天气跟踪集成到 Web 应用程序中
78 0
|
8月前
|
PHP
PHP全自动采集在线高清壁纸网站源码
PHP全自动采集在线高清壁纸网站源码,PHP全自动采集在线高清壁纸网站源码,一款开源壁纸源码,无需安装。集合360壁纸,百度壁纸,必应壁纸,简单方便。每天自动采集,自动更新,非常不错,php源码 网站源码 免费源码 自动采集。
143 3
|
9月前
|
Linux CentOS 宝塔 Suhosin禁用php5.6版本eval函数详细图文教程
【8月更文挑战第27天】本文介绍两种禁用PHP执行的方法:使用`PHP_diseval_extension`禁用和通过`suhosin`禁用。由于`suhosin`不支持PHP8,仅适用于PHP7及以下版本,若服务器安装了PHP5.6,则需对应安装`suhosin-0.9.38`版本。文章提供了详细的安装步骤,并强调了宝塔环境下与普通环境下的PHP路径差异。安装完成后,在`php.ini`中添加`suhosin.so`扩展并设置`executor.disable_eval = on`以禁用执行功能。最后通过测试代码验证是否成功禁用,并重启`php-fpm`服务生效。
160 2